WildFly: How to store sessions in the Database

In this guide, we’ll explore the steps to persist sessions in a database using WildFly or JBoss EAP. This can be particularly useful in scenarios where you need to distribute sessions across multiple server instances or require persistent storage of session data.

Prerequisites

Before we begin, ensure you have the following prerequisites:

Step 1: Configure Infinispan Subsystem

Configure the Infinispan subsystem with an Infinispan invalidation-cache that uses a shared, persistent JDBC store referencing the DataSource created in step 1.

Example configuration in the standalone-ha.xml:

<invalidation-cache name="http-db">
     <jdbc-store data-source="PostgrePool" dialect="POSTGRES" passivation="false" purge="false" shared="true">
         <table prefix="${jboss.node.name}">
               <data-column type="BYTEA"/>
        </table>
    </jdbc-store>
</invalidation-cache>

Please note that, to get around the following error in PostgreSQL, we have defined a Table prefix for BYTEA columns:

Caused by: java.util.concurrent.CompletionException: org.infinispan.persistence.spi.PersistenceException: ERROR: type \"binary\" does not exist

You can safely remove the table element for other Database configurations

Step 2: Apply Cache Configuration

Next, we will test inour applications the invalidation cache which stores the Sessions on the database. There are several options to do that. We will discuss them one-by-one in the following sections:

A. Make the Cache an Default Cache

If you want to store Sessions for all your Applications, then the simplest strategy is to set the default-cache attribute in your Infinispan subsystem. For example, to offload all web Sessions, change the default cache of the web cache container to use your cache:

<cache-container name="web" default-cache="http-db">...</cache-container>

B. Modify the distributable-web Subsystem

If you are using a recent WildFly distribution, then you can also apply the change in the distributable-web subsystem which decouples you from the infinispan subsystem. You can define a new infinispan-session-management profile to use the invalidation cache. For example:

<subsystem xmlns="urn:jboss:domain:distributable-web:4.0" default-session-management="database-cache" default-single-sign-on-management="default">
             <infinispan-session-management name="database-cache" cache-container="web" cache="http-db" granularity="SESSION">
                 <primary-owner-affinity/>
            </infinispan-session-management>
    . . .
</subsystem>

With the above change, all your Web applications will use the database-cache profile.

Alternatively, you can leave the “default” profile and include in your application the following /WEB-INF/distributable-web.xml :

<?xml version="1.0" encoding="UTF-8"?>
<distributable-web xmlns="urn:jboss:distributable-web:4.0">
    <session-management name="database-cache"/>
/distributable-web>

With this change, you can achieve an application-level configuration of your caches.

C. Configure Application-Specific Session-Management Profile

Finally, it is worth mentioning that you can bundle the whole distributable-web configuration in your /WEB-INF/distributable-web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<distributable-web xmlns="urn:jboss:distributable-web:4.0">
    <infinispan-session-management name="database-cache" cache-container="web" cache="http-db" granularity="SESSION">
        <primary-owner-affinity/>
    </infinispan-session-management>
</distributable-web>

In this case, your infinispan-session-management configuration will be fully part of your application.

Step 3: Make Your Web Application Distributable

Finally, ensure your web application is distributable by adding the <distributable/> element to your web.xml file. For example:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="...">
    <distributable/>
    <!-- ... -->
</web-app>

Step 4: Test your HTTP Session storage on the DB

Assumed your Database is up an running, then deploy a Web application which meets the requirements discussed so far. You should be able to see two tables per application: (the name varies according to your Hostname and application name):

jboss store sessions on the database

By accessing HTTP Sessions in your applications you should be able to see binary data in the Database table. For example:

jboss wildfly store http session db

By the way: do you wonder how to set up a quick environment with PostgreSQL and the Adminer Web interface on Docker? then check this article: How to manage a PostgreSQL Database with Docker

Conclusion

Persisting sessions in a database with WildFly can enhance the scalability and reliability of your applications. By following the steps outlined in this guide, you can leverage WildFly’s features to efficiently manage session data in a database, enabling seamless distribution and persistence across your application servers.