Article
· Aug 15, 2023 8m read

Java Quarkus application working with IRIS

As an example of an application on Java working with Hibernate dialect for IRIS, wanted to use RealWorld application, and found realization for Quarkus. RealWorld application is an example of an application close to some real one, with already prepared tests for the backend. Most of the examples of realizations can be found here

RealWorld Example App

The RealWorld example application is often referred to as the "Wikipedia for building full-stack applications." It serves as a standardized prototype that developers can use to create applications using various programming languages and frameworks. The application provides a real-world use case by mimicking a blogging platform, complete with features like user authentication, profile management, article posting, and comments. With a comprehensive set of specifications, including ready-made backend API documentation and frontend designs, it allows developers to see how the same functional requirements are implemented across different technology stacks. The RealWorld example is widely used as a learning tool and a benchmark for comparing various technologies.

Quarkus

Quarkus is an open-source, Kubernetes-native Java framework tailored for the GraalVM and HotSpot. Created with the aim to enhance the modern cloud-native environment, it significantly reduces the footprint and startup time of Java applications. Quarkus is known for its "container-first" philosophy, allowing developers to build lightweight, high-performing applications with a focus on microservices architecture. This flexibility has made it a popular choice for organizations looking to transition into serverless or cloud-based platforms, combining both imperative and reactive programming models. Whether it's a traditional web application or a complex system of microservices, Quarkus provides a robust platform for building scalable and maintainable software.

Original realization of the project can be found here: https://github.com/diegocamara/realworld-api-quarkus. It uses Embbedded in-memory database H2 during tests and PostgreSQL in actual run. And uses Quarkus version 2. 

I needed to upgrade it to the latest version of Quarkus 3, which uses the latest version of Hibernate 6.

Configure for IRIS

Then we can add, InterSystems JDBC driver, this project uses Maven, so, we need to change pom.xml. To be able to use InterSystems JDBC driver, we need to add link to GitHub repository where it's stored.

<repositories>
    <repository>
        <id>InterSystems IRIS DC Git Repository</id>
        <url>https://raw.githubusercontent.com/intersystems-community/iris-driver-distribution/main/JDBC/JDK18/</url>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
        </snapshots>
    </repository>
</repositories>

And add driver as a dependency

<dependency>
    <groupId>com.intersystems</groupId>
    <artifactId>intersystems-jdbc</artifactId>
    <version>3.7.1</version>
</dependency>

And only Hibernate dialect left. And thanks to @Yuri Marx we can install it this way

<dependency>
	<groupId>io.github.yurimarx</groupId>
	<artifactId>hibernateirisdialect</artifactId>
	<version>1.0.0</version>
</dependency>

Now it's time to switch tests to IRIS. The database connectivity in tests implemented in file DatabaseIntegrationTest.java. Just change to IRIS from H2 in a couple places

  private static Properties properties() {
    Properties properties = new Properties();
    properties.put(Environment.DRIVER, "com.intersystems.jdbc.IRISDriver");
    properties.put(Environment.DIALECT, "io.github.yurimarx.hibernateirisdialect.InterSystemsIRISDialect");
    properties.put(Environment.SHOW_SQL, true);
    properties.put(Environment.FORMAT_SQL, true);
    properties.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
    properties.put(Environment.HBM2DDL_AUTO, "create-drop");
    properties.put(Environment.DATASOURCE, dataSource);
    return properties;
  }

And during actual DataSource creation, where we define the the host, port, namespace and credentials to access IRIS, using IRISDataSource from the JDBC driver

  private static DataSource dataSource() {
    IRISDataSource jdbcDataSource = new IRISDataSource();
    jdbcDataSource.setServerName("localhost");
    jdbcDataSource.setPortNumber(5572);
    jdbcDataSource.setDatabaseName("USER");
    jdbcDataSource.setUser("_SYSTEM");
    jdbcDataSource.setPassword("SYS");
    return jdbcDataSource;
  }

Clean function, requires small changes to follow IRIS SQL syntax, to clean data before any test without any checks.

  public void clear() {
    transaction(
        () ->
            entities.forEach(
                tableName ->
                    entityManager
                        .createNativeQuery("TRUNCATE TABLE %NOCHECK " + tableName)
                        .executeUpdate()));
  }

Run IRIS with docker-compose

docker-compose up -d

And we ready to run tests. There are two ways to run tests for Quarkus applications, using installed Quarkus cli, or with Maven, assuming you already have Java installed version 17 or 20.

./mvnw clean test 

The first run will take a time, downloading all the dependencies. But at the end it should finish, with a successful run of all tests. During the run it will display all the SQL queries executed on IRIS.

[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 41, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  33.405 s
[INFO] Finished at: 2023-08-15T18:37:05+04:00
[INFO] ------------------------------------------------------------------------

When our tests are passed, we ready run the server, and to do so, we need to switch application itself to IRIS too. To do so, we need to edit application.properties file with the new values

quarkus.datasource.db-kind=other
quarkus.datasource.jdbc.url=jdbc:IRIS://localhost:5572/USER
quarkus.datasource.jdbc.driver=com.intersystems.jdbc.IRISDriver
quarkus.datasource.username=_SYSTEM
quarkus.datasource.password=SYS
quarkus.hibernate-orm.dialect=io.github.yurimarx.hibernateirisdialect.InterSystemsIRISDialect

To run server, use this command

./mvnw compile quarkus:dev

And now we can run original tests, which comes from RealWorld project, to test API using newman. Needs a second terminal

./collections/run-api-tests.sh

And all tests passed

┌─────────────────────────┬────────────────────┬────────────────────┐
│                         │           executed │             failed │
├─────────────────────────┼────────────────────┼────────────────────┤
│              iterations │                  1 │                  0 │
├─────────────────────────┼────────────────────┼────────────────────┤
│                requests │                 31 │                  0 │
├─────────────────────────┼────────────────────┼────────────────────┤
│            test-scripts │                 46 │                  0 │
├─────────────────────────┼────────────────────┼────────────────────┤
│      prerequest-scripts │                 17 │                  0 │
├─────────────────────────┼────────────────────┼────────────────────┤
│              assertions │                280 │                  0 │
├─────────────────────────┴────────────────────┴────────────────────┤
│ total run duration: 19.8s                                         │
├───────────────────────────────────────────────────────────────────┤
│ total data received: 7.63kB (approx)                              │
├───────────────────────────────────────────────────────────────────┤
│ average response time: 121ms [min: 10ms, max: 969ms, s.d.: 168ms] │
└───────────────────────────────────────────────────────────────────┘

Now we have a java application that uses IRIS as a datasource.

Continious Integration

The whole migration process would not worth without automated tests, luckily the original project already implemented GitHub Actions, using PostgreSQL, and we just need to switch it to IRIS.

InterSystems IRIS Community Edition Docker images with IPM, intersystemsdc supports using environment variables to set credentials, with this ability it makes very easy to use IRIS in tests like in this application. So, we can just replace an existing service with a new one, set username, password and namespace. GitHub Actions will use this docker image to create container to run it alongside when the actual jobs are executed. And the rest of the GitHub Actions workflow remains the same.

    services:
      iris:
        image: intersystemsdc/iris-community
        ports:
          - 5572:1972
        env:
          IRIS_USERNAME: _SYSTEM
          IRIS_PASSWORD: SYS
          IRIS_NAMESPACE: REALWORLD

Now we have an application fully migrated to IRIS. With Kubernetes native nature of Quarkus application, and IRIS Kuberntes support, it's easy to deploy it.

 

The changed code is available on OpenExchange and in GitHub repo. Give it a try.

Discussion (5)2
Log in or sign up to continue