7 Replies Latest reply on Sep 9, 2009 5:05 AM by ataylor

    Remote client JNDI lookup on HQ standalone clustered instanc

      Hi,

      I have 2 HQ clustered standalone instances running on server1 with RMI ports 1099 and 1199 and Netty acceptors at 5445 and 5446 ports. There is a Servlet (Message Sender) deployed to JBoss AS running on server2. JBoss AS doesnt have hornetq installed but has jms-ra.rar.

      Servlet code does JNDI look up on RA connection factory java:/RemoteJmsXA which is configured (as below) to use jms-ra.rar.

      <tx-connection-factory>
       <jndi-name>RemoteJmsXA</jndi-name>
       <xa-transaction/>
       <rar-name>jms-ra.rar</rar-name>
       <connection-definition>org.hornetq.ra.HornetQRAConnectionFactory</connection-definition>
       <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property>
       <config-property name="ConnectorClassName" type="java.lang.String">org.hornetq.integration.transports.netty.NettyConnectorFactory</config-property>
       <config-property name="ConnectionParameters" type="java.lang.String">hornetq.remoting.netty.host=server1;hornetq.remoting.netty.port=5445</config-property>
       <max-pool-size>20</max-pool-size>
       <!--security-domain-and-application>JmsXARealm</security-domain-and-application-->
       </tx-connection-factory>


      I have the following questions.
      1. Is it necessary to specify ConnectorClassName and ConnectionParameters? If yes, how can we configure to load balance messages to 2 instances? Doesn’t it require specifying RMI ports for those 2 HQ instances (If JNDI is used)? How the RemoteJmsXA configuration should be?
      2. How does servlet lookup queue/ExampleQueue which is remote to servlet? – I know it can be done by specifying full JNP path for ex: jnp://server1:1199/queue/ExampleQueue.

      Please clarify.



        • 1. Re: Remote client JNDI lookup on HQ standalone clustered ins
          ataylor

          You will have to specify the connector classname but i would suggest running your servers with discovery rather than specifying the ports directly, take a look at the client load balancing example and run your servers similar to this. Then in your jca config specify the discovery address and/or port and then connections made will be round robined via both servers. see http://hornetq.sourceforge.net/docs/hornetq-2.0.0.BETA5/user-manual/en/html_single/index.html#d0e6806 for the full list of params that can be set, in this case it will be DiscoveryGroupAddress and/or DiscoveryGroupPort.

          Bare in mind that the App server pools these connections so how the load balancing happens is Dependant on how and when the the App server creates them.

          • 2. Re: Remote client JNDI lookup on HQ standalone clustered ins

            Andy, thanks for your reply, that helped me upto some extent. But my remote servlet question remains un-resolved. In your "client-side-load-balancing" example, your POJO is performing JNDI lookup on localhost:1099 where HQ is running. Because of that it is able to locate the queue. In my case I do not have HQ running on JBoss AS where servlet is deployed and it complains "javax.naming.NameNotFoundException: queue not bound". Another point is that I have those 2 HQ instances running on 2 different physical boxes.

            Please clarify.



            • 3. Re: Remote client JNDI lookup on HQ standalone clustered ins
              ataylor

              Ok, with HornetQ standalone we ship the jboss jndi naming service so if you want you could just connect to either HornetQ instance to get a handle on the queue.

              Alternatively you could change your code to use session.createQueue(name), this will use the current connection being used and give you the queue.

              • 4. Re: Remote client JNDI lookup on HQ standalone clustered ins

                Andy, thanks for your reply. As per your suggestion I tried session.createQueue(name), but I get the following error.

                javax.jms.JMSException: There is no queue with name java:/queue/ExampleQueue1


                Please advise me.

                • 5. Re: Remote client JNDI lookup on HQ standalone clustered ins
                  ataylor

                  have you pre configured the queue, it needs to exist. If it does can you supply a full stack trace

                  • 6. Re: Remote client JNDI lookup on HQ standalone clustered ins

                    Yes, Queue is pre-configured. Stacktrace is given below.

                    15:46:20,996 ERROR [STDERR] javax.jms.JMSException: There is no queue with name queue/ExampleQueue
                    15:46:20,996 ERROR [STDERR] at org.hornetq.jms.client.HornetQSession.createQueue(HornetQSession.java:601)
                    15:46:20,997 ERROR [STDERR] at org.hornetq.ra.HornetQRASession.createQueue(HornetQRASession.java:1052)
                    15:46:20,997 ERROR [STDERR] at com.usaa.ar.mqm.servlet.ObjectMessageSender.sendMessageToJBM(ObjectMessageSender.java:179)
                    15:46:20,997 ERROR [STDERR] at com.usaa.ar.mqm.servlet.ObjectMessageSender.doPost(ObjectMessageSender.java:68)
                    15:46:20,997 ERROR [STDERR] at com.usaa.ar.mqm.servlet.ObjectMessageSender.doGet(ObjectMessageSender.java:51)
                    15:46:20,997 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
                    15:46:20,997 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
                    15:46:20,997 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                    15:46:20,997 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                    15:46:20,997 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                    15:46:20,997 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                    15:46:20,998 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                    15:46:20,998 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
                    15:46:20,998 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
                    15:46:20,998 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
                    15:46:20,998 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
                    15:46:20,998 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
                    15:46:20,998 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
                    15:46:20,998 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
                    15:46:20,998 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
                    15:46:20,998 ERROR [STDERR] at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
                    15:46:20,998 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                    15:46:20,998 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
                    15:46:20,998 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
                    15:46:20,999 ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
                    15:46:20,999 ERROR [STDERR] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
                    15:46:20,999 ERROR [STDERR] at java.lang.Thread.run(Thread.java:619)


                    My Servlet is (note that this is not production quality code)

                    protected InitialContext getJbmContext() throws Exception {
                     String provideUrl = "jnp://server2:1199";
                    
                     Properties props = new Properties();
                     props.put("java.naming.factory.initial",
                     "org.jnp.interfaces.NamingContextFactory");
                    
                     props.put(Context.PROVIDER_URL, provideUrl);
                     props.put("java.naming.factory.url.pkgs",
                     "org.jboss.naming:org.jnp.interfaces");
                     return new InitialContext(props);
                     }
                    
                     public void sendMessageToJBM(HttpServletRequest request,
                     HttpServletResponse response) throws ServletException, IOException {
                     String jndiQCFName = "java:/RemoteJmsXA";
                     String jndiQName = "queue/ExampleQueue";
                     Connection connection = null;
                     InitialContext initialContext = null;
                     try {
                     initialContext = getJbmContext();
                     ConnectionFactory cf = (ConnectionFactory) initialContext
                     .lookup(jndiQCFName);
                     connection = cf.createConnection();
                     Session session = connection.createSession(false,
                     Session.AUTO_ACKNOWLEDGE);
                     connection.start();
                    
                     Queue queue = session.createQueue(jndiQName);
                     // (Queue) initialContext.lookup(jndiQName);
                    
                     MessageProducer producer = session.createProducer(queue);
                    
                     SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss,SSS");
                     ObjectMessage message = null;
                     Date date = null;
                     String n = request.getParameter("n");
                     int msgCount = 1;
                     if (n != null) {
                     msgCount = Integer.parseInt(n);
                     }
                     Member member = Member.generateFakeMember();
                     ServletOutputStream out = response.getOutputStream();
                     for (int i = 0; i < msgCount; i++) {
                     date = new Date();
                     message = session.createObjectMessage(member);
                     message.setStringProperty("timeMsgSent", dateFormat
                     .format(date));
                     message.setIntProperty("msgCounter", i);
                     producer.send(message);
                     out.println("Sent message: " + message.getObject());
                     System.out.println("Sent message: " + message.getObject()
                     + " timeMsgSent: " + dateFormat.format(date));
                     }
                     out.flush();
                     } catch (Exception e) {
                     e.printStackTrace();
                     e.printStackTrace(response.getWriter());
                     } finally {
                     if (initialContext != null) {
                     try {
                     initialContext.close();
                     } catch (NamingException e) {
                     e.printStackTrace();
                     }
                     }
                     if (connection != null) {
                     try {
                     connection.close();
                     } catch (JMSException e) {
                     e.printStackTrace();
                     }
                     }
                     }
                     }


                    remote-jms-ds.xml is

                    <?xml version="1.0" encoding="UTF-8"?>
                    <connection-factories>
                     <tx-connection-factory>
                     <jndi-name>RemoteJmsXA</jndi-name>
                     <xa-transaction/>
                     <rar-name>jms-ra.rar</rar-name>
                     <connection-definition>org.hornetq.ra.HornetQRAConnectionFactory</connection-definition>
                     <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property>
                     <max-pool-size>20</max-pool-size>
                     </tx-connection-factory>
                    </connection-factories>


                    Resource Adapter configuration (ra.xml) is given below.

                    <config-property>
                     <description>The transport type</description>
                     <config-property-name>ConnectorClassName</config-property-name>
                     <config-property-type>java.lang.String</config-property-type>
                     <config-property-value>org.hornetq.integration.transports.netty.NettyConnectorFactory</config-property-value>
                     </config-property>
                     <config-property>
                     <description>The transport configuration. These values must be in the form of key=val;key=val;</description>
                     <config-property-name>ConnectionParameters</config-property-name>
                     <config-property-type>java.lang.String</config-property-type>
                     <config-property-value>hornetq.remoting.netty.port=5446;hornetq.remoting.netty.host=server1</config-property-value>
                     </config-property>
                    



                    • 7. Re: Remote client JNDI lookup on HQ standalone clustered ins
                      ataylor

                      sorry for the late reply, so you are confusing the name used to bind the queue to jndi and the name of the queue itself, you should be using 'ExampleQueue' not queue/ExampleQueue.