Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

Real World Usage

Dario Abdulrehman edited this page Aug 15, 2018 · 20 revisions

Setting up

There are several configuration files:

  • config.json
  • services.json
  • templates.json
  • profiles.json
  • service-mappings.json

As a new user you will mostly care about services.json and config.json

config.json

This is where you set your Nexus and Bintray repository details which sm uses to download and run binaries of services on your machine

services.json

This is the meat of the operation, this file contains all of the services that are shared across your organisation. For example, let pretend we are working for a travel agency. This company has a TRAVEL_FRONTEND application, a CUSTOMER_MICROSERVICE and a PAYMENTS_MICROSERVICE. In this instance we would have a row for each microservice, the TRAVEL_FRONTEND may look like this:

"TRAVEL_FRONTEND": {  
    "name": "Frontend for allowing customers to testapps to peruse and purchase holidays over the internet",
    "type": "play",
    "location": "/travel-frontend",
    "hasServiceMappings": true,
    "defaultPort" : 8500,
    "hasMongo" : true,
    "healthcheck": {
        "url": "http://localhost:${port}",
        "response": ""
    },
    "sources": {
        "cmd": [
            "play",
            "start"
        ],
        "extra_params": [
            "-DFoo=false"
        ],
        "repo": "git@github.com:organisation/travel-frontend.git"
    },
    "binary": {
         "artifact": "travel-frontend",
         "groupId":"foo/bar/foo/",
         "nexus": "/content/repositories/",
         "destinationSubdir" : "travel-frontend/target",
         "cmd": [
             "./basicplayapp/bin/travel-frontend",
             "-DProd.microservice.whitelist.useWhitelist=false",
             "-DProd.mongodb.uri=mongodb://localhost:27017/somedb",
             "-J-Xmx256m",
             "-J-Xms256m",
             "-J-XX:MaxPermSize=128m"
        ]
    }
}

This config can then be stored in a shared repo shared across world borders, a different team in a different part of the world could be responsible for CUSTOMER_MICROSERVICE and you may be working on the PAYMENTS_MICROSERVICE. A dev working on PAYMENTS_MICROSERVICE may not care about how to start this dependency up or and shouldn't have to waste their time understand other teams setup, in this instance all the user needs to do is

sm --start TRAVEL_FRONTEND

Service manager will check out the code from the repo for you and start it up from source, nice! Alternatively pass the -f (binary) flag and it will download the binary from Nexus and fire it up from binary.

Bintray setup

If your artifact resides on Bintray, rather than Nexus, remove binary.nexus element.

Pain Free Evolution

So lets say we now have our several services set up in confignow in services.json, lets simplify how this might look in overview:

{
    "TRAVEL_FRONTEND" : {
       ...
    },
    "CUSTOMER_MICROSERVICE" : {
       ...
    },
    "PAYMENTS_MICROSERVICE" : {
       ...
    }
}

So this sounds great, but suddenly the team working on the customer micro-service has split the service into three giving us the below, oh no! now different teams need to be educated about a change which doesn't even really affect them! but wait... not so fast sherlock :)

{
    "TRAVEL_FRONTEND" : {
       ...
    },
    "CUSTOMER_STORE_MICROSERVICE" : {
       ...
    },
    "CUSTOMER_REWARDS_MICROSERVICE" : {
       ...
    },
    "CUSTOMER_FOO_MICROSERVICE" : {
       ...
    },
    "PAYMENTS_MICROSERVICE" : {
       ...
    }
}

Enter profiles.json

This is a way to lump services together for common usages. In the first example we may have added a profile entry such as "TRAVEL_ALL" (below) which meanse we would have started with sm --start TRAVEL_ALL:

{
    "ALL" : [ "*" ],
    "TRAVEL_ALL": ["TRAVEL_FRONTEND", "CUSTOMER_STORE_MICROSERVICE", "PAYMENTS_MICROSERVICE"],
    "CUSTOMER_DEV_PROFILE": ["CUSTOMER*"]
}

so this means that the team that just added some more microservices just adds the new ones to the TRAVEL_ALL profile and nobody even needs to know that anything has changed, sweeeet

How to share config

This brings us to service-manager-config sm by default looks in $WORKSPACE/service-manager-config for its config, though it can be customised. The easiest way to share config is to create a repo containing your config and check it out into that location. Then each user can either use the most recent version by pulling the repo occasionally or alternatively they can use any version in the repos history. It allows for a clean decoupling between the app and configurations.

More advanced configurations and templates.json

So your now using sm but your services.config is huge and full of duplicated configs. Theres an Ap... I mean config for that, templates.json. It's pretty simple, you just define a template, such as below. You can then remove all these duplicated configs in your services.json file and just add "template" : "PLAY" to your entry in services.json. Service Manager takes the template first and then overlays the services.json config over the top of the template, so services.json takes precedence

{
    "DROPWIZARD" : {
        "type": "dropwizard",
        "versionEnv": "${SERVICE-ID}_VERSION",
        "pattern": "service.manager.serviceName=${SERVICE-ID}",
        "hasMongo": true,
        "hasServiceMappings": true,
        "healthcheck": {
            "url": "http://localhost:${port}/ping",
            "response": "pong"
        }
    },
    "PLAY": {
        "type": "play",
        "versionEnv": "${SERVICE-ID}_VERSION",
        "pattern": "service.manager.serviceName=${SERVICE-ID}",
        "hasMongo": false,
        "hasServiceMappings": false,
        "healthcheck": {
            "url": "http://localhost:${port}/ping/ping",
            "response": ""
        },
        "sources": {
            "extra_params": [
                 "-Drun.mode=Dev"
            ],
            "cmd": [
                "sbt",
                "update",
                "start"
            ]
        },
        "binary": {
            "ext": "tgz",
            "repo": "artifactory"
        } 
    }
}

Common commands

Find out all the commands available sm -h

See status of running applications sm -s for example will print out something like

Running:
+------------------+-------+-------+-------------+--------+------+---------+----------+----------+-------------+
| name             |  ppid |   pid |      uptime |    mem | port | test id | run from | features | healthcheck |
+------------------+-------+-------+-------------+--------+------+---------+----------+----------+-------------+
| TRAVEL_FRONTEND  |     1 | 26008 | 01-04:15:14 |   1368 | 9032 |         |          |          |        PASS |
| TRAVEL_MS        | 66928 | 66929 |    06:45:46 |   1352 | 9032 |         |          |          |        BOOT |
| PAYMENT_MS       |     1 | 25785 | 01-04:16:25 | 104660 | 8500 |         | SNAPSHOT |          |        PASS |
| CITIZEN_FRONTEND |     1 | 27142 | 01-04:13:13 |  72508 | 9029 |         | SOURCE   |          |        PASS |
| MONGO            |     1 | 25871 | 01-04:15:41 |  75640 | 8123 |         |          |          |        PASS |
| RABBITMQ         |   167 |   235 | 01-11:20:21 |  14208 |      |         |          |          |        NONE |
+------------------+-------+-------+-------------+--------+------+---------+----------+----------+-------------+

I want to fire up a service manually: You can contextually show how sm would start an app by doing:

sm --showcmdfor [SERVICE_NAME OR PROFILE_NAME](s) (other params)

i.e.

sm --showcmdfor TRAVEL_ALL -f

would print out the start command for each service in the profile when starting from binary

s, --start TRAVEL_ALL -f --appendArgs '{"TRAVEL_MS":["-DFoo=Bar","-Dmongo.port=localhost:4563"]}'

Will start all services in the travel profile but will start the travel micro service with custom args

There is more???

Yes, sm also has a built in capability to help run integration tests. simply run smserver from the command line and it will open up a rest api on your machine... This then allows your tests to request sm to start up an instance of any configured service on the machine to be used for testing against. See the smserver page