Deploying High-Availability Messaging with WildFly and AMQ 7 on OpenShift
- Prerequisites
- Log Into the OpenShift Cluster
- Install and deploy AMQ 7 using an operator
- Build WildFly with a messaging application image using the WildFly Maven Plugin
- Push WildFly image to the OpenShift registry
- Install the WildFly Operator
- Deploy the application image using the WildFly Operator
- Test the Application
- What’s Next?
- References
In this guide, you will learn how to configure a WildFly server connected to a remote AMQ 7 cluster on OpenShift using operators.
Prerequisites
To complete this guide, you need:
-
Roughly 20 minutes
-
JDK 17+ installed with
JAVA_HOME
configured appropriately -
Apache Maven 3.9+
-
Access to an OpenShift cluster (consider using the 'Self-managed' variant for a local development environment, available for free at Red Hat OpenShift)
-
OpenShift CLI tool
Log Into the OpenShift Cluster
Before we can deploy our application, we need to log in to an OpenShift cluster. You can log in via the OpenShift CLI:
oc login -u myUserName
Alternatively, you can log in using an API token:
oc login --token=myToken --server=myServerUrl
You can request the token via the Copy Login Command
link in the OpenShift web console.
If you don’t already have a project created, you can create one using:
oc new-project myProjectName
Install and deploy AMQ 7 using an operator
To install the AMQ 7 Operator, follow the instructions in the Red Hat documentation: Installing the Operator using OperatorHub
Next, create a file named broker.yaml
with the following content to deploy the AMQ 7 cluster:
apiVersion: broker.amq.io/v1beta1
kind: ActiveMQArtemis
metadata:
name: amq-broker
application: amq-broker-app
spec:
acceptors:
- name: acceptor
protocols: core,amqp
port: 61616
sslEnabled: false
enabledProtocols: TLSv1,TLSv1.1,TLSv1.2
needClientAuth: true
wantClientAuth: true
verifyHost: true
sslProvider: JDK
sniHost: localhost
expose: true
anycastPrefix: jms.queue.
multicastPrefix: /topic/
console:
expose: true
deploymentPlan:
journalType: nio
messageMigration: true
persistenceEnabled: true
requireLogin: false
size: 2
storage:
size: "1Gi"
upgrades:
enabled: false
minor: false
This Custom Resource (CR) file configures an AMQ 7 cluster with two brokers deployed as a StatefulSet. This setup ensures high availability because, in the event of a pod failure, the StatefulSet will automatically restart the failed pod. However, to maintain data integrity, Persistent Volumes must be configured to store the messaging journal. Without them, messages will be lost during restarts.
Additionally, the messageMigration: true
setting enables the graceful scaling down of AMQ 7 pods. This ensures that messages
from the scaled-down node are migrated to another node in the cluster, preventing data loss.
Run following command to deploy AMQ 7 on OpenShift:
oc create -f broker.yaml
Check that AMQ 7 brokers are in Running
state by checking running pods:
$ oc get pods
NAME READY STATUS RESTARTS AGE
amq-broker-ss-0 1/1 Running 0 35m
amq-broker-ss-1 1/1 Running 0 36m
...
Build WildFly with a messaging application image using the WildFly Maven Plugin
We’re going to use the WildFly Quickstart: remote-helloworld-mdb
to demonstrate how to build a trimmed WildFly server with a deployed messaging application. This quickstart leverages the WildFly Maven plugin
to create a trimmed WildFly server and deploy the remote-helloworld-mdb.war
application. It then produces a new container image based on
the WildFly Runtime Image, incorporating the application.
This quickstart includes a HelloWorldMDBServletClient
servlet, which sends messages to the HELLOWORLDMDBQueue
queue,
and a HelloWorldQueueMDB
message-driven bean (MDB) that consumes messages from this queue.
To build the remote-helloworld-mdb quickstart, execute the following commands:
git clone git@github.com:wildfly/quickstart.git
cd quickstart/remote-helloworld-mdb
mvn clean package wildfly:image -Popenshift
The openshift
profile is used to provide additional configuration for the WildFly server to work correctly on the Openshift
environment. The Maven goal wildfly:image
instructs the WildFly Maven Plugin to build a container image.
You can verify the newly built image by running:
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/remote-helloworld-mdb latest cf9a174a5311 14 minutes ago 621 MB
...
Push WildFly image to the OpenShift registry
We need to expose the created image in the registry, so it can later be referenced from the Custom Resource for the WildFly Operator. We can utilize the integrated OpenShift registry and push the image into it through the ImageStream. First create a new ImageStream in your namespace:
oc create imagestream remote-helloworld-mdb
Now push your image into the ImageStream:
export REGISTRY="$(oc get routes -n openshift-image-registry default-route -o=jsonpath='{.spec.host}')"
podman login --tls-verify=false -u admin -p $(oc whoami -t) $REGISTRY
podman tag localhost/remote-helloworld-mdb $REGISTRY/$(oc config view --minify -o jsonpath='{..namespace}')/remote-helloworld-mdb
podman push --tls-verify=false $REGISTRY/$(oc config view --minify -o jsonpath='{..namespace}')/remote-helloworld-mdb
You can verify that the image was successfully pushed to the ImageStream by running:
$ oc get imagestream remote-helloworld-mdb
NAME IMAGE REPOSITORY TAGS UPDATED
remote-helloworld-mdb default-route-openshift-image-registry.apps-crc.testing/mnovak/remote-helloworld-mdb latest 17 minutes ago
Install the WildFly Operator
First we need to install the WildFly Operator to OpenShift cluster. Since the WildFly Operator is not included in the OpenShift
OperatorHub by default, it must be added manually. Create the file community-catalog-source.yaml
with content:
apiVersion: operators.coreos.com/v1alpha1
kind: CatalogSource
metadata:
name: operatorhubio-catalog
namespace: openshift-marketplace
spec:
displayName: Community Operators
grpcPodConfig:
securityContextConfig: restricted
image: quay.io/operatorhubio/catalog:latest
publisher: OperatorHub.io
sourceType: grpc
updateStrategy:
registryPoll:
interval: 60m
Execute the following command to add the community catalog to the OperatorHub:
oc apply -f community-catalog-source.yaml
You can now install the WildFly Operator using the wildfly-operator.yml
file:
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
name: wildfly
spec:
channel: alpha
installPlanApproval: Automatic
name: wildfly
source: operatorhubio-catalog
sourceNamespace: openshift-marketplace
and install it by:
oc apply -f wildfly-operator.yml
You can now verify the installed operator in your namespace by inspecting the pods:
$ oc get pods
NAME READY STATUS RESTARTS AGE
wildfly-operator-d975cb47c-q9vgp 1/1 Running 0 4m17s
...
Deploy the application image using the WildFly Operator
Now, we will configure the WildFly Operator to deploy the WildFly image with the messaging application. To achieve this, we will
create a new file, wildfly-remote-messaging.yaml
. In this file, the location of the AMQ 7 broker must be specified by setting
the environment variables JBOSS_MESSAGING_CONNECTOR_HOST
and JBOSS_MESSAGING_CONNECTOR_PORT
:
apiVersion: wildfly.org/v1alpha1
kind: WildFlyServer
metadata:
name: wildfly-remote-activemq
spec:
applicationImage: "remote-helloworld-mdb:latest"
replicas: 1
env:
- name: JBOSS_MESSAGING_CONNECTOR_HOST
value: amq-broker-acceptor-0-svc
- name: JBOSS_MESSAGING_CONNECTOR_PORT
value: '61616'
and deploy it by:
oc apply -f wildfly-remote-messaging.yaml
You can now verify the deployed wildfly in your namespace by inspecting the pods:
$ oc get pods
NAME READY STATUS RESTARTS AGE
wildfly-remote-activemq-0 1/1 Running 0 63s
...
Test the Application
We’re going to test the application by sending 5 messages to the HELLOWORLDMDBQueue
to the AMQ 7 broker.
Then we will check that the MDB consumed those messages from the queue:
curl http://$(oc get route wildfly-remote-activemq-route --template='{{ .spec.host }}')/remote-helloworld-mdb/HelloWorldMDBServletClient
This command invokes the HelloWorldMDBServletClient
servlet deployed to WildFly to send messages. Check the server log
to ensure they contain entries similar to the following:
$ oc logs wildfly-remote-activemq-0
...
13:39:27,846 INFO [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-10 (ActiveMQ-client-global-threads)) Received Message from queue: This is message 1
13:39:27,860 INFO [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-12 (ActiveMQ-client-global-threads)) Received Message from queue: This is message 3
13:39:27,863 INFO [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-11 (ActiveMQ-client-global-threads)) Received Message from queue: This is message 2
13:39:27,874 INFO [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-10 (ActiveMQ-client-global-threads)) Received Message from queue: This is message 4
13:39:27,878 INFO [class org.jboss.as.quickstarts.mdb.HelloWorldQueueMDB] (Thread-12 (ActiveMQ-client-global-threads)) Received Message from queue: This is message 5
The presence of these log entries in the server log confirms that the MDB successfully consumed messages from the HELLOWORLDMDBQueue
from one of the clustered remote AMQ 7 broker.
What’s Next?
Now that you have deployed WildFly with a messaging application connected to AMQ 7, explore the following resources to enhance your understanding and further extend your deployment:
-
Deploying AMQ Broker on OpenShift: Dive deeper into deploying and managing AMQ Broker on OpenShift with detailed guides and best practices. Deploying AMQ Broker on OpenShift
-
WildFly Operator Repository: Learn more about the WildFly Operator, its features, and advanced configuration options directly from the official GitHub repository. WildFly Operator GitHub
-
WildFly Maven Plugin Documentation: Explore the WildFly Maven Plugin for automating deployment, configuration, and management of WildFly applications during your build process. WildFly Maven Plugin Documentation
These resources provide valuable insights and tools to optimize your WildFly and AMQ deployments, automate workflows, and build robust applications on OpenShift.