Difficulty: beginner
Estimated Time: 15 minutes

The Audit Service

The law is the law. The Sarbanes–Oxley Act requires you to keep a track of every transaction you do on a financial market. The audit service records the shares you buy and sell in a database. It’s going to be a PostGreSQL database, but is would be similar with another database, even no-sql database. The database is going to be deployed in OpenShift.

In this chapter we are going to cover:

  • advanced asynchronous orchestration
  • asynchronous JDBC
  • Vert.x Web to build REST API
  • Managing secrets with OpenShift

1. Initialize katacoda environment

You may have noticed a script running in the terminal. This is getting the lab ready up to this scenario i.e. it is

  1. Cloning the source code
  2. Initialize the OpenShift environment
  3. Build and deploy the quote-generator scenario
  4. Build and deploy the portfolio-service sceanrio
  5. Build and deploy the compulsive-traders sceanrio
  6. Build and deploy the micro-trader-dashboard

2. Accessing data asynchronously

As said previously, Vert.x is asynchronous and you must never block the event loop. And you know what’s definitely blocking? Database accesses and more particularly JDBC! Fortunately, Vert.x provides a JDBC client that is asynchronous.

The principle is simple (and is applied to all clients accessing blocking systems):


However, interactions with databases are rarely a single operation, but a composition of operations. For example:

  1. Get a connection
  2. Drop some tables
  3. Create some tables
  4. Close the connection

3. The Audit service

The Audit service:

  1. Listens for the financial operations on the event bus
  2. Stores the received operations in a database
  3. Exposes a REST API to get the last 10 operations

Interactions with the database use the vertx-jdbc-client, an async version of JDBC. So expect to see some SQL code (I know you love it). But, to orchestrate all these asynchronous calls, we need the right weapons. We are going to use RX Java 2 for this.


In this scenaro, you covered

  • how to manage advanced asynchronous orchestration

  • how to interact with a database

  • how to build a REST API

  • how to manage secrets with OpenShift

MicroTrader Part 4: Audit Service

Step 1 of 6

Step 1

Composing methods returning Single

Open the io.vertx.workshop.audit.impl.AuditVerticle class:


The first important detail of this verticle is its start method. As the start method from the traders, the method is asynchronous, and report its completion in the given Future object.

Vert.x would consider the verticle deploy when the Future is valuated. It may also report a failure if the verticle cannot be started correctly.

Initializing the audit service includes:

  • Discover and configure the database (already in the code), and prepare the database (create the table),
  • Start the HTTP service and expose the REST API,
  • Retrieve the message source on which the operation are sent

So, it’s clearly 3 independent actions, but the audit service is started only when all of them has been completed. So, we need to implement this orchestration.

Replace the matching // TODO: retrieveSingles block with code below

Single<JDBCClient> databaseReady = jdbc
    .flatMap(client -> initializeDatabase(client, true));
Single<HttpServer> httpServerReady = configureTheHTTPServer();
Single<MessageConsumer<JsonObject>> messageConsumerReady = retrieveThePortfolioMessageSource();

Single<MessageConsumer<JsonObject>> readySingle = Single.zip(databaseReady, httpServerReady,
    messageConsumerReady, (db, http, consumer) -> consumer);

This code should retrieves 3 Single objects (from methods provided in the class) and wait for the completion of the three tasks. The three singles are then combined in one Single<MessageConsumer<JsonObject>>. Don’t forget that the initializeDatabase requires the JDBC client as parameter and so should be called once the jdbc Single has completed. Also look at the retrieveThePortfolioMessageSource method to see how you can create a Single object from an already known entity (we should have used service discovery - it’s just to give an example). When you have the three Singles, zip them to be notified when all of them have completed. The zip function must return the MessageConsumer<JsonObject>>.

On success this Single registers a message listener on the portfolio message source storing the operation in the database for each received message.

Its completion notifies Vert.x that the start process is completed (or successfully or not), it calls future.complete() and future.fail(cause).

Local Web Browser
OpenShift Console