Skip to content
This repository has been archived by the owner on May 11, 2021. It is now read-only.

How to use it

Marcin Grzejszczak edited this page Nov 14, 2015 · 27 revisions

Quick start

Just clone boot-microservice sample project and look around.

Spring Cloud Zookeeper support (since 2.0.1)

Starting from 2.0.1 you can use the microservice descriptor like presented in Spring Cloud Zookeeper documentation

Microservice descriptor (deprecated since 2.0.1)

The library you're browsing is using Curator/ZooKeeper to give you proper service discovery and dependency monitoring using rather convention then configuration.

You can read more on how the service discovery is done using Curator on the Service Discovery documentation page.

microservice.json file

The heart of your application is the microservice.json file. The file defines three things:

  • The context in which your microservice will be deployed
  • Fully qualified name of your microservice
  • List of the dependencies

But lets look at the file (think internet shop and microservice that handles user registration, so it must create users, sign them up for newsletters and send confirmation emails).

    {
        "prod": {
            "this": "foo/bar/registration",
            "dependencies": {
                "users": "foo/bar/users",
                "newsletter": {
                    "path": "foo/bar/comms/newsletter",
                    "load-balancer": "random",
                    "contentTypeTemplate": "application/vnd.newsletter.$version+json",
                    "version": "v1",
                    "stubs": "foo.bar.comms:newsletter-product:stubs"                    
                },
                "confirmation": {
                    "path": "foo/bar/security/confirmation",
                    "headers": {
                        "header1": "value1",
                        "header2": "value2"
                    }
                }
            }
        }
    }

Deployment context

Your microservice is deployed in the "prod" environment (see the root of the json).

Having this you can use single zookeeper server for many contexts, and while a prod context is not maybe the best example, it makes more sense when you have 7 jenkins agents building your application simultaneously - in that case you will just register your microservices in contexts under agent names.

Name of the microservice

Whatever is put here will be the fully qualified name of your microservice.

In the above example microservice will be registered under prod/foo/bar/registration and since we're using ServiceDiscovery implemented in Curator you will have all instances of your service registered under generated UUIDs under the above path. Service Discovery will out of the box give you different strategies for high availability.

Dependencies

The last section defines the dependencies that your microservice will be looking for. When starting everything up you will have possibility to either use an out-of-the-box strategy or implement your own on what should happen when a dependency is or is not available during the microservice boot and then what happens when a dependency disappears.

Dependencies are always defined with a key and a value. The key must be an unique identifier that you will reference from your code, while the value is a map containing configuration properties. Here are supported properties:

  • path - value of this property is fully qualified name of the dependency (when the path to the dependency changes, you do not have to change it everywhere in the code, just in this one place),
  • load-balancer - sets a type of load balancer strategy (available values are sticky, random and round-robin/round_robin/roundrobin); if provided type is not a correct one or the type is not set then the default one is set, i.e. round robin strategy,
  • contentTypeTemplate - template of a Content-Type HTTP header send to the service (it can contain $version variable that will be updated with the value assigned to the version property),
  • version - contains a version number of the MIME type we are using sending requests to the service,
  • headers - a map containing key-value entries that are directly set as HTTP headers of the request send to the service,
  • required - specifies whether the service we are depending on is a mandatory one or is optional: when set to true during the startup phase of our microservice the exception will be thrown in case the service we are depending on is not available, on the other hand if value of the property is false then by default a message is logged with information the service is not available.
  • stubs - colon separated name of the dependency in Nexus that holds stubs. Notation is groupId:artifactId:classifier or groupId:artifactId - the latter appends default stubs classifier. E.g. com.ofg:service:stubsand its equivalentcom.ofg:service`.

Usage

Register your service

If you are using spring, checkout the microdeps-spring-config that will create all the needed beans.

In all other cases it will most probably make sense for you to check out com.ofg.infrastructure.discovery.util.MicroDepsService.

This class takes all the configuration needed to start, then you call start() on it and your service will get registered. Check out the javadocs for the specific usage.

If you want to have more control over the specific classes used inside, feel free to check out the code to see how they are used.

Register custom Dependency Watchers

Use MicroDepsService.registerDependencyStateChangeListener or DependencyWatcher.registerDependencyStateChangeListener if you have chosen to create all the classes on your own.

The object you pass of class DependencyWatcherListener is a very simple listener

interface DependencyWatcherListener {        
    void stateChanged(String dependencyName, DependencyState newState)        
}

Now every time any of your dependency changes, you will get a notification with the dependencyName (the key from dependencies) and the state of it - it can be either that at least one is CONNECTED or all are DISCONNECTED. Just bare in mind you will be notified every time a node connects or disconnects so you might be getting number of CONNECTED notifications in a row.

Resolve dependency endpoints

Use com.ofg.infrastructure.discovery.ServiceResolver.getUrl(dependency), where dependency is the key from you dependency list.

This will give you url to your dependency that zookeeper thinks is alive. It is a good idea to run this every time you are accessing your dependency to be almost sure you're getting one that is alive and that you're using you HA strategy.

Just bare in mind, that if a service dies unexpectedly without proper closing the zookeeper connection there will be a timeout after which zookeeper will realise your dependency is dead. So allow timeouts there.

How to use it with Spring Boot?

If you want to profit from the whole core stack presented above just add a dependency:

repositories {
    jcenter()
}

dependencies {
    compile 'com.ofg:micro-infra-spring-boot-starter:0.8.20'
}

and enable it:

@SpringBootApplication
class YourMainClass {
}

if you want to use only parts of the system just scroll to the bottom of this page for more info.

How to use all of the core parts of the system?

With Swagger

If you want to profit from the whole core stack presented above just add a dependency:

repositories {
    jcenter()
}

dependencies {
    compile 'com.ofg:micro-infra-spring:0.6.0'
}

and enable microservice stack with swagger api documentation.

@Configuration
@ComponentScan
@EnableMicroservice              // microservice
@EnableMicroserviceDocumentation // swagger api documentation
class MyWebAppConfiguration {
}

Without Swagger

If you don't want to add Swagger and still want to have the whole base functionality just add a enable microservice stack without swagger:

repositories {
    jcenter()
}

dependencies {
    compile 'com.ofg:micro-infra-spring-base:0.6.0'
}

and

@Configuration
@EnableMicroservice
class MyWebAppConfiguration {
}

Swagger is enabled automatically when annotation com.wordnik.swagger.annotations.Api is used. To disable this feature use VM argument:

-Dcom.ofg.infra.microservice.documentation.auto=false

##How to use only parts of it?

If you want to just profit only from the selected modules (if that's actually possible) by enabling specific feature.

@Configuration
@EnableMetrics
class FooConfiguration {
}
@Configuration
@EnableHealthCheck
@EnableExceptionHandler
class FooConfiguration {
}

On Spring Boot application you need to disable autoconfiguration first:

-Dcom.ofg.infra.microservice.documentation.auto=false
-Dcom.ofg.infra.microservice.auto=false