Tutorial on Microservices with Kotlin, SpringBoot, Akka and Docker – part 2


In the previous post we have built the scaffold of our microservice project, implementing the Eureka registration service. Now we will begin ti add some real functionality, beginning (surprisingly) with the data access. Only the crucial aspects of the implementation will be covered here, so you may download the full code from the repository:

git clone https://github.com/gitgabrio/container-microservices-tutorial-2.git


For this tutorial we will create a simple entity, User, with the basic CRUD operations. We will use HsqlDb as in-memory database and JPA for ORM-mapping, with the utilities offered by Spring-Data. Let’s begin adding the module declaration to the parent pom:


This is the persistence-service pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">






Inside the resources directory we will put all the html templates used by Thymeleaf and the Spring configurations file: bootstrap.yml and application.yml:


# Spring properties
# Service registers under this name
      name: persistence-service


# Spring properties
  # Ignore Eureka dashboard FreeMarker templates
      enabled: false
  # Allow Thymeleaf templates to be reloaded at runtime
       cache: false
  # Trailing / mandatory
  # Template location for this application only
       prefix: classpath:/templates/

  # Database configuration
  # Spring Boot automatically creates a JPA EntityManagerFactory using Hibernate
  # but we need to override some defaults:
  #   1. Stop Hibernate automatically creating a schema, we are doing it in
  #      schema.sql. Instead check the tables match their JPA mapped classes
      ddl-auto: none
      naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
    database: HSQL
    show-sql: true

# Map the error path to error template (for Thymeleaf)
  path: /error

# HTTP Server
# HTTP (Tomcat) port
  port:  ${SERVICE_PORT:@service.port@}
      defaultZone: http://${RS_PORT_1111_TCP_ADDR:@rs.ip@}:${RS_PORT_1111_TCP_PORT:@rs.port@}/eureka/
    preferIpAddress: true
    leaseRenewalIntervalInSeconds: 5

#Test db
  url: jdbc:hsqldb:file:testdb
  username: SA
  driverClassName: org.hsqldb.jdbcDriver

# Disabling security for Actuator' REST services
    enabled: false
    enabled: false


Since this tutorial is focused on the microservices architecture, I will not explain all the details of this configuration: fell free to ask for further explanation, if needed.
Please note:

  • port: ${SERVICE_PORT:@service.port@}: this is the listening port of the application; as for the registration-server, will be injected at compile time;
  • defaultZone:http://${RS_PORT_1111_TCP_ADDR:@rs.ip@}:${RS_PORT_1111_TCP_PORT:@rs.port@}/eureka/: this is the address of the registration service; RS_PORT_1111_TCP_ADDR and RS_PORT_1111_TCP_PORT will be dynamically injected by the fabric8 plugin during image building (more about them in the image configuration), otherwise rs.ip and rs.port (defined in the persistenceservice pom.xml)will be used
  • preferIpAddress: true: this is needed mostly for applications running inside docker containers; without this, the service will register itself with the container id, so it could not be attainable by the other services


package net.microservices.tutorial.persistenceservice

import net.microservices.tutorial.persistenceservice.configurations.PersistenceConfiguration
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.cloud.client.discovery.EnableDiscoveryClient
import org.springframework.context.annotation.Import

import java.util.logging.Logger

 * Run as a micro-service, registering with the Discovery Server (Eureka).
 * Note that the configuration for this application is imported from
 * [PersistenceConfiguration]. This is a deliberate separation of concerns.
open class PersistenceServer {

    protected var logger = Logger.getLogger(PersistenceServer::class.java.name)

    companion object {

         * Run the application using Spring Boot and an embedded servlet engine.

         * @param args
         * *            Program arguments - ignored.
        @JvmStatic fun main(args: Array<String>) {
            SpringApplication.run(PersistenceServer::class.java, *args)

This is the application entry point. As for the registration service, there is a single annotation needed to transform the module in an Eureka client:


With this in place, we are telling Spring to instantiate the class as a Eureka client, taking the properties from the *.yml files.

image creation

What is left now is to configure the image to be built inside the docker pom docker/pom.xml: first, as the dependency on the persistence service:


then add this just below the registration service’ one:

            <!-- Persistence service -->
                            <!-- Alias name which can used for linking containers during runtime -->
                            <!-- ....................................... -->
                            <!-- Build configuration for creating images -->
                            <!-- ....................................... -->
                                <!-- Assembly descriptor holds the reference to the created artifact-->
                                <!-- Expose ports -->
                                <!-- Default command for the build image -->
                                <cmd>java -Djava.security.egd=file:/dev/./urandom -jar /maven/persistenceservice.jar
                            <!-- ............................................................... -->
                            <!-- Runtime configuration for starting/stopping/linking containers -->
                            <!-- ............................................................... -->
                                <!-- Assign dynamically mapped ports to maven variables (which can be reused in integration tests) -->
                                    <!-- Check for this URL to return a 200 return code .... -->
                                     <!-- ... but at max 30 seconds -->
                                    <!-- Links can be referenced via alias (registrationservice) or name (${docker.repo}/registration-service:${project.version}) -->
                                    <!-- THIS SHOULD CREATE SOME RS_XXX variables -->

This is almost identical to the registration service, but there are a couple of new tags:

  • dependsOn: this is to indicate the container dependency, i.e. we are telling to the plugin that the container for this image requires the registrationservice container
  • links: this is needed to inject in the persistence service container some properties of the registration service one

In the previous post I have explained how to inject properties inside container as environment variables, and that some of them are automatically generated and injected by the fabric8 plugin. In the documentation you will find more explanation; simply put, with  &lt;link&gt;registrationservice:rs&lt;/link&gt; we are telling to the plugin to use “rs” as prefix for some automatically generated properties, with the following convention (everything upper-case):


For the current project, the port number is 1111 (registration.service.port), the prefix is rs, and let’s say that the registration container ip is Following the above rules, we will have:


This properties will be injected as environment variables in the persistence service container. Now, if you look back at application.yml, you will find exactly these:

defaultZone: http://${RS_PORT_1111_TCP_ADDR}:${RS_PORT_1111_TCP_PORT}/eureka/

Now, calling from the root directory

mvn install 

We should be able to build all the modules and the two images.
Last, let’s start them all. Go to the docker directory and type

mvn docker:start

We should have:

the two  containers up and running

# docker ps
CONTAINER ID IMAGE                        COMMAND                CREATED            STATUS            PORTS                  NAMES
36909d6973b0 ***/persistence-service:0.1 "/bin/sh -c 'java -Dj"  About a minute ago Up About a minute>2222/tcp distracted_varahamihira
3f8bebf677ca ***/registration-service:0.1 "/bin/sh -c 'java -Dj" 2 minutes ago      Up About a minute>1111/tcp jovial_galileo

the registration service  here

the persistence service here

the persistence service registered inside the registration service

some REST for CRUD operation


Well, feel free to look in the code to see what REST services are implemented
To clone the project:

git clone https://github.com/gitgabrio/container-microservices-tutorial-2.git

In the next part we will add another Eureka client container that will implement a long time request service so… stay tuned!!!

Any comment and suggestion will be greatly appreciated!!!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s