Micronaut Kafka Consumer Producer example.

Micronaut Kafka consumer and producer example.

Micronaut is a java framework and it’s been popular to develop microservice-based applications because of lower memory footprint and fast startup.

In this article, we will see how to write down simple Kafka consumers and producers using the micronaut framework. 

You can read my articles on micronaut framework on https://www.techwasti.com/

Start generating project using https://micronaut.io/launch/

You can create a project either using the launch site or using CLI tool.

$ mn create-app techwastikafkaexample --features kafka

Micronaut version for this demo is 2.0.0 and Java 8.

generating project and adding Kafka profile CLI provides powerful option such as;

$ mn create-app techwasti-kafka-service --profile kafka

Prerequisites:– 

  1. Java programming
  2. Kafka
  3. Micronaut

I am assuming the people. You know about this if you don’t know then learn it.

Micronaut features dedicated support for defining both Kafka Producer and Consumer instances.

Kafka Producer:-

We will create one simple Producer using annotation.

package com.techwasti.kafkaex;

import io.micronaut.configuration.kafka.annotation.KafkaClient;
import io.micronaut.configuration.kafka.annotation.KafkaKey;
import io.micronaut.configuration.kafka.annotation.Topic;

@KafkaClient
public interface GreetMessageClient {

    // greet is a kafka topic
    @Topic("greet")
    void sendGreetMessage(@KafkaKey String day, String message);

    void sendGreetMessage(@Topic String topic, @KafkaKey String day, String message);
}

@KafkaClient annotation is used to mark this is the kafka client.

@Topic annotation is indicated, on which topic message should get published. 

@Kafkakey annotation is to have a message key.

In the above code snippet we have defined two methods:

  1. In the first method accepting two arguments key and value and topic name is annotated using @Topic. 
  2. In the second method instead of annotating the topic name, we are accepting the topic name in the argument. 

If you omit the @KafkaKey then it’s null.

As we are aware of the beauty of micronaut framework, it will produce an implementation of the above client interface. We can retrieve this instance either by looking up the bean from ApplicationContext or by injecting the bean using @Inject. 

GreetMessageClient client = applicationContext.getBean(GreetMessageClient.class); client.sendProduct("Thursday", "Good morning");

Now our producer is ready and we sent a successful message as well.

Let us create Kafka Consumer.

Kafka Consumer:-

As we have seen a couple of annotations to create a producer and produce a message over a topic. The same way we have @KafkaListener annotation to create a kafka consumer.

package com.techwasti.kafkaex;

import io.micronaut.configuration.kafka.annotation.KafkaKey;
import io.micronaut.configuration.kafka.annotation.KafkaListener;
import io.micronaut.configuration.kafka.annotation.OffsetReset;
import io.micronaut.configuration.kafka.annotation.Topic;

@KafkaListener(offsetReset = OffsetReset.EARLIEST)
public class GreetMessageConsumer {

    @Topic("greet")
    public void receive(@KafkaKey String day, String message) {
        System.out.println("Got Message for the  - " + day + " and Message is  " + message);
    }
}

@KafkaListener is used to indicate this is kafka consumer and while reading a message from the topic “greet” and offset should be earliest this will start reading a message from the start.

receive method having two arguments one is key and another one is the message. 

This is a simple example of having kafka consumers and producers. 

Advanced Options for producer and consumer:

@Header: To add a header to kafka message. 

When we want to add some header into the kafka producer when we produce a message, let us say we want to add authentication token while publishing message over kafka in this case 

e.g.

@Header(name = “JWT-Token”, value = “${my.authentication.token}”)

Also, you can pass the header as a method argument the same as a topic name. 

@Body: to explicitly indicate the message body.

Generally, the value sent by the producer resolved using @Body annotation only but if we haven’t mentioned it then the first argument resolved as message body. 

e.g 

@Topic(“greet”)
void sendGreetMessage(@KafkaKey String day, String message);

or

@Topic(“greet”)
void sendGreetMessage(@KafkaKey String day, @Body String message);

For more such things please visit micronaut documentation.

Reference:

https://micronaut-projects.github.io/micronaut-kafka/latest/guide/

Micronauts Launch: The best way to getting started.

Micronaut has launched a website to generate the Micronauts project using the website without installing the Micronauts CLI SDK.

In a couple of blogs, we have seen about Micronauts if you don’t know you can check below blog post:

Micronaut is very much similar to the spring framework. Micronaut took inference from Spring framework and most the API are in sync only, that’s why adopting Micronauts for spring developer is very easy. As we have start.spring.io to start and create spring or spring boot project on the same note Micronauts also launched website aka Micronauts launch.

https://micronaut.io/launch/

As we know we can generate micronaut project using CLI but we can take same advantage using website as well.

