Vert.x Distributed Microservices with Java.
Distributed Systems Development A-Z Guide.
Give us a message if you’re interested in Blockchain and FinTech software development or just say Hi at Pharos Production Inc.
Or follow us on Youtube to know more about Software Architecture, Distributed Systems, Blockchain, High-load Systems, Microservices, and Enterprise Design Patterns.
In our previous Vert.x articles we have looked at how to install Vert.x for development purposes and at simple RESTful service with Vert.x. If you have missed it, check it out.
This time we will develop a new microservice inside our project. Every new module has its own EventBus and in order to send messages between modules, we have to join them into the cluster. The first microservice is our REST API, the second microservice will be prepared for RocksDB integration. We will send GET and POST queries to the first one, then request a data from the second microservice via event bus, and return this data to the user.
RocksWorker.
Let’s add a new Maven module and create a package and add several classes. We will need several new class and one configuration file:
- RocksService interface and implementation — this is the definition of our future service;
- RocksServiceVerticle — we have to deploy the service, we can do this via a verticle
- Package-info.java — configuration file that defines auto-generation settings for two new useful classes, that Vert.x will create for us.
One more thing, to the global Maven configuration file, let’s add 3 new dependencies.
- vertx-service-proxy — this one creates a proxy for us. A proxy allows giving access to the isolated functionality from the outside world;
- vertx-codegen — this dependency adds a possibility to generate tons of boilerplate code just with a couple of annotations;
- vertx-hazelcast — this dependency creates a cluster for us.
Let’s add cluster settings to the common package. This is an XML file in the resources directory. We will not go deep inside cluster settings today, please refer to Vert.x documentation to know more about Hazelcast and cluster.xml.
Let’s take a look at package-info.java file. This file defines settings for boilerplate code generation. Here we say that module rocksworker contains classes to be generated.
Let’s define RocksService interface. The interface is straightforward. We define two string constants — the name and the address on event bus of our service. Also, we want to define two asynchronous methods to get and to create a user. Both methods don’t return anything but instead of that act asynchronously via handlers.
In the implementation of the interface in both methods, we return futures with placeholder responses. Both objects in responses will be replaced by RocksDB calls in the next article.
To define a verticle extended from our Microservice verticle class, we need to add the Common module as a dependency.
Let’s add one more method to the MicroserviceVerticle class. It will be used to publish information about new event bus service into service discovery.
Let’s go through RocksServiceVerticle. First of all, it’s extended from MicroserviceVerticle.
We define two global variables here. One is for binding the service to the address, another one is to manage consumer, e.g. get rid of it into the stop method.
We override the start method. Here we create a new instance of RocksService. Then create a ServiceBinder to bind the service to the address. Then we register service in ServiceBinder instance. And the last thing we do — we publish information about newly created service into service discovery.
On successful completion, we call a handler which will inform us about a new service appeared, just for the sake of clarity.
Mobile API.
In the Mobile API module, we need to add a new dependency — our RocksWorker module.
In ServerVerticle we add a new global variable that will represent a RocksService instance.
We create a new service through ServiceProxyBuilder class.
Let’s change handleRequest method to make possible to handle both GET and POST requests.
We define GET handler like this. We request a user from RocksService and respond with 200 and payload or 404 and nothing when a user is not found.
The same with the post request. We take userId from parameters, call RocksService and respond with 201 and new ID or 422 — unprocessable entity.
Cluster.
To make things work together, we have to add one small method Launcher class. Before Vert.x will initiate its instance we inject clustering mode into options and define a cluster host to localhost.
Let’s Try It.
To run the new service we need to create a new Application which will start the corresponded verticle.
We’re ready to go! Run both microservices and try to send both requests.
We have learned how to make two microservices communicate via event bus. You can find the full source code at our Github repo.
Thank you for reading!