Using Infinispan remote cache - PART 1: Docker Image

In this guide, we will extend the example created in WildFly Java Microservice - PART 1: Docker Image and use a remote Infinispan Server to cache HTTP Session data.

Prerequisites

To complete this guide, you need:

Infinispan Server

Infinispan is the most common solution used with WildFly when you want to cache some data outside WildFly.

Using Infinispan, for example, you can avoid users losing their session in case WildFly is shut down and re-started.

In this guide, we will use the containerized version of Infinispan: see Infinispan Server.

Start Infinispan

podman network create demo-network

podman run --rm --network=demo-network --name=my-infinispan \
  -p 11222:11222 \
  -e USER="admin" \
  -e PASS="123pippobaudo" \
  quay.io/infinispan/server:latest
Note
NOTE: We created the demo-network network and started the my-infinispan container with the --network=demo-network option: later in this guide, this will allow us to connect to the my-infinispan container from the my-jaxrs-app-infinispan container.
Note
you can check the container is running by opening http://localhost:11222/console/ in your browser and logging in as admin / 123pippobaudo

Maven Project

web.xml

Add the <distributable/> tag to the src/main/webapp/WEB-INF/web.xml file (if the src/main/webapp/WEB-INF/web.xml doesn’t exist then create it):

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
         version="6.0">
    <distributable/>
</web-app>

Infinispan Connection

Add a file named infinispan.cli to the root of the maven project:

infinispan.cli
/subsystem=jgroups/channel=ee:write-attribute(name=stack,value=tcp)
/subsystem=transactions:write-attribute(name=node-identifier,value=${transactions.node-identifier:wildfly1})
# add DNS_PING protocol to TCP stack
/subsystem=jgroups/stack=tcp/protocol=dns.DNS_PING:add(add-index=1, properties={dns_query="_ping._tcp.jgroups-dns-ping.myproject.svc.cluster.local"})
# connection to the remote infinispan server
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-infinispan-server:add(host=${infinispan.server.host}, port=${infinispan.server.port:11222})
batch
# remote-cache-container
/subsystem=infinispan/remote-cache-container=web-sessions:add(default-remote-cluster=infinispan-server-cluster, statistics-enabled=true, properties={infinispan.client.hotrod.auth_username=${infinispan.server.user:admin}, infinispan.client.hotrod.auth_password=${infinispan.server.password:123pippobaudo}, infinispan.client.hotrod.sasl_mechanism=DIGEST-MD5})
/subsystem=infinispan/remote-cache-container=web-sessions/remote-cluster=infinispan-server-cluster:add(socket-bindings=[remote-infinispan-server])
# hotrod
/subsystem=infinispan/remote-cache-container=web-sessions:write-attribute(name=modules,value=[org.wildfly.clustering.web.hotrod])
# PROTOSTREAM
/subsystem=infinispan/remote-cache-container=web-sessions:write-attribute(name=marshaller,value=PROTOSTREAM)
# set as default for session management
/subsystem=distributable-web/hotrod-session-management=remote-infinispan-session-management:add(remote-cache-container=web-sessions,granularity=SESSION)
/subsystem=distributable-web/hotrod-session-management=remote-infinispan-session-management/affinity=local:add
/subsystem=distributable-web:write-attribute(name=default-session-management,value=remote-infinispan-session-management)
run-batch

pom.xml

dependencies

Add the following dependency to dependencies section:

    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>

wildfly-maven-plugin

Add the following to the wildfly-maven-plugin configuration:

  • packaging-scripts pointing to the infinispan.cli file

  • web-clustering layer

You should end up with the wildfly-maven-plugin configured like in the following:

    <plugin>
        <groupId>org.wildfly.plugins</groupId>
        <artifactId>wildfly-maven-plugin</artifactId>
        <version>5.0.0.Final</version>
        <configuration>
            <feature-packs>
                <feature-pack>
                    <location>org.wildfly:wildfly-galleon-pack:32.0.0.Final</location>
                </feature-pack>
                <feature-pack>
                    <location>org.wildfly.cloud:wildfly-cloud-galleon-pack:7.0.0.Final</location>
                </feature-pack>
            </feature-packs>
            <layers>
                <layer>cloud-server</layer>
                <layer>web-clustering</layer>
            </layers>
            <packaging-scripts>
                <packaging-script>
                    <scripts>
                        <script>infinispan.cli</script>
                    </scripts>
                </packaging-script>
            </packaging-scripts>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>package</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

Java Classes

Modify the GettingStartedService class:

GettingStartedService.java
package org.wildfly.examples;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.servlet.http.HttpServletRequest;

@ApplicationScoped
public class GettingStartedService {

    @Inject
    private HttpServletRequest httpRequest;

    public String hello(String name) {
        String previousName = (String) httpRequest.getSession().getAttribute("NAME_PARAMETER");
        httpRequest.getSession().setAttribute("NAME_PARAMETER", name);
        return String.format("Hello '%s'." + (previousName == null ? "" : "(last time you were " + previousName + ")"), name);
    }
}

Build the application

$ mvn clean package
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.417 s
[INFO] Finished at: 2024-05-30T16:32:46+02:00
[INFO] ------------------------------------------------------------------------

Docker Image

Build the Docker Image

Build the Docker Image with the following command:

$ podman build -t my-jaxrs-app-infinispan:latest .
STEP 1/3: FROM quay.io/wildfly/wildfly-runtime:latest
STEP 2/3: COPY --chown=jboss:root target/server $JBOSS_HOME
-→ 5afd485c6552
STEP 3/3: RUN chmod -R ug+rwX $JBOSS_HOME
COMMIT my-jaxrs-app-infinispan:latest
-→ 625a63506dab
Successfully tagged localhost/my-jaxrs-app-infinispan:latest
625a63506dab171c4750f6be89e45c236591d40524b239307e32c716add01457

Run the Docker Image

Note that, when running the my-jaxrs-app-infinispan:latest Docker Image, we specify some environment variables used by WildFly to connect to the PostgreSQL database:

podman run --rm --network=demo-network -p 8080:8080 -p 9990:9990 \
    -e INFINISPAN_SERVER_HOST=my-infinispan \
    -e INFINISPAN_SERVER_PORT=11222 \
    -e INFINISPAN_SERVER_USER=admin \
    -e INFINISPAN_SERVER_PASSWORD=123pippobaudo \
    --name=my-jaxrs-app-infinispan \
    my-jaxrs-app-infinispan:latest
Note
NOTE: We started the my-jaxrs-app-infinispan container with the --network=demo-network option just like we did when we started the my-infinispan container: the two containers now run in the same demo-network network and we can connect to the my-infinispan container from the my-jaxrs-app-infinispan container using the my-infinispan DNS name

Check the application

Open http://localhost:8080/ in your Browser, enter some name in the Name field (e.g. "pippo") and press `Say Hello`".

Stop the application (press CTRL+C from the terminal where you started it).

Start the application once again.

Type a different name in the Name field and press Say Hello again: the page should display something like "last time you were pippo" and that means that the previous name was stored in the Infinispan Server.

Stop the Docker containers

Stop the running container:

podman stop my-jaxrs-app-infinispan
podman stop my-infinispan
< Back to Guides