Jboss client sends message to remote hornetq in Jboss

I have a client run in JBoss (JB_Client), and it needs to send messages to the remote Jboss server (JB_Server) HornetQ . And the remote jboss server (JB_server) needs to send a response message to him with HornetQ . So, the JB_Client MDB listens on the remote HorentQ for responses.

I am using Jboss AS6 for my client and server. This system works fine in a local environment, which is a client and server as in the same JBoss . But now I need to split the client and server into two machines.

here is my test client configuration.

  Properties prop = new Properties(); prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); prop.put(Context.PROVIDER_URL, "jnp://localhost:1099"); ictx = new InitialContext(prop); conFactory = (ConnectionFactory)ictx.lookup("/ConnectionFactory"); qcon = (QueueConnection)conFactory.createConnection(); qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 

The server has no special settings, except for certain queues.

What configuration do I need to do on the server and client side to make this work?

+1
source share
1 answer

I was able to connect to the remote server and get a response from the remote queue. Both my client and the server running on two separate computers, JBossAS [6.1.0.Final "Neo"]. My client is a simple web application (war file)

Client sender queue class.

 private static void prepareContext() { logger.debug("Loading Context"); try { Properties prop = new Properties(); prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); prop.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); prop.put(Context.PROVIDER_URL, "jnp://10.1.4.48:1099"); ictx = new InitialContext(prop); conFactory = (ConnectionFactory)ictx.lookup("/ConnectionFactory"); qcon = (QueueConnection)conFactory.createConnection(); qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); } catch (NamingException er) { logger.fatal("Error ", er); } catch (JMSException er) { logger.fatal("Error ", er); } } public static boolean sendToQueue(String xml, String sendQ) { logger.warn("Sending to queue: " + xml); try { prepareContext(); Queue queue = getQueue(sendQ); if (null == queue) { throw new JMSException("Queue not defined at the end point"); } qcon.start(); QueueSender qsender = qsession.createSender(queue); TextMessage tmsg = qsession.createTextMessage(); tmsg.setText(xml); qsender.send(tmsg); return true; } catch (JMSException er) { logger.fatal("Error ", er); } finally { try { qsession.close(); } catch (Exception er) {/**/} try { qcon.close(); } catch (Exception er) {/**/} } return false; } 

Above is the sender code on the client side.

Now let's see how the recipient of messages is on the client side. I used MDB to listen on the remote server queue.

 public class MessageReceiverBean implements MessageListener { public void onMessage(Message message) { try { if (message instanceof TextMessage) { TextMessage textMsg = (TextMessage) message; logger.info("Inside onMessage of client app MessageReceiverBean : " + textMsg.getText()); } } catch (Exception er) { logger.error("Error while retrieving message from Service provider", er); } } } 

The MDB configuration is located in ejb-jar.xml in the META-INF folder of my war file.

 <message-driven> <ejb-name>User1</ejb-name> <ejb-class>com.my.MessageReceiverBean</ejb-class> <messaging-type>javax.jms.MessageListener</messaging-type> <transaction-type>Container</transaction-type> <activation-config> <activation-config-property> <activation-config-property-name>destinationType</activation-config-property-name> <activation-config-property-value>javax.jms.Queue</activation-config-property-value> </activation-config-property> <activation-config-property> <activation-config-property-name>destination</activation-config-property-name> <activation-config-property-value>queue/User4</activation-config-property-value> </activation-config-property> <activation-config-property> <activation-config-property-name>ConnectorClassName</activation-config-property-name> <activation-config-property-value>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</activation-config-property-value> </activation-config-property> <activation-config-property> <activation-config-property-name>ConnectionParameters</activation-config-property-name> <activation-config-property-value>host=10.1.4.48;port=5445</activation-config-property-value> </activation-config-property> </activation-config> </message-driven> 

To connect to a remote server, the last two activation-configuration properties are additionally added. Thus, client java coding is completed.

Bonus !!!. Above just name it via JNDI in a simple java class. But you may be interested in doing this through EJB CDI injection without using context properties, etc. To do this, you need to change the settings below on the jboss client side.

In the Jboss node client, two settings are changed.

  • hornetq-configuration.xml in the Jboss node client.

<connector name="netty"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class> <param key="host" value="${MY_IP:10.1.4.48}"/> <!-- For MY_IP you can put any word. Doesn't matter. --> <param key="port" value="${hornetq.remoting.netty.port:5445}"/> </connector>

  • ra.xml file in jms-ra.rar (deployment folder) in the Jboss node client. Comment on the settings below.

    <!--<config-property> <description>The transport configuration. These values must be in the form of key=val;key=val;, if multiple connectors are used then each set must be separated by a comma ie host=host1;port=5445,host=host2;port=5446. Each set of params maps to the connector classname specified. </description> <config-property-name>ConnectionParameters</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>server-id=0</config-property-value> </config-property>-->

Ok Jboss settings are complete. Now let's see the EJB bean. We need to enter the specified connection through the annotation.

 @Resource(mappedName = "/ConnectionFactory") private QueueConnectionFactory qConnectionFactory; 

If you checked your hornetq-jms.xml , you can see in <connection-factory name="NettyConnectionFactory"> above mappedName is defined ( <entry name="/ConnectionFactory"/> ). This is the JNDI name you must look in your EJB to find the connectionFactory on the remote HornetQ server. This is if you need to use EJB CDI injection rather than JNDI lookup.

Restart client jboss, after which you can send messages from the client to the server. (No special settings when running jboss)

You can check where it connects if you go to the client jmx console and go to org.hornetq , then click module=JMS,name="NettyConnectionFactory",type=ConnectionFactory . In StaticConnectors you see where this NettyConnector connects.

Now the server side Jboss HornetQ settings.

Edit hornetq-configuration.xml in Server Jboss and change the section.

 <acceptor name="netty"> <factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class> <param key="host" value="${jboss.esb.bind.address:10.1.4.48}"/> <!-- Here I add the server IP and esb. May be you can remove the esb and use "jboss.bind.address:10.1.4.48" --> <param key="port" value="${hornetq.remoting.netty.port:5445}"/> </acceptor> 

So these are the Jboss server settings. And I start the server with the parameter run.bat -b 10.1.4.48.

Hope this helps.

+1
source

Source: https://habr.com/ru/post/899644/


All Articles