Get Started with Hazelcast and Microprofile

What You’ll Learn

In this tutorial, you will learn how to use Hazelcast within Microprofile microservices.

The Microprofile application contains three endpoints that help you to put, read, and list the data.

You can either prefer using Hazelcast client to connect an existing Hazelcast cluster (Client/Server mode) or create Hazelcast instances along with your Microprofile servers to form a new cluster (Embedded mode).

In client mode, the application connects to an existing Hazelcast cluster. In this setup, the client is not responsible for holding any data but fetching/putting data from/to the Hazelcast cluster.

In embedded mode, the application initializes a single Hazelcast member instance which is used to keep the data. When you run the application multiple times, Hazelcast members build a cluster and share the data.

See documentation for the details on client/server and embedded topologies.

Before you Begin

  • A text editor or IDE

  • JDK 1.8+

  • Apache Maven 3.2+

Configure Hazelcast

Note that if you will use embedded Hazelcast instances, members will be created within your application and form a cluster automatically. However, if you will use Hazelcast client, you need to have a running Hazelcast cluster. You can have one with one of these methods:

  • Hazelcast Cloud

  • Docker Image

  • Hazelcast CLI

  • Download Packages

You can easily create a Hazelcast cluster on Hazelcast Cloud with just a few clicks. See Getting Started documentation for details.

You can start members inside Docker containers. See the documentation for details.

$ docker run hazelcast/hazelcast:$HAZELCAST_VERSION

You can start members via Hazelcast CLI. See the documentation for the installation instructions and details.

$ hz start

You can start members via start script in IMDG bundle.

$ sh bin/start.sh

You can find other ways of starting Hazelcast members and forming a cluster here.


Let’s configure our HazelcastInstance in HazelcastApplication.java:

  • Client

  • Embedded

@Produces
HazelcastInstance create() {
    ClientConfig clientConfig = new ClientConfig();
    // configure existing Hazelcast cluster address to be connected.
    clientConfig.getNetworkConfig().addAddress("127.0.0.1:5701");
    return HazelcastClient.newHazelcastClient(clientConfig);
}
Maps need to be configured in member configuration, not client.
@Produces
HazelcastInstance create() {
    Config config = new Config();
    // all other configurations (networking,
    // listeners, etc.) can be set here.
    MapConfig mapConfig = new MapConfig();
    mapConfig.setName(MAP_NAME);
    mapConfig.setTimeToLiveSeconds(30);
    config.addMapConfig(mapConfig);
    return Hazelcast.newHazelcastInstance(config);
}

create() method will supply HazelcastInstance wherever it is injected:

@Inject
HazelcastInstance instance;

Now that we have a HazelcastInstance, we can reach to the distributed map over the instance:

private IMap<Integer,String> getDistributedMap() {
    return instance.getMap(HazelcastApplication.MAP_NAME);
}

The map will have 30 seconds of time-to-live if it’s configured to do so:

MapConfig mapConfig = new MapConfig();
mapConfig.setName(MAP_NAME);
mapConfig.setTimeToLiveSeconds(30);
config.addMapConfig(mapConfig);

Be aware that this needs to be done on member configuration before it starts, not on client configuration.

And that’s all! The distributed map is ready to use now.

IMap<Integer,String> map = getDistributedMap();
map.put(1, "value");
map.get(1);
map.putIfAbsent(1, "another_value");

Run the Microprofile Application

Now, let’s build the servers and then deploy the applications.

$ mvn clean install

Start the first server listening on port 9080:

$ mvn -pl server1 liberty:run-server

In another terminal session, start the second server listening on port 9081:

$ mvn -pl server2 liberty:run-server

After two servers are up and ready, you will see the logs:

The HazelcastGuides1 server is ready to run a smarter planet.
...
The HazelcastGuides2 server is ready to run a smarter planet.

Let’s give it a try:

$ curl -X PUT "http://localhost:9080/application/map/put?key=1&value=greetings_from_server1"
Put: greetings_from_server1. Old value was: null

$ curl -X GET "http://localhost:9081/application/map/get?key=1"
{ 1 : greetings_from_server1 }

$ curl -X PUT "http://localhost:9081/application/map/put?key=2&value=cool"
Put: cool. Old value was: null

$ curl -X GET "http://localhost:9080/application/map/list"
Size: 2
{ 1: greetings_from_server1 }
{ 2: cool }

Note that after 30 seconds, these values will be evicted if the map is configured properly.

Summary

In this tutorial, you developed a simple application that uses Hazelcast to store the data. When you started two application instances, if they used Hazelcast client, they connected to a Hazelcast cluster and share the same map for fetching and storing data. Otherwise in embedded mode, the applications also created Hazelcast instances and they formed a cluster on their own to share data among them. In both cases, you could access the same data from both application instances.