Install ActiveMQ
First, you need to download ActiveMQ from here. After downloading the package, archive the package.Fig.01 download activemq |
$tar -xvf apache-activemq-5.15.11-bin.tar.gz
$mv apache-activemq-5.15.11 activemq
$cp -R activemq /opt/
$mv apache-activemq-5.15.11 activemq
$cp -R activemq /opt/
Generate SSL keystore and truststore
You can use java keytool to create keystore and truststore for both broker and client. The concept is the same as you create keystore and truststore for HTTPS. You can refer in previous tutorial.![]() |
Fig.02 Creating Keystore and truststore concept. |
## Create a keystore for the broker SERVER
keytool -genkey -alias broker -keyalg RSA -keysize 2048 -validity 35600 -storepass password -keypass password -dname "CN=wildfly.itstikk.pro, o=itstikk, c=LA" -keystore broker.keystore
## Export broker key certificate
keytool -export -alias broker -keystore broker.keystore -storepass password -file broker.cert
## Create a keystore/certificat for the client
keytool -genkey -alias client -keyalg RSA -keysize 2048 -validity 35600 -storepass password -keypass password -dname "CN=wildfly.itstikk.pro, o=itstikk, c=LA" -keystore client.keystore
## create truststore for the client, and import the broker's certificate
keytool -import -alias broker -keystore client.truststore -file broker.cert -storepass password -noprompt
## export client certificate
keytool -export -alias client -keystore client.keystore -storepass password -file client.cert
## import client certificate to broker's truststore
keytool -import -alias client -file client.cert -keystore broker.truststore -storepass password -noprompt
After execute this script you should get below keystore and truststore set as below.keytool -genkey -alias broker -keyalg RSA -keysize 2048 -validity 35600 -storepass password -keypass password -dname "CN=wildfly.itstikk.pro, o=itstikk, c=LA" -keystore broker.keystore
## Export broker key certificate
keytool -export -alias broker -keystore broker.keystore -storepass password -file broker.cert
## Create a keystore/certificat for the client
keytool -genkey -alias client -keyalg RSA -keysize 2048 -validity 35600 -storepass password -keypass password -dname "CN=wildfly.itstikk.pro, o=itstikk, c=LA" -keystore client.keystore
## create truststore for the client, and import the broker's certificate
keytool -import -alias broker -keystore client.truststore -file broker.cert -storepass password -noprompt
## export client certificate
keytool -export -alias client -keystore client.keystore -storepass password -file client.cert
## import client certificate to broker's truststore
keytool -import -alias client -file client.cert -keystore broker.truststore -storepass password -noprompt
-rw-rw-r-- 1 wildfly wildfly 799 Mar 29 11:57 broker.cert
-rw-rw-r-- 1 wildfly wildfly 2150 Mar 29 11:56 broker.keystore
-rw-rw-r-- 1 wildfly wildfly 862 Mar 29 11:58 broker.truststore
-rw-rw-r-- 1 wildfly wildfly 799 Mar 29 11:57 client.cert
-rw-rw-r-- 1 wildfly wildfly 2150 Mar 29 11:57 client.keystore
-rw-rw-r-- 1 wildfly wildfly 862 Mar 29 11:57 client.truststore
Maintain broker.keystore and broker truststore in the broker. And maintain client.keystore and client.truststore at the client side.-rw-rw-r-- 1 wildfly wildfly 2150 Mar 29 11:56 broker.keystore
-rw-rw-r-- 1 wildfly wildfly 862 Mar 29 11:58 broker.truststore
-rw-rw-r-- 1 wildfly wildfly 799 Mar 29 11:57 client.cert
-rw-rw-r-- 1 wildfly wildfly 2150 Mar 29 11:57 client.keystore
-rw-rw-r-- 1 wildfly wildfly 862 Mar 29 11:57 client.truststore
Setup SSL for ActiveMQ
To enable SSL for ActiveMQ, you need to edit activemq.xml as below
$vim /opt/activemq/conf/activemq.xml
add below to your activemq.xml
<!--
The managementContext is used to configure how ActiveMQ is exposed in
JMX. By default, ActiveMQ uses the MBean server that is started by
the JVM. For more information, see:
http://activemq.apache.org/jmx.html
-->
<managementContext>
<managementContext createConnector="false"/>
</managementContext>
<!-- SSL Connection -->
<sslContext>
<sslContext keyStore="file:${ACTIVEMQ_KEYS}/broker.keystore"
keyStorePassword="password" trustStore="file:${ACTIVEMQ_KEYS}/broker.truststore"
trustStorePassword="password"/>
</sslContext>
And add below line to enable SSLThe managementContext is used to configure how ActiveMQ is exposed in
JMX. By default, ActiveMQ uses the MBean server that is started by
the JVM. For more information, see:
http://activemq.apache.org/jmx.html
-->
<managementContext>
<managementContext createConnector="false"/>
</managementContext>
<!-- SSL Connection -->
<sslContext>
<sslContext keyStore="file:${ACTIVEMQ_KEYS}/broker.keystore"
keyStorePassword="password" trustStore="file:${ACTIVEMQ_KEYS}/broker.truststore"
trustStorePassword="password"/>
</sslContext>
<!--
The transport connectors expose ActiveMQ over a given protocol to
clients and other brokers. For more information, see:
http://activemq.apache.org/configuring-transports.html
-->
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ssl" uri="ssl://0.0.0.0:61714?transport.enabledProtocols=TLSv1.2"/>
<!--
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
-->
</transportConnectors>
now you can start activemqThe transport connectors expose ActiveMQ over a given protocol to
clients and other brokers. For more information, see:
http://activemq.apache.org/configuring-transports.html
-->
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ssl" uri="ssl://0.0.0.0:61714?transport.enabledProtocols=TLSv1.2"/>
<!--
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
-->
</transportConnectors>
$cd /opt/activemq/bin/linux-x86-64/
$ls -la
total 160
drwxrwxr-x 2 wildfly wildfly 4096 Mar 29 18:06 .
drwxrwxr-x 5 wildfly wildfly 4096 Feb 25 11:45 ..
-rwxr-xr-x 1 wildfly wildfly 15455 Nov 20 17:25 activemq
-rwxr-xr-x 1 wildfly wildfly 15248 Nov 20 16:34 libwrapper.so
-rwxr-xr-x 1 wildfly wildfly 111027 Nov 20 16:34 wrapper
-rw-r--r-- 1 wildfly wildfly 6033 Nov 20 17:25 wrapper.conf
$./activemq start
Now, check whether ActiveMQ run properly below$ls -la
total 160
drwxrwxr-x 2 wildfly wildfly 4096 Mar 29 18:06 .
drwxrwxr-x 5 wildfly wildfly 4096 Feb 25 11:45 ..
-rwxr-xr-x 1 wildfly wildfly 15455 Nov 20 17:25 activemq
-rwxr-xr-x 1 wildfly wildfly 15248 Nov 20 16:34 libwrapper.so
-rwxr-xr-x 1 wildfly wildfly 111027 Nov 20 16:34 wrapper
-rw-r--r-- 1 wildfly wildfly 6033 Nov 20 17:25 wrapper.conf
$./activemq start
[wildfly@wildfly linux-x86-64]$ netstat -ntl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp6 0 0 :::61714 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 :::38152 :::* LISTEN
tcp6 0 0 :::111 :::* LISTEN
tcp6 0 0 :::61616 :::* LISTEN
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp6 0 0 :::61714 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 :::38152 :::* LISTEN
tcp6 0 0 :::111 :::* LISTEN
tcp6 0 0 :::61616 :::* LISTEN
Configure Wildfly 10 and Set Up SSL for ActiveMQ connection
Now, we need to integrate Wildfly Application server with ActiveMQ. In order to that, we need to download resource adapter here. After finish download, copy activemq-rar-5.11.1.rar to Wildfly's deploy folder.
$cp activemq-rar-5.15.12.rar $JBOSS_HOME/standalone/deployments/
Next is to edit standalone-full.xml file.
<subsystem xmlns="urn:jboss:domain:resource-adapters:4.0">
<resource-adapters><resource-adapter id="activemq">
<archive>
activemq-rar-5.15.12.rar
</archive>
<transaction-support>XATransaction</transaction-support>
<config-property name="ServerUrl">
ssl://wildfly.itstikk.pro:61714
</config-property>
<config-property name="UserName">
jms-user
</config-property>
<config-property name="UseInboundSession">
false
</config-property>
<config-property name="Password">
Qf48d8uv12!@
</config-property>
<config-property name="TrustStore">
/opt/keys/activemq/client.truststore
</config-property>
<config-property name="TrustStorePassword">
password
</config-property>
<config-property name="KeyStore">
/opt/keys/activemq/client.keystore
</config-property>
<config-property name="KeyStorePassword">
password
</config-property>
<connection-definitions>
<connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/ConnectionFactory0" enabled="true" pool-name="ConnectionFactory">
<xa-pool>
<min-pool-size>1</min-pool-size>
<max-pool-size>20</max-pool-size>
<prefill>false</prefill>
<is-same-rm-override>false</is-same-rm-override>
</xa-pool>
<config-property name="TrustStore">
/opt/keys/activemq/client.truststore
</config-property>
<config-property name="TrustStorePassword">
password
</config-property>
<config-property name="KeyStore">
/opt/keys/activemq/client.keystore
</config-property>
<config-property name="KeyStorePassword">
password
</config-property>
</connection-definition>
</connection-definitions>
<admin-objects>
<admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:jboss/activemq/queue/TestQueue" use-java-context="true" pool-name="testQueue">
<config-property name="PhysicalName">
activemq/queue/TestQueue
</config-property>
</admin-object>
</admin-objects>
</resource-adapter>
</resource-adapters>
</subsystem>
<subsystem xmlns="urn:jboss:domain:ejb3:4.0">
<session-bean>
<stateless>
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
</stateless>
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
<singleton default-access-timeout="5000"/>
</session-bean>
<mdb>
<resource-adapter-ref resource-adapter-name="activemq"/>
<bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
</mdb>
<pools>
<bean-instance-pools>
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
</bean-instance-pools>
</pools>
<caches>
<cache name="simple"/>
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
</caches>
<passivation-stores>
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
</passivation-stores>
<async thread-pool-name="default"/>
<timer-service thread-pool-name="default" default-data-store="default-file-store">
<data-stores>
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
</data-stores>
</timer-service>
<remote connector-ref="http-remoting-connector" thread-pool-name="default"/>
<thread-pools>
<thread-pool name="default">
<max-threads count="10"/>
<keepalive-time time="100" unit="milliseconds"/>
</thread-pool>
</thread-pools>
<iiop enable-by-default="false" use-qualified-name="false"/>
<default-security-domain value="other"/>
<default-missing-method-permissions-deny-access value="true"/>
<log-system-exceptions value="true"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:io:1.1">
<worker name="default"/>
<buffer-pool name="default"/>
</subsystem>
<session-bean>
<stateless>
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
</stateless>
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
<singleton default-access-timeout="5000"/>
</session-bean>
<mdb>
<resource-adapter-ref resource-adapter-name="activemq"/>
<bean-instance-pool-ref pool-name="mdb-strict-max-pool"/>
</mdb>
<pools>
<bean-instance-pools>
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
</bean-instance-pools>
</pools>
<caches>
<cache name="simple"/>
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
</caches>
<passivation-stores>
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
</passivation-stores>
<async thread-pool-name="default"/>
<timer-service thread-pool-name="default" default-data-store="default-file-store">
<data-stores>
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
</data-stores>
</timer-service>
<remote connector-ref="http-remoting-connector" thread-pool-name="default"/>
<thread-pools>
<thread-pool name="default">
<max-threads count="10"/>
<keepalive-time time="100" unit="milliseconds"/>
</thread-pool>
</thread-pools>
<iiop enable-by-default="false" use-qualified-name="false"/>
<default-security-domain value="other"/>
<default-missing-method-permissions-deny-access value="true"/>
<log-system-exceptions value="true"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:io:1.1">
<worker name="default"/>
<buffer-pool name="default"/>
</subsystem>
Now start Wildfly.
$cd $JBOSS_HOME/bin
$bash standalone.sh -c=standalone-full.xml
$bash standalone.sh -c=standalone-full.xml
After start Wildfly, if you configuration is working you could see the queue is created in the message broker.
Fig.03 check the queue is created |
Create Message Producer and Message Consumer to test the set up
First you need to create message producer by creating JAVA SE project and create Java Class.
package pro.itstikk.jms.app;
import java.io.File;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQSslConnectionFactory;
public class Main01 {
private static final String CLIENT_TS_FILE="E:\\workplace\\keys\\activemq\\keys\\client.truststore";
private static final String CLIENT_KS_FILE="E:\\workplace\\keys\\activemq\\keys\\client.keystore";
private static String url = "ssl://wildfly.itstikk.pro:61714";
private static String subject = "activemq/queue/TestQueue"; // Queue Name.You can create any/many queue names as per your requirement.
public static void main(String[] args) throws Exception {
// Getting JMS connection from the server and starting it
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName("jms-user");
connectionFactory.setPassword("Qf48d8uv12!@");
connectionFactory.setTrustStore(new File(CLIENT_TS_FILE).toURI().toString());
connectionFactory.setTrustStorePassword("password");
connectionFactory.setKeyStore(new File(CLIENT_KS_FILE).toURI().toString());
connectionFactory.setKeyStorePassword("password");
Connection connection = connectionFactory.createConnection();
connection.start();
//Creating a non transactional session to send/receive JMS message.
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
//Destination represents here our queue 'JCG_QUEUE' on the JMS server.
//The queue will be created automatically on the server.
Destination destination = session.createQueue(subject);
// MessageProducer is used for sending messages to the queue.
MessageProducer producer = session.createProducer(destination);
// We will send a small text message saying 'Hello World!!!'
TextMessage message = session
.createTextMessage("Hello !!! Welcome to the world of ActiveMQ.");
// Here we are sending our message!
for(int i=0;i<10000;i++) {
System.out.println("send message to the queue !!!!!!!!!!!");
producer.send(message);
}
System.out.println("JCG printing@@ '" + message.getText() + "'");
connection.close();
}
}
package pro.itstikk.wildfly;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
/**
* Message-Driven Bean implementation class for: ActiveMQMDB
*/
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "activemq/queue/TestQueue") })
public class ActiveMQMDB implements MessageListener {
/**
* Default constructor.
*/
public ActiveMQMDB() {
super();
}
/**
* @see MessageListener#onMessage(Message)
*/
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
System.out.println(">>>> Got Message "
+ ((TextMessage) message).getText());
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
No comments:
Post a Comment