If you see here we have different options few are listed below.

  1. Application type
  2. Java version
  3. Base Package
  4. Name of application
  5. etc

1. Application type:-

Application type where we have to specify which type of application we want such as Application (web or any other application), CLI application, Serverless function, gRPC application, and Messaging application. This application type will help us to organize the dependencies.

2. Java Version:-

Java version where we have to specify on which JDK we want to develop your application, e.g Java 8,11, 14 etc.

3. Base Package:-

Base package here we have specify our package of the application under which we want organise our classes, interfaces.

e.g com.techwasti.micronaut.demo

4. Name:-

Here we have to specify name of the application.

e.g HelloworldLaunch.

5. Micronaut Version:-

Which micronaut version our application should be compatible latest one when I am writing this blog post is 2.0.0.

6. Language:-

Select which language do you want to write down the beautiful code, right now micronaut support java, kotlin and Groovy.

7. Build Tool:-

Select which build tool either from maven or gradle.

8. Test Framework:-

Here we have a choice to select the test framework anything from the list such as Junit, Spock, and kotlintest.

9. Features:

When you click on features button one popup will launch.

In features we have different groups such as cache, config, database, etc.

10. Diff:-

This is to show the difference. This is interesting option. Shows the changes that the selected features have on an application generated without any features selected.

11. Preview:-

Another best option this site provides is the preview of your project based on your selection.

The final option is to generate the project and once you click on this are getting zip file. After zip extraction, you will get below kind of structure.

Were we have docker file, build file, gitignore along with source directory structure. Download and import this in any of your IDE(eclipse, intellij) and happy coding.

This is it for now. Let me know your finding on this if any.

Micronaut with Graal native image example.

As we have seen in the last couple of articles on how to create simple Micronauts application development and dockerizing it. In this article, we are gone exploring Helloworld Graal micronaut application.

Here is the definition from Wikipedia. If you are crossing this article that means you are familiar with either of the topic.

GraalVM is a Java VM and JDK based on HotSpot/OpenJDK, implemented in Java. It supports additional programming languages and execution modes, like an ahead-of-time compilation of Java applications for fast startup and low memory footprint. The first production-ready version, GraalVM 19.0, was released in May 2019.

Let us start coding and simultaneously enjoy the topic.

Create a micronaut application using CLI:

$ mn create-app helloworld-graal --features=graal-native-image

The default option is not available to add Graal support we have to use this option  — features=graal-native-image.

If you are using Java or Kotlin and IntelliJ IDEA make sure you have enabled annotation processing.

Now let us create one simple POJO class to hold Play name to make it simple.

import io.micronaut.core.annotation.Introspected;

@Introspected
public class Play{

    private String name;

    public Play(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

@Introspected annotation is used to generate BeanIntrospection metadata at compilation time. This information is using the render the POJO as JSON using Jackson without using reflection.

Now let us create the Singelton Service class and return play name randomly.

(Note:- The play names are Marathi Play names of famous Sri Pu la Deshpande)

import javax.inject.Singleton;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

@Singleton
public class PlayService {
// create list of plays
    private static final List<Play> PLAYS = Arrays.asList(
            new Play("Tujhe Ahe Tujpashi"),
            new Play("Sundar Mee Honar"),
            new Play("Tee Phularani"),
            new Play("Teen Paishacha Tamasha"),
            new Play("Ek Jhunj Varyashi")
    );
 // to choose random play from PLAYS list
    public Play randomPlay() {
        return PLAYS.get(new Random().nextInt(PLAYS.size()));
    }
}

Now we need a controller to serve the request of random play name from service class.

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller
public class PlayController {

    private final PlayService playService;

    public PlayController(PlayService playService) {
        this.playService = playService;
    }

    @Get("/randomplay")
    public Play randomPlay() {
        return playService.randomPlay();
    }
}

Created controller and injected service object using constructor injection and mapping of GET method using @Get(“/randomplay”).

Now our application is ready you can test by executing below command.

$ ./gradlew run

http://localhost:8080/randomplay

JSON output 

{

 name: “Tee Phularani”

}

Let us create a Graal native image.

Micronaut only supported in Java or Kotlin for graal native-image.

While creating a project we have added — features=graal-native-image this is adding three important features. 

  1. svm(Substrate VM) and graal dependencies in build.gradle.
compileOnly "org.graalvm.nativeimage:svm"
annotationProcessor "io.micronaut:micronaut-graal"

2. A Dockerfile which can be used to construct the native image executing docker-build.sh

3. A native-image.properties file in the resource directory.

Args = -H:IncludeResources=logback.xml|application.yml|bootstrap.yml \
       -H:Name=helloworld-graal \
       -H:Class=helloworld.graal.Application

This is very easy for developer to create a native image inside docker. Fire below two commands: 

$ ./gradlew assemble
$ ./docker-build.sh

Once image is ready we can create a container to verify our understanding. 

$ docker run -p 8080:8080 helloworld-graal

To test the application you can use curl with time:

$ time curl localhost:8080/randomplay

This is for now. You can check the time difference with native image executable and docker with a native image. 

Source code download or clone from github: https://github.com/maheshwarLigade/micronaut-examples/tree/master/helloworld-graal

Dockerise Micronaut application.

Micronauts is a java framework to develop a cloud-native microservices application easily and seamlessly. If you don’t know about Micronaut Please go through below two articles. 

In this article, we are exploring a micronaut framework and How to dockerize it. 

Let us create a small micronaut REST service application and try to dockerize it.

Micronaut provides a CLI option to create an application easily.

$ mn create-app helloworld

This will scaffold a new Gradle project. If you prefer Maven, add a --build maven parameter. If you want to create a new Groovy or Kotlin project, add a --lang parameter.

$ mn create-app --lang groovy helloworld-groovy
$ mn create-app --lang kotlin helloworld-kotlin

These options depend on you, which language are you comfortable with.

These options depend on you, which language are you comfortable with. 

Once the project is ready we can import that in your favorite editor. I am using IntelliJ.

We are using already created Hello world app, source code is available at below location you can clone

https://github.com/maheshwarLigade/micronaut-examples/tree/master/helloworld

By default, micronaut app can create Docker file for you and docker file you can locate on current directory of your project <appname>/Docker 

e.g helloworld/Docker

The Default content of Docker file:

FROM adoptopenjdk/openjdk13-openj9:jdk-13.0.2_8_openj9-0.18.0-alpine-slim
COPY build/libs/helloworld-*-all.jar helloworld.jar
EXPOSE 8080
CMD ["java", "-Dcom.sun.management.jmxremote", "-Xmx128m", "-XX:+IdleTuningGcOnIdle", "-Xtune:virtualized", "-jar", "helloworld.jar"]

If you are familiar with docker then fine if not you can explore below article to understand docker.

https://www.techwasti.com/demystify-docker-container-technology-9a8e1ec3968b/

Micronaut create docker file with alpine-slim 

and JDK image which is used here is unofficial.

This repo provides Unofficial AdoptOpenJDK Docker Images,

Reference:- https://hub.docker.com/r/adoptopenjdk/openjdk13-openj9

Thrid line to copy the generated jar(helloworld.jar) file and the expose default port as 8080. Last line to launch the jar file.

For this example, I am using Gradle as a build tool

$ cd helloworld
$ ./gradlew run

To test whether code is working fine or not. (curl http://localhost:8080/hello)

Now build a Docker image from the docker file for that fire below command. 

To run the application with IntelliJ IDEA, you need to enable annotation processing:

  1. open Settings → Build → Execution → Deployment → Compiler →Annotation Processors
  2. Set the checkbox Enable annotation processing

As we know micronaut CLI generates a Dockerfile by default, making it easy to package your application for a container environment such as Kubernetes.

$ docker build . -t hello-world-ex

Fire above command to create a docker image. -t 1.0.0 indicates the tag for this image. Now our image is ready to make a container from its fire below command. 

$ docker run --rm -p 8080:8080 hello-world-ex

As we have exposed 8080 port in docker file. We are doing port mapping to an external system.

to verify the docker image fire below command.

$ curl http://localhost:8080/hello

In this article, we have seen dockerizing micronaut apps. We have created helloworld application and created a docker image using the existing Docker file. You can edit the docker file and optimize it as per your requirement. 

Installation of Micronaut on Mac(OSX) & Linux.

Micronaut is a full framework to develop cloud native microservice architecture based application using java, kotlin or Groovy.

Let us check the steps required to install micronaut on OSx.

Simple and effortless start on Mac OSX, Linux, you can use SDKMAN! (The Software Development Kit Manager) to download and configure any Micronaut version of your choice.

INSTALLING WITH SDKMAN:

This tool makes installing of a Micronaut on any Unix based platform such as Linux, OSx.

Open a terminal and install SDKMAN,

$  curl -s https://get.sdkman.io | bash

Follow the on-screen instructions to complete installation.

Then fire below command after installation of SDKMAN to configure SDKMAN.

 $ source "$HOME/.sdkman/bin/sdkman-init.sh"

Once above two steps are in align then go and setup micrnaut using SDKMAN,

$ sdk install micronaut

After installation is complete it can be validated with below command.

$ mn --version
installation and validation of micronaut

this is the simple steps with SDKMAN.

INSTALLING WITH HomeBrew:

Before installation using homebrew you should update homebrew version

$ brew update

In order to install Micronaut, run following command:

$ brew install micronaut

After installation is complete it can be validated with below command.

$ mn --version

Installing with MacPorts:

Before installing it is recommended to sync the latest Portfiles, So that there shouldn’t be any issue,

$ sudo port sync

To install Micronaut, run following command

$ sudo port install micronaut

After installation is complete it can be validated with below command.

$ mn --version

Above are they three different way we can setup micronaut framework on MacOS and linux based OS.

Micronaut java full stack Microservice Framework!!

Micronaut is a modern, JVM-based, full-stack microservices framework designed for building modular, easily testable microservice applications.

Micronaut is the latest framework designed to make creating microservices quick and easy.

Micronaut is a JVM-based framework for building lightweight, modular applications. Developed by OCI, the same company that created Grails. Micronaut is developed by the creators of the Grails framework and takes inspiration from lessons learned over the years building real-world applications from monoliths to microservices using Spring, Spring Boot, and Grails.

Micronaut supports Java, Groovy or Kotlin.

Features of Micronaut:-

One of the most exciting features of Micronaut is its compile-time dependency injection mechanism. If you know the spring-boot mostly using reflection API and proxies which is always at run time and that causing the spring boot application needs a more startup time as compared to Node application. 

  1. First-class support for reactive HTTP clients and servers based on Netty.
  2. An efficient compile time dependency injection container. 
  3. Minimal startup time and lower memory usage.
  4. Cloud-native features to boost developer productivity.
  5. Very minimal learning curve because Micronaut code looks very similar to Spring Boot with Spring Cloud.

What’s wrong with Spring Boot?

Disclaimer 

There is nothing wrong with spring boot. I am a very big fan of spring projects including spring, spring Boot, Spring Data, etc. Spring Boot is a good and very elegant solution and it makes developer job easier than anything, just add one dependency and magic will happen for you. 

When spring is providing things on your fingertip that means spring is doing so many things under the hood for you. Spring does reflection, proxy classes and injection and many more and for this, you have to pay the cost because spring does things at runtime. You have pay in terms of memory, CPU cycles and application bootstrap time.

Micronaut addressed some of these problems using ATC (Ahead of time compilation), GraalVM. Micronaut does major things at compile time that reduces memory footprint and CPU utilization this leads to reduce in application bootstrap time. Currently, spring is not supporting GraalVM and Micronaut is supporting this is also a big difference. 

GraalVM is basically a high-performance polyglot VM. GraalVM is a universal virtual machine for running applications written in JavaScript, Python, Ruby, R, JVM-based languages like Java, Scala, Groovy, Kotlin, Clojure, and LLVM-based languages such as C and C++.

Now we know what is and why Micronaut and a couple of features. Let us setup Micronaut and we will create one simple Hello world application. 

Setup Micronaut?

To install or setup micronaut is a very easy task. Go to this page https://micronaut.io/download.html

Either you can download binary, or use SDKMAN to setup micronaut on your favorite OS.

Using SDKMAN

Simply open a new terminal and start:

$ curl -s https://get.sdkman.io | bash

$ source “$HOME/.sdkman/bin/sdkman-init.sh”

$ sdk install micronaut

$ mn — version

Now installation is done let us create simple Hello world application

mn create-app hello-world

By Default Micronaut uses Gradle as a build tool you can also specify maven as well.

mn create-app hello-world --build maven

Using Homebrew

Before installing make sure you have the latest Homebrew installed.

$ brew update

$ brew install micronaut

Using Binary on windows

  1. Download the latest binary from
  2. Extract the binary to appropriate location
  3. Create an environment variable MICRONAUT_HOME which points to the installation directory
  4. Update the PATH environment variable, append %MICRONAUT_HOME%\bin

Now enjoy the coding.

Let us have HelloWorld controller 

import io.micronaut.http.MediaType; 
import io.micronaut.http.annotation.Controller; 
import io.micronaut.http.annotation.Get; 
@Controller("/hello")  
public class HelloController {  
    
@Get(produces = MediaType.TEXT_PLAIN)      
public String index() { 
        
return "Hello World";     
 
} 
}

Now enjoy the output:

$ curl http://localhost:8080/hello 

> Hello World

Conclusion:-

Spring boot and micronaut both have some pros and cons. As per my understanding if you are developing a new greenfield application start with micronaut but don’t rewrite existing application of spring boot to micronaut unless and until you are facing some serious performance issues. If you are migrating from monolith to cloud-native microservice then micronaut is the good option. Please let us know your thoughts on this.

Reference link:

This is the performance comparison between spring boot and micronaut.

https://docs.micronaut.io/latest/guide/index.html