/boot-microservice

Common classes for microservices set up on Spring Boot.

Primary LanguageGroovyApache License 2.0Apache-2.0

boot-microservice Build Status Coverage Status

Example of a microservice that works on Spring Boot.

Requirements

  • Java 8

Introduction

To make setting up microservices in micro-time we needed to extract the common building blocks to separate libraries. In this template we are using 4finance custom library, i.e. micro-infra-spring (available in jcenter).

GUI version

There is a version with web application connected with backend side. You can find it on the branch of this repo: boot-microservice-gui.

What should I do after I clone the repo?

You can remove all the caching related libraries, annotations and com.ofg.twitter packages. Next adjust all the properties and then you have an empty project - you're now ready to go.

How can I run it?

From gradle

You can also run it directly using gradle. Please check run.sh script.

From jar

To run it just

  • create a jar - ./gradlew clean build
  • go to build/libs to find the fat jar
  • execute java -jar with the arguments the same as in [run.sh])(scripts/run.sh) script
java -jar boot-microservice.jar runShArgs

From Docker

Development

Running:

./gradlew docker

will create /build/docker/Dockerfile. You can use this file to create Docker image:

sudo docker build -t boot-microservice build/docker

Self-sufficient Docker image with our sample microservice can be started as follows:

docker run -e spring.profiles.active=dev -p 8080:8095 boot-microservice

Test with curl localhost:8080/ping. Notice that we run it in dev profile (in-memory embedded ZooKeeper and stubs) and we re-map 8095 port to 8080 on host machine.

Standalone setup with ZooKeeper and Graphite

If you want to run microservice with real service discovery via ZooKeeper and Graphite, first prepare Docker images for that:

docker run --name zookeeper            jplock/zookeeper
docker run --name graphite  -p 8081:80 kamon/grafana_graphite

After the first time these containers can be executed with docker start -a zookeeper and docker start -a graphite shorthands. Now you can run arbitrary number of microservices and they will all register themselves in ZooKeeper/Graphite instances:

docker run \
  -p 8080:8080 \
  -e spring.profiles.active=prod \
  --link zookeeper:zk \
  --link graphite:gr \
  boot-microservice \
  --service.resolver.url=zk:2181 \
  --graphite.host=gr

We link microservice container with ZooKeeper container aliasing it to zk. This way microservice sees ZooKeeper container under zk hostname and we can simply point service.resolver.url=zk:2181 (zk:2181 is a valid network address from boot-microservice container's perspective). Same applies to Graphite.

Your microservice (assuming it exposes 8080 port) will be visible outside under 8080 as well. Moreover you can browse to localhost:8081 and browse Grafana.

How it works?

Production code

Configuration

Below you can find description of the most crucial parts of the application's production code.

Application

contains Spring Boot autoconfiguration and contains main method

Microservice Autoconfiguration

Spring boot auto-configure application and enable support for 4finance's "Micro Infra Spring". That enables module like ServiceDiscovery, Swagger, CorrelationId filters, custom RestTemplate, custom exception handling, health check controllers etc. Check out Micro Infra Spring's Boot Starter module's Spring factories set up

If you want only certain modules of the system just check out 4finance's Micro Infra Spring's readme.

Tests

Below you can find description of the most crucial parts of the application's test code.

MicroserviceIntegrationSpec

extends com.ofg.infrastructure.base.IntegrationSpec Spock Specification class that initializes Spring web-context.

MicroserviceMvcIntegrationSpec

extends com.ofg.infrastructure.base.MvcIntegrationSpec Spock Specification class that initializes Spring web-context and provides some additional Mvc related fields.

MicroserviceMvcWiremockSpec

extends com.ofg.infrastructure.base.MvcWiremockIntegrationSpec Spock Specification class that extends the MvcIntegrationSpec spec. Additionally it provides WireMock related fields and methods.

Consumer Driven Contracts

you may wonder - how on earth does the collaborator collerator respond to with 200 when you post him at /1 ?! It's all about Consumer Driven Contracts and our implementation called stub-runner-spring.

What happens under the hood is that the stubs are downloaded from 4finance Bintray account. A jar of the stub-runner-examples is downloaded and unpacked to a temporary folder and all the tests are ran against it. The stub is in fact here twitter-places-collerator stub!

The paths to the repo, the module name and artifactId are here - twitter-places-analyzer.yaml.

Sample business requirement

Twitter places analyzer, searches through tweets for places. Then analyzers send those to Collerators.

INPUT

Hit PUT at:

/api/{pairId}

with list of tweets:

[
    {
        "created_at": "Sat Jul 26 09:15:10 +0000 2014",
        "id": 492961315070439424,
        "id_str": "492961315070439424",
        "geo": null,
        "coordinates":
        {
            "coordinates":
                [
                    -75.14310264,
                    40.05701649
                ],
            "type":"Point"
        },
    },
    {
            "created_at": "Sat Jul 26 09:15:10 +0000 2014",
            "id": 492961315070439424,
            "id_str": "492961315070439424",
            "geo": null,
            "coordinates":
            {
                "coordinates":
                    [
                        -75.14310264,
                        40.05701649
                    ],
                "type":"Point"
            },
     }
]

OUTPUT

And it will hit collectors at /{pairId} with tweets taken from twitter

[
    {
        "pair_id" : 1,
        "tweet_id" : "492967299297845248",
        "place" :
        {
            "name":"Washington",
            "country_code": "US"
        },
        "probability" : "2",
        "origin" : "twitter_place_section"
    },
    {
        "pair_id" : 2,
        "tweet_id" : "123187246819263981"
    },
]

Build status

Build Status Coverage Status