<commit_before># Overview

[Microservices](https://en.wikipedia.org/wiki/Microservices) is a recent software development approach that allows to build scalable, distributable and fault-tolerant applications. Each microservice is a small independent program (OS process) that does only one thing but does it well. Obviously those microservices should communicate to each other in some way.

The diagram below shows one possible approach when microservices communicate through a common bus:

![msb-java overview](msb-java overview.png)

[MSB-Java](https://github.com/tcdl/msb-java) (for Java) and [MSB](https://github.com/tcdl/msb) (for Node.js) are libraries that can be used by microservice developers to streamline development in the following ways:
* Hide interaction with the bus behind simple interfaces. They support different pluggable adapters for different bus implementations.
* Hide message creation/parsing.
* Natively support some enterprise integration patterns like [Request-Reply](http://www.enterpriseintegrationpatterns.com/RequestReply.html),  [Correlation Identifier](http://www.enterpriseintegrationpatterns.com/CorrelationIdentifier.html), [Publish-Subscribe Channel](http://www.enterpriseintegrationpatterns.com/PublishSubscribeChannel.html) and others.
* MSB and MSB-Java are compatible at protocol level. So Java microservices are able to interact with Node.js microservices.

MSB = MicroService Bus.

# Supported microservice models

Below we consider different ways in which microservices can interact with each other using MSB-Java.

## Listening microservice

![Simple Service](Simple Service.png)

The diagram shows a simple microservice (`MyService`) that:
* is subscribed to `request topic`
* processes the incoming request and calculates result
* produces the result in `response topic`.

## Producing microservice

### General flow (no acks)

![Aggregating Service](Aggregating Service.png)

This diagram shows situation when `MyService1` needs additional information from `MyService2` to process the incoming request. The image contains a lot of arrows so they are numbered to ease understanding of their sequence.

### Adding acks to the mix

![Ack processing](Ack processing.png)

By using ack messages `MyService2` can declare to `MyService1` how many responses it's going to produce and how much time it's going to take.

## Message format

Messages are UTF-8 JSON strings. Incoming messages may be validated (depending on configuration settings) against [JSON schema](/core/src/main/resources/schema.js).

Here's an example of a message:

```json
{
  "id": "3c19407acf321800000279b5",
  "correlationId": "3c19407acf3218000003598f",
  "topics": {
    "to": "test:aggregator",
    "response": "test:aggregator:response:3c19407acf32180000016402"
  },
  "meta": {
    "ttl": null,
    "createdAt": "2015-04-17T16:24:26.737Z",
    "durationMs": 0,
    "serviceDetails": {
      "hostname": "Pieter-s-MacBook-Pro.local",
      "ip": "10.166.139.50",
      "pid": 6144,
      "name": "msb",
      "version": "0.3.4",
      "instanceId": "3c19407acf32180000016402"
    }
  },
  "ack": {
    "responderId": "3c824cd39fe87366001ed82e",
    "responsesRemaining": -1,
    "timeoutMs": 500
  },
  "payload": {
    "url": "http://mock",
    "method": "GET",
    "params": {},
    "query": {},
    "headers": {},
    "body": {}
  }
}
```

Here's the field description:

Message field           | Description
------------------------|------------
id                      | unique id of a message
correlationId           | unique id of message sequence related to single conversation. Responses and acks have the same `correlationId` as the request. Also if a microservice receives a request with `correlationId` = "abc" and as a part of processing it sends another request to another microservice it re-uses the same correlationId (for easy tracing of message flow though a system)
topics                  | section for routing information
  to                    | name of the topic this message is sent to
  response              | name of the topic where response to this message is expected
meta                    | section for message meta information
  ttl                   | time to live of a message. If ttl is exceeded an incoming message is ignored
  createdAt             | timezone-aware date/time when message was created
  durationMs            | time taken to process the message
  serviceDetails        | section for microservice details
    name                | microservice name
    version             | microservice version
    instanceId          | unique id of the running instance of a microservice
    hostname            | name of the host the microservice is runnig on
    ip                  | IP address of a host a microservice is running on
    pid                 | process id of a running microservice
ack                     | section that describes acknowledgement part of the message
  responderId           | unique id of a _responder_. _Resonder_ is a component that is created for _each_ request and is used to send responses and acks back
  responsesRemaining    | adjusts the number of responses expected from this _responder_
  timeoutMs             | defines amount of time this _responder_ needs to completely process the message and send all responses back
payload                 | section for message payload (REST-like)
  headers               | provides things like authorisation, information about the body and information about the user. (Request Meta Info/Who)
  params                | provides hierarchical ids of the entities acted upon. (What)
  query                 | provides instructions. (How)
  statusCode            | response status code
  statusMessage         | response status message
  body                  | provides data/state
  bodyBuffer            | base64-encoded binary body

# MSB-Java API

## Maven modules

MSB-Java has pluggable architecture that allows to use different bus adapters transparently.
It consists of the following Maven modules:
- msb-java-core: core classes
- msb-java-amqp: AMQP adapter that allow to use AMQP broker (for example RabbitMQ) as a bus
- msb-java-cli: CLI monitoring tool
- msb-java-examples: examples of various microservices

## Core classes

All classes and interfaces that should be used by a microservice developer reside in package  [io.github.tcdl.msb.api](/core/src/main/java/io/github/tcdl/msb/api) and its subpackages. [This Appendix](#api-class-diagram) shows relation between all those classes.

The following subsections describe the most important ones.

### [MsbContext](/core/src/main/java/io/github/tcdl/api/MsbContext.java)

Instance of [MsbContext](/core/src/main/java/io/github/tcdl/api/MsbContext.java) is a central object that should be used by microservice for proper initialization, accessing of the bus and shutting down.

* To initialize `MsbContext` one needs to use [MsbContextBuilder](/core/src/main/java/io/github/tcdl/api/MsbContextBuilder.java). During this step configuration files are read and some internal library objects are created and initialized.
* Instance of [ObjectFactory](/core/src/main/java/io/github/tcdl/api/ObjectFactory.java) is stored in `MsbContext`. The factory produces objects that need to be used by microservice to access the bus. A microservice should not create those objects directly.
* To shut down `MsbContext` one needs to use method `MsbContext.shudown`. This step is opposite to initialization: all initialized resources as well as connection to the bus are closed.

> If microservice developer does not want to invoke `shutdown` explictily he/she should instruct `MsbContextBuilder` to automatically register JVM shutdown upon `MsbContext` creation. That hook just invokes the method on JVM termination.

### [ResponderServer](/core/src/main/java/io/github/tcdl/api/ResponderServer.java)

[ResponderServer](/core/src/main/java/io/github/tcdl/api/ResponderServer.java) allows to listen to a given namespace, process requests from that namespace and provide responses and acks back. The instance should be created via `ObjectFactory`.

### [Requester](/core/src/main/java/io/github/tcdl/api/Requester.java)

[Requester](/core/src/main/java/io/github/tcdl/api/Requester.java) allows to send messages to a given namespace and optionally handle responses. The instance should be created via `ObjectFactory`.

## Typical microservice examples

Let's consider two simple microservices: one sends "PING" to another and the other responds "PONG".

[PingService](/examples/src/main/java/io/github/tcdl/msb/examples/PingService.java)

```java
package io.github.tcdl.msb.examples;

import io.github.tcdl.msb.api.MsbContext;<commit_msg>Fix for hyperlinks<commit_after># Overview

[Microservices](https://en.wikipedia.org/wiki/Microservices) is a recent software development approach that allows to build scalable, distributable and fault-tolerant applications. Each microservice is a small independent program (OS process) that does only one thing but does it well. Obviously those microservices should communicate to each other in some way.

The diagram below shows one possible approach when microservices communicate through a common bus:

![msb-java overview](msb-java overview.png)

[MSB-Java](https://github.com/tcdl/msb-java) (for Java) and [MSB](https://github.com/tcdl/msb) (for Node.js) are libraries that can be used by microservice developers to streamline development in the following ways:
* Hide interaction with the bus behind simple interfaces. They support different pluggable adapters for different bus implementations.
* Hide message creation/parsing.
* Natively support some enterprise integration patterns like [Request-Reply](http://www.enterpriseintegrationpatterns.com/RequestReply.html),  [Correlation Identifier](http://www.enterpriseintegrationpatterns.com/CorrelationIdentifier.html), [Publish-Subscribe Channel](http://www.enterpriseintegrationpatterns.com/PublishSubscribeChannel.html) and others.
* MSB and MSB-Java are compatible at protocol level. So Java microservices are able to interact with Node.js microservices.

MSB = MicroService Bus.

# Supported microservice models

Below we consider different ways in which microservices can interact with each other using MSB-Java.

## Listening microservice

![Simple Service](Simple Service.png)

The diagram shows a simple microservice (`MyService`) that:
* is subscribed to `request topic`
* processes the incoming request and calculates result
* produces the result in `response topic`.

## Producing microservice

### General flow (no acks)

![Aggregating Service](Aggregating Service.png)

This diagram shows situation when `MyService1` needs additional information from `MyService2` to process the incoming request. The image contains a lot of arrows so they are numbered to ease understanding of their sequence.

### Adding acks to the mix

![Ack processing](Ack processing.png)

By using ack messages `MyService2` can declare to `MyService1` how many responses it's going to produce and how much time it's going to take.

## Message format

Messages are UTF-8 JSON strings. Incoming messages may be validated (depending on configuration settings) against [JSON schema](/core/src/main/resources/schema.js).

Here's an example of a message:

```json
{
  "id": "3c19407acf321800000279b5",
  "correlationId": "3c19407acf3218000003598f",
  "topics": {
    "to": "test:aggregator",
    "response": "test:aggregator:response:3c19407acf32180000016402"
  },
  "meta": {
    "ttl": null,
    "createdAt": "2015-04-17T16:24:26.737Z",
    "durationMs": 0,
    "serviceDetails": {
      "hostname": "Pieter-s-MacBook-Pro.local",
      "ip": "10.166.139.50",
      "pid": 6144,
      "name": "msb",
      "version": "0.3.4",
      "instanceId": "3c19407acf32180000016402"
    }
  },
  "ack": {
    "responderId": "3c824cd39fe87366001ed82e",
    "responsesRemaining": -1,
    "timeoutMs": 500
  },
  "payload": {
    "url": "http://mock",
    "method": "GET",
    "params": {},
    "query": {},
    "headers": {},
    "body": {}
  }
}
```

Here's the field description:

Message field           | Description
------------------------|------------
id                      | unique id of a message
correlationId           | unique id of message sequence related to single conversation. Responses and acks have the same `correlationId` as the request. Also if a microservice receives a request with `correlationId` = "abc" and as a part of processing it sends another request to another microservice it re-uses the same correlationId (for easy tracing of message flow though a system)
topics                  | section for routing information
  to                    | name of the topic this message is sent to
  response              | name of the topic where response to this message is expected
meta                    | section for message meta information
  ttl                   | time to live of a message. If ttl is exceeded an incoming message is ignored
  createdAt             | timezone-aware date/time when message was created
  durationMs            | time taken to process the message
  serviceDetails        | section for microservice details
    name                | microservice name
    version             | microservice version
    instanceId          | unique id of the running instance of a microservice
    hostname            | name of the host the microservice is runnig on
    ip                  | IP address of a host a microservice is running on
    pid                 | process id of a running microservice
ack                     | section that describes acknowledgement part of the message
  responderId           | unique id of a _responder_. _Resonder_ is a component that is created for _each_ request and is used to send responses and acks back
  responsesRemaining    | adjusts the number of responses expected from this _responder_
  timeoutMs             | defines amount of time this _responder_ needs to completely process the message and send all responses back
payload                 | section for message payload (REST-like)
  headers               | provides things like authorisation, information about the body and information about the user. (Request Meta Info/Who)
  params                | provides hierarchical ids of the entities acted upon. (What)
  query                 | provides instructions. (How)
  statusCode            | response status code
  statusMessage         | response status message
  body                  | provides data/state
  bodyBuffer            | base64-encoded binary body

# MSB-Java API

## Maven modules

MSB-Java has pluggable architecture that allows to use different bus adapters transparently.
It consists of the following Maven modules:
- msb-java-core: core classes
- msb-java-amqp: AMQP adapter that allow to use AMQP broker (for example RabbitMQ) as a bus
- msb-java-cli: CLI monitoring tool
- msb-java-examples: examples of various microservices

## Core classes

All classes and interfaces that should be used by a microservice developer reside in package  [io.github.tcdl.msb.api](/core/src/main/java/io/github/tcdl/msb/api) and its subpackages. [This Appendix](#api-class-diagram) shows relation between all those classes.

The following subsections describe the most important ones.

### [MsbContext](/core/src/main/java/io/github/tcdl/msb/api/MsbContext.java)

Instance of [MsbContext](/core/src/main/java/io/github/tcdl/msb/api/MsbContext.java) is a central object that should be used by microservice for proper initialization, accessing of the bus and shutting down.

* To initialize `MsbContext` one needs to use [MsbContextBuilder](/core/src/main/java/io/github/tcdl/msb/api/MsbContextBuilder.java). During this step configuration files are read and some internal library objects are created and initialized.
* Instance of [ObjectFactory](/core/src/main/java/io/github/tcdl/msb/api/ObjectFactory.java) is stored in `MsbContext`. The factory produces objects that need to be used by microservice to access the bus. A microservice should not create those objects directly.
* To shut down `MsbContext` one needs to use method `MsbContext.shudown`. This step is opposite to initialization: all initialized resources as well as connection to the bus are closed.

> If microservice developer does not want to invoke `shutdown` explictily he/she should instruct `MsbContextBuilder` to automatically register JVM shutdown upon `MsbContext` creation. That hook just invokes the method on JVM termination.

### [ResponderServer](/core/src/main/java/io/github/tcdl/msb/api/ResponderServer.java)

[ResponderServer](/core/src/main/java/io/github/tcdl/msb/api/ResponderServer.java) allows to listen to a given namespace, process requests from that namespace and provide responses and acks back. The instance should be created via `ObjectFactory`.

### [Requester](/core/src/main/java/io/github/tcdl/msb/api/Requester.java)

[Requester](/core/src/main/java/io/github/tcdl/msb/api/Requester.java) allows to send messages to a given namespace and optionally handle responses. The instance should be created via `ObjectFactory`.

## Typical microservice examples

Let's consider two simple microservices: one sends "PING" to another and the other responds "PONG".

[PingService](/examples/src/main/java/io/github/tcdl/msb/examples/PingService.java)

```java
package io.github.tcdl.msb.examples;

import io.github.tcdl.msb.api.MsbContext;
{'fraction_non_alphanumeric': 0.08270891723388435, 'fraction_numerical': 0.01601555797060001, 'mean_word_length': 3.580560649724915, 'pattern_counts': {'":': 54, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 6, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2161323', 'n_tokens_mistral': 4906, 'n_tokens_neox': 4606, 'n_words': 1857}