Arrowhead Client library quickstart

Warning

This library is a work in progress, and no api should be considered stable.

Prerequisites

  • Arrowhead_client library installed

  • Docker installed

  • Docker compose installed

Running the quickstart example

Setting up an Arrowhead local cloud can be a tricky process. To simplify that process, this library provides an example directory that contains all necessary components to setup a local cloud. You can access that folder by cloning the repository and navigating into the examples/quickstart directory.

To start and setup the local cloud, run:

shell-session
python quickstart_setup.py

This script will start local cloud and setup the orchestration and authorization rules necessary to run the example files.

Getting a provider running

The provider provides services within a local cloud. To get a provider running start by importing the client library.

python
from arrowhead_client.client.implementations import SyncClient

Then we can create an http client running in secure mode.

python
provider = SyncClient.create(
        system_name='quickstart-provider',
        address='127.0.0.1',
        port=7655,
        keyfile='certificates/crypto/quickstart-provider.key',
        certfile='certificates/crypto/quickstart-provider.crt',
        cafile='certificates/crypto/sysop.ca',
)

To add a service, we decorate a function with the provided_service decorator of the provider. The decorator takes as arguments the service definition, service uri, protocol and related method, payload format and access policy, which is one of 'NOT_SECURE', 'CERTIFICATE' and 'TOKEN. For more information regarding access policies/security modes, see the user guide section on security and the Eclipse-Arrowhead documentation.

python
@provider.provided_service(
        service_definition='hello-arrowhead',
        service_uri='hello',
        protocol='HTTP',
        method='GET',
        payload_format='JSON',
        access_policy='TOKEN', )
def hello_arrowhead(request):
    return {"msg": "Hello, Arrowhead!"}

This example will return a simple JSON message when the client is accessed on https://127.0.0.1:7655/hello, using the token access policy.

The request parameter in the previous example is necessary as it contains the request body. The request body is ignored when the http method is get, but let’s make another service that echoes any JSON message it’s given:

python
@provider.provided_service(
        service_definition='echo',
        service_uri='echo',
        protocol='HTTP',
        method='PUT',
        payload_format='JSON',
        access_policy='CERTIFICATE', )
def echo(request):
    body = request.read_json()

    return body

In this example, the request body can be accessed as a dict using the request.read_json() method.

All that’s left to do now is to run the provider, which we do by calling the run_forever() method.

python
if __name__ == '__main__':
    provider.run_forever()

This method registers the provider system and services, and then runs the underlying Flask application. The output should look like this:

python
Service Registry entry with provider: (quickstart-provider, 127.0.0.1:7655) and service definition: hello-arrowhead already exists.
Service Registry entry with provider: (quickstart-provider, 127.0.0.1:7655) and service definition: echo already exists.
Started Arrowhead ArrowheadSystem
 * Serving Flask app "" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on https://127.0.0.1:7655/ (Press CTRL+C to quit)

And that’s it! In 30 lines of code (or 11 if you make the code hard to read) we have set up an Arrowhead provider with two services and are currently running it! Here is the full code listing for this example.

examples/quickstart/clients/provider.py

python
"""
Provider example app
"""
from arrowhead_client.client.implementations import SyncClient

provider = SyncClient.create(
        system_name='quickstart-provider',
        address='127.0.0.1',
        port=7655,
        keyfile='certificates/crypto/quickstart-provider.key',
        certfile='certificates/crypto/quickstart-provider.crt',
        cafile='certificates/crypto/sysop.ca',
)


@provider.provided_service(
        service_definition='hello-arrowhead',
        service_uri='hello',
        protocol='HTTP',
        method='GET',
        payload_format='JSON',
        access_policy='TOKEN', )
def hello_arrowhead(request):
    return {"msg": "Hello, Arrowhead!"}


@provider.provided_service(
        service_definition='echo',
        service_uri='echo',
        protocol='HTTP',
        method='PUT',
        payload_format='JSON',
        access_policy='CERTIFICATE', )
def echo(request):
    body = request.read_json()

    return body


if __name__ == '__main__':
    provider.run_forever()

Next, we will create a consumer.

Getting a consumer running

It’s just as easy to get a consumer going, we start similarly by importing the library and creating a client.

python
from arrowhead_client.client.implementations import SyncClient

consumer = SyncClient.create(
        system_name='quickstart-consumer',
        address='127.0.0.1',
        port=7656,
        keyfile='certificates/crypto/quickstart-consumer.key',
        certfile='certificates/crypto/quickstart-consumer.crt',
        cafile='certificates/crypto/sysop.ca',
)

A difference between a provider and a pure consumer is that we need to set up the pure consumer first:

python
if __name__ == '__main__':
    consumer.setup()

This method was also called by the provide inside the run_forever() method. The setup method enables the consumer to use the core services.

To consume a service, the consumer needs to get the orchestration rule from the orchestrator core system:

python
    consumer.add_orchestration_rule('hello-arrowhead', 'GET')

The first argument is the service definition, and the second is the http method used.

Then we can consume the service and print the response:

python
    response = consumer.consume_service('hello-arrowhead')
    print(response.read_json()['msg'])

Let’s do the same for the second service:

python
    consumer.add_orchestration_rule('echo', 'PUT')
    echo_response = consumer.consume_service('echo', json={'msg': 'ECHO'})
    print(echo_response.read_json()['msg'])

The output should then be

python
Hello, Arrowhead!
ECHO

And the full listing:

examples/quickstart/clients/consumer.py

python
"""
Consumer example app
"""
from arrowhead_client.client.implementations import SyncClient

consumer = SyncClient.create(
        system_name='quickstart-consumer',
        address='127.0.0.1',
        port=7656,
        keyfile='certificates/crypto/quickstart-consumer.key',
        certfile='certificates/crypto/quickstart-consumer.crt',
        cafile='certificates/crypto/sysop.ca',
)


if __name__ == '__main__':
    consumer.setup()

    consumer.add_orchestration_rule('hello-arrowhead', 'GET')
    response = consumer.consume_service('hello-arrowhead')
    print(response.read_json()['msg'])

    consumer.add_orchestration_rule('echo', 'PUT')
    echo_response = consumer.consume_service('echo', json={'msg': 'ECHO'})
    print(echo_response.read_json()['msg'])

If you first start the provider application and then run the consumer application, the your terminal should print

shell
Hello, Arrowhead!

Beyond the tutorial

These examples show the basics of what the library will be able to do, with support for further protocols and features planned. Try changing the functions in provider.py a bit and see what happens. If you want to add new services to the cloud, you need to set up orchestration and authorization rules. I suggest taking a look at the Arrowhead Management Tool to do that.

Just note that the cloud used for this example only contains the mandatory core systems, i.e. the service registry, orchestrator, and authorization systems. If you want to use more core services, you need to set up your own local cloud, which is outside the scope of this tutorial.

Quickstart help

This section will be filled with the various questions and issues people have with the quickstart.