Skip to content

Service implementation

This template project shows how to feed the program with its accesstokens, url:s and other nice things to needed to run properly in an Arrigo Local environment.

5 minutes WAMP

In Arrigo Local, all microservices communicates on a WAMP channel. The WAMP channel is simply a websocket connection to a broker, and all messages are encoded with messagepack. In the broker, all microservices communicates with each other on topics. A topic is a string identifier for something a message can be sent to. The service can publish a message to a topic, and another service can subscribe to that topic to receive a message. A service can also register a method on a topic which can be called by another service. This examples make use of the RPC pattern for communication between our custom-service and the Arrigo Local SSF-service as well as between the connected browser and the custom-service. Every microservice in Arrigo Local reserves a namespace in a topic structure. The topic structure is account.[accountName].[type].[name].[methods]. All views, on the JavaScript tab, has the ServerSide callee attribute set to accounts.%account%.services.ssf.execute. Based on the topic strucure, this means that all the views SSF default calls should go to the execute method in the ssf service under services in the account %account% (which is resolved during runtime to the very same account the custom-service is fed with).

environment.js

This is the file loaded by the index.js file to obtain the environment for the custom-service. It is possible to pass variables in several different ways for a program, both in the environment (the program that starts the service) and as a command line parameter. The command line parameters always takes precendence over the variables fed via the environment. (so it is possible to override a global setting with a local). We do not dig too deep into this file, but if you are familiar with JavaScript this should be easy to follow along.

index.js

This is the main entry point of the service, and also the script referenced in the custom-service definition snippet in the previous step. This file connects to the WAMP router, obtains a session and uses that session for communication with the other microservices. Let's go through the file in detail.

1
2
3
import ENV from './environment.js';
import autobahn from 'autobahn';
import context from './context.js';
The import statement imports the dependencies into this script. The ENV is the environment exported in the environment.js next to the index.js file. We include autobahn for WAMP connection, and the context for calling other microservices over the WAMP channel.

Lets go on with the script!

const connection = new autobahn.Connection({
    realm: ENV.realm,
    authid: ENV.key,
    authmethods: ["anonymous"],
    transports: [{
        url: `${ENV.url}`,
        type: 'websocket',
        protocols: ['wamp.2.msgpack']
    }],

});

This code creates the connection variable, with the WAMP connection object. This instance keeps track of the WAMP connection to the broker. We use the ENV.url to get the URL to the broker. Now, when we have a connection, it is time to add a callback handler to the onSession event, and use this session object to register callback methods in the custom-service.

const serviceName = 'arrigo-custom-service-template';

const ns = `accounts.${ENV.account.toLowerCase()}.services.${serviceName}`;

connection.onopen = async function (session) {
    console.log("Connected, got new session!");

    try {
        await session.register(`${ns}.hello`, async (args, kwargs, details) => {
            return "Hello from service";
        });
    } catch (error) {
        console.log("Exception while registering methods", error)
        console.log("Exiting to be resurrected by the pm2 service manager");
        process.exit(1);
    }
};

On line 17, the serviceName is used to reserve a topic. When a topic is choosen, be careful to not name your service to any of the other services in your Arrigo Local installation.

Warning

The service names ssf, chart, state, dc and volume are used/reserved. Do not use those.

Line 19 simply creates a fully qualified name for the service by using the ENV.account variable gotten from the process environment created by PM2 (the value of account is simply the account in globalsettings.json on your computer).

Line 21 adds an event handler to the connection. When a new connection is made to the broker, the callback with a session context variable is passed as a parameter to the callback function.

Line 25 registers a RPC method on the services namespace, with its callback method.
The registration must be wrapped in a try/catch block since the startup process of the WAMP broker might not have completed when attempting to register the service. This ensures that the services is restarted in case the registration fails due to the WAMP broker not being fully operational.

Important

All methods needs to have a return statement! MsgPack does not handle the JavaScript undefined value, which is the default return value from a function if none are specified! This will result in an error and a malfunction. Always return something from your RPC methods. a simple return true is best practice here if you have nothing to return.

Tip

For advanced users: The last section in this file shows how to enable and configure another WAMP connection to EXO services in Arrigo. Review the source code and comments to understand the concepts. This functionality adds the legacy read/write possibility to the context. This is the same context available in SSF. To be able to use the local context for state, db and other methods, a local context has to be created with a valid path variable set. Review docs for SSF context to locate path and how to call methods.

Ok! That is all! Your custom service is waiting for someone to call the hello method! Let's continue with the next step !