The Modulith Runtime
A modulith runtime is a platform that implements the component model (developing components that are loosely coupled and reusable).
Introduction
In the past few weeks, I have been working with Red Hat Fuse, which is supported mainly by the Apache Karaf OSGi runtime and several Open-Source projects, such as Apache Camel for integration, Apache CXF for web services, Hawtio for management, and so on.
For an experienced Java software engineer who developed web services back in the day without using frameworks like Spring, Struts, or Quarkus, keywords like OSGi, CXF, and Hawtio sound familiar. For those, like myself, who do not know what they mean, please pay attention to the following paragraphs.
OSGi Runtimes
OSGi is built around a service-oriented architecture. Applications or components, come in the form of bundles for deployment, can be remotely installed, started, stopped, updated, and uninstalled without requiring a reboot. - Wikipedia
In short, OSGi is a platform for Java applications that implements the component model (developing components that are loosely coupled and reusable) and follows the service-oriented architecture (developing applications using multiple services connected through a network instead of developing a monolith application). This topic will be discussed in a dedicated section.
Apache Camel
Apache Camel is an integration framework with hundreds of components that can be used to access databases, messaging queues, streams, and APIs. It ships components to manage the major cloud services and much more.
I have been building integrations with Camel for moving data from databases to data lakes on Microsoft Azure, performing Extract Transform and Load operations, creating REST APIs, and running batch and cron jobs.
Camel is a Java framework and they have documentation for integrating it with Quarkus, Spring, and Apache Karaf.
Apache CXF
CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI. - Apache CXF
JAX-WS is an application programming interface (API) to build web services, precisely SOAP services. JAX-RS is also an API to create RESTful web services. Both APIs can be found under Jakarta. For the backend Java developers, you might use JAX-RS annotations already. The most common ones are @Get @Post @Put @Delete @Produces @Consumes @PathParam @QueryParam.
Hawtio
Hawtio is a console built in Java that is extendable through plugins. Inside Red Hat, as far as I know, this console is used in Red Hat Fuse, Red Hat AMQ Broker. However, according to Hawtio documentation, it is used by Apache Camel, Quarkus, Spring Boot, and JMX. As this allows creating custom plugins, I will be playing with it in the following weeks.
Apache Karaf
This section describes the architecture, key concepts, and the most important key features (imho). After reviewing all of these architectural topics, I will explain how to administrate a standalone Karaf by deploying a small application generated using the archetype.
Architecture
As aforementioned, Apache Karaf is an OSGi environment. It is supported by Apache Felix OSGi and on top of that bundles more open-source technologies to enrich the OSGi environment such as Apache Camel, Logging, JMX, Deployers, different ways of provisioning, web and shell consoles, and remote access.
Key Concepts
Bundle: A bundle is a JAR file. It represents a Java-based application.
Feature: In Apache Karaf, a feature describes an application provisioning (name, version, set of bundles, configuration files, and dependency features)
Deployer: Apache Karaf supports hot deployment by dropping files inside the deploy folder. Apache Karaf has deployer components that are responsible for watching that folder and whenever there is a new file, the deployer will register the features XML as a features repository and install features that have the auto attribute. For instance, there are Camel, Blueprint, War, and Spring deployers.
Blueprint: Blueprint is a similar way to Spring DM for defining services.
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="bookingService" class="org.apache.karaf.examples.blueprint.provider.internal.BookingServiceImpl"/>
<service ref="bookingService" interface="org.apache.karaf.examples.blueprint.common.BookingService"/>
</blueprint>
Key Features
Hot Deploy: Automatic deployment of new applications by just dropping them inside the
deploy
folder. It does not require any restart to deploy new applications and the uptime of the deployed applications will not be affected. The deployers are the main components of this feature, they are responsible to detect and deploy new applications that are dropped inside the folder. If you drop a camel application (xml file), it will require the camel deployer.Dynamic Configuration: All configurations are located in the
etc
folder. Whenever they are updated, the runtime will load them automatically without any restart.Logging: All application logs are centralized and accessible through the console and saver under the
logs
folder.Shell Console: Apache Karaf can be managed through a shell console which is provided by the binary
bin/karaf
.Web Console: Apart from the shell console, it is possible to manage the runtime using Hawtio.
Demo
Generate a blueprint using the archetype
mvn archetype:generate \
-DarchetypeGroupId=org.apache.karaf.archetypes \
-DarchetypeArtifactId=karaf-blueprint-archetype \
-DarchetypeVersion=4.0.0 \
-DgroupId=com.mycompany \
-DartifactId=com.mycompany.blueprint \
-Dversion=1.0-SNAPSHOT \
-Dpackage=com.mycompany.blueprint
Review the blueprint
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">
<bean id="serviceBean" class="com.mycompany.blueprint.MyServiceImpl"/>
<service ref="serviceBean" interface="com.mycompany.blueprint.MyService"/>
</blueprint>
Compile the Java application using Maven
$ mvn clean install
(optional) Install the application using OBR
I noticed that my Karaf was not using my local Maven repository. So, when I installed an application, Karaf couldn’t find it because it was using its own Maven repository.
Adding a Maven repository is quite easy, the following command adds a repo from any repository into Karaf. Please note that for remote repositories, the Maven settings file must be configured accordingly.
For more details about Provisioning, please read the docs here.
$ feature:repo-add mvn:group-id/artifact-id/version/xml/features
$ feature:install group-id/artifact-id/version/feature/xml
As I mentioned, I tried to run such command and Karaf couldn’t resolve the artifact. If you notice, the local repository is /fuse-karaf/data/repository
and not the usual .m2
folder. I spent a couple hours searching for a solution to this problem and found out another way to deploy blueprints using OSGi Bundle Repository (OBR).
Install OBR
Add your local Maven repository
Deploy your bundle
Review your bundle
Install the application using hot-deploy (jar): Drop your jar file inside the deploy folder and check out the Karaf logs using
log:display
.