JBoss Hornetq – Connecting from external App

In this article I tried to use JBoss Messaging service by an external Spring solution. The idea is to connect a console app (but it may also work as Web Application) that run in external JVM than JBoss one.

JBoss adopts Hornetq as embedded Messaging service and I use it in EAP (Enterprise Application Platform) version 6.4.0.

First bad news; it seems that Hornetq will be substituted in the next EAP version (7)  replaced by ActiveMq. More details here. The reason is explained in this post http://hornetq.blogspot.co.uk/2015/06/hornetq-apache-donation-and-apache.html.

Anyway, I hope they won’t change to much so this article could be helpful in the future. The overall schema is the follow:

jbosshornetq

Firstly, I used Jboss EAP as standalone installation on my local machine. That’s easier to manage for my purpose. Once installed, I run it with “standalone-full” configuration:

C:\jboss-eap-6.4.0\bin>standalone.bat -c standalone-full.xml

In this way I get the Message Service activated. Before logging in the console application, you have to create an user get into the console.
So, create an Management User:

C:\jboss-eap-6.4.0\bin>add-user.bat

What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): a

Enter the details of the new user to add.
Using realm 'ManagementRealm' as discovered from the existing property files.
Username : administrator
The username 'administrator' is easy to guess
Are you sure you want to add user 'administrator' yes/no? yes
Password requirements are listed below. To modify these restrictions edit the add-user.properties configuration file.
 - The password must not be one of the following restricted values {root, admin, administrator}
 - The password must contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)
 - The password must be different from the username
Password :
Re-enter Password :
What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)[  ]: admin
About to add user 'administrator' for realm 'ManagementRealm'
Is this correct yes/no? yes
Added user 'administrator' to file 'C:\jboss-eap-6.4.0\standalone\configuration\mgmt-users.properties'
Added user 'administrator' to file 'C:\jboss-eap-6.4.0\domain\configuration\mgmt-users.properties'
Added user 'administrator' with groups admin to file 'C:\jboss-eap-6.4.0\standalone\configuration\mgmt-groups.properties'
Added user 'administrator' with groups admin to file 'C:\jboss-eap-6.4.0\domain\configuration\mgmt-groups.properties'
Is this new user going to be used for one AS process to connect to another AS process?
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.
yes/no? yes
To represent the user add the following to the server-identities definition <secret value="YWRtaW4yMDE1IQ==" />

Now, with the user administrator is allowed to enter in the Management Console at http://localhost:9990/console/App.html.

The display shows this console.

jbosshornetq1

In the Destination panel (Configuration->Messaging->Destinations) it’s possible to create the queues under the default broker.

jbosshornetq2

The result is also visible in the “standalone_full” configuration file:

<jms-queue name="processQueue">
    <entry name="queue/processQueue"/>
    <entry name="java:/jboss/exported/jms/queue/processQueue"/>
</jms-queue>

Just another one step before taking a look at the Spring code. To access the remote destination, it’s necessary to create an “Application User” for this scope. In order to do it, just repeat the procedure “add-user” choosing “Application User (b)” at the user’s type.

I created one called jmsadmin.

Now, the Spring configuration file:

<beans...>

	<mvc:annotation-driven />

	<!-- JndiTemplate Access -->
	<bean id="jnditemplate" class="org.springframework.jndi.JndiTemplate">
		<property name="environment">
			<props>
				<prop key="java.naming.factory.initial">org.jboss.naming.remote.client.InitialContextFactory
				</prop>
				<prop key="java.naming.factory.url.pkgs">org.jboss.ejb.client.naming</prop>
				<prop key="java.naming.provider.url">remote://127.0.0.1:4447</prop>
			</props>
		</property>
	</bean>

	<!-- Queue Destination -->
	<bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiTemplate" ref="jnditemplate" />
		<property name="jndiName" value="jms/queue/processQueue" />
	</bean>

	<!-- Jms Template -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="credentialsconnectionfactory" />
	</bean>

	<!-- Remote Connection Factory -->
	<bean id="connectionfactory" class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiTemplate" ref="jnditemplate" />
		<property name="jndiName" value="jms/RemoteConnectionFactory" />
	</bean>

	<bean id="credentialsconnectionfactory"
		class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
		<property name="targetConnectionFactory" ref="connectionfactory" />
		<property name="username" value="jmsadmin" />
		<property name="password" value="jmsadmin2015!" />
	</bean>

	<!-- Jms Factory Singleton (used in the code) -->
	<bean class="it.demo.spring.hornetq.app.JMSFactory" id="jmsFactory">
		<property name="processQueue" ref="destination" />
		<property name="jmsTemplate" ref="jmsTemplate" />
	</bean>

	<!-- Listener -->
	<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
		<property name="connectionFactory" ref="credentialsconnectionfactory" />
		<property name="destination" ref="destination" />
		<property name="messageListener" ref="jmsListener" />
	</bean>

	<bean class="it.demo.spring.hornetq.app.JMSListener" id="jmsListener" />

</beans>

The graphic view of the configuration makes easier the file:

jbosshornetq3

Briefly, it’s enough to configure the “Connection Factory” and the “Destination“. The connection is made through the “RemoteConnectionFactory” and the remote connection port is 4447.

The idea is to call the Jms Service from an external Jvm and the App is not deployed in the local Jboss.

It’s also be configured the credential for connecting at the remote destination named processQueue.

The class file are easier and made to the purpose of produce and consume Jms Messages. The producer class is:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
public class JMSProducerSpring {

	private Logger logger = Logger.getLogger(JMSProducerSpring.class);

	@Autowired
	private JMSFactory jmsFactory;

	@Test
	public void sendMessage() throws IOException, JMSException {
		jmsFactory.getJmsTemplate().send(jmsFactory.getTicketQueue(),
				new MessageCreator() {
					@Override
					public Message createMessage(Session session)
							throws JMSException {
						return session.createTextMessage("Spring Process");
					}
				});
		logger.info("Message sent to processQueue");
	}

	public JMSFactory getJmsFactory() {
		return jmsFactory;
	}

	public void setJmsFactory(JMSFactory jmsFactory) {
		this.jmsFactory = jmsFactory;
	}
}

The Consumer/Listener class is

public class JMSListener implements javax.jms.MessageListener{

	private Logger logger = Logger.getLogger(JMSListener.class);

	@Override
	public void onMessage(Message message) {
		TextMessage text = (TextMessage)message;
		try {
			logger.info("Received message "+text.getText());
		} catch (JMSException e) {
			logger.error("Error Received message ", e);
		}
	}
}

Running JBoss EAP is now possible to connect to the remote Jms Service; it’s also possible do it inside Eclipse, installing JBoss Tools available in Eclipse Marketplace.
Once JBoss is running, launch the Junit Test, immediately a message is produced and send to the Queue. Have a look at EAP interface under Runtime->Subsystems->JMS Destinations it’s illustrated the Message Count (number of messages in the Queue) and the Message Added (number of messages already delivered).

jbosshornet4

As soon as the Message reaches it a JmsListener gets it from the Queue:

jbosshornet5

That’s all.

I made this example by taking codes from different examples that I’ve found.
I apologize with everyone that could recognize part of their code in this example without the reference to them. Sincerely, I don’t remember the sources of all of them.

Reference: http://itsvenkis.blogspot.it/2014/02/hornetq-spring-integration-tutorial.html

Advertisements

One thought on “JBoss Hornetq – Connecting from external App

  1. Pingback: JBoss Hornetq – Connecting from external App | Dinesh Ram Kali.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s