8 Replies Latest reply on Jul 15, 2010 5:45 AM by lowecg2004

    Interceptor problem - Unable to get address from message

    lowecg2004

      Hello,

       

      I have an interceptor defined where I want to run some debug logging.  The first message is captured fine, but

      subsequent messages do not have an address so my code ignores them:

       

           public boolean intercept(final Packet packet, final RemotingConnection connection) throws HornetQException {
                try {
                     if (packet instanceof SessionSendMessage) {
                          final SessionSendMessage realPacket = (SessionSendMessage) packet;
                          final Message msg = realPacket.getMessage();
      
                          if (msg instanceof ServerMessage) {
                               // ******* FIRST TIME OKAY, BUT IS NULL ON SUBSEQUENT VISITS
                               final String queue =
                                    (msg.getAddress() == null) ? null : msg.getAddress().toString();
      
                               if (queue != null) {
                                    // Record all messages heading for the command, response
                                    // and session queues.
                                    if (queue.startsWith("jms.queue.lgp") || queue.startsWith("jms.queue.session")) {
                                         logMessage(msg);
                                    }
                               }
                               else {
                                    System.err.println("No queue: " + msg.getPropertyNames() + " - logme = " + msg.getStringProperty("logme") + ", msg = " + msg + " remote address = " + connection.getRemoteAddress());
                               }
                          }
                     }
                } catch (final Exception cause) {
                     System.err.println("[INTERCEPTOR] Caught exception " + cause);
                }
      
                return true;
           }
      

      The messages ARE going through and I'm getting responses from my client app, however I get the "no queue" message because there is no address on the SessionSendMessage object.  Interestingly where "no queue" is printed, the "logme" property prints a value which is assigned to the message when it is sent.

       

      I'm using the same session, queue and producer objects on each send.

       

      Is this expected behaviour and, if so, how can I reliably determine the message destination queue from within the interceptor?

       

      Environment wise I'm sending the message from a Seam component.  The HornetQ server is 2.1.0 Final and embedded within Jboss 5.1.0 - just a dev environment (Win 7, 64bit OS, 32bit 1.6_21 JVM) and no-clustering.  The JMS client is an external process connecting directly to JBoss via JNDI.

       

      Cheers,

       

      Chris.

        • 1. Re: Interceptor problem - Unable to get address from message
          clebert.suconic

          We cache the last destination on the ServerSession for performance reasons.

           

          Say, if you send 100 messages to a single address, only the first message will have the address.

           

           

          If you send 10 messages to Address A, 10 messages to Address B.... you will have:

           

          Message1(A)

          Message2()

          Message3()

          ...

          Message10()

           

          Message11(B)

          Message12()

          Message13()

          ...

          Message20

          • 2. Re: Interceptor problem - Unable to get address from message
            clebert.suconic

            "If you send 10 messages to Address A, 10 messages to Address B.... you will have:"

             

             

            Actually, a little correction.

             

             

            The way it works is.. there is a default address on the Session that will be captured from the first message sent.

             

            The first message to A will have the address set, and all the subsequent wont.

             

            All the messages sent to B will have the address set.

            • 3. Re: Interceptor problem - Unable to get address from message
              lowecg2004

              Hi Clebert,

               

              Thanks for the clarification.  I have 2 clients and with my interceptor installed at the server what I am seeing is this:

               

              C1 sends message to CommandQueue (address ok);

              C2 sends message to ResponseQueue (address ok);

               

              C1 sends another message to CommandQueue using same session (address null);
              C2 sends another message to ResponseQueue using same session (address null);

               

              Where the address is null, from the interceptor's view of the world I cannot tell where the message is going - I can't use the last used queue name.

               

              So... with everything that's been said on this thread so far my next attempt is this:

               

                   private static Map<Object, String> lastQueue = Collections.synchronizedMap(new HashMap<Object, String>());
              
                   public boolean intercept(final Packet packet, final RemotingConnection connection) throws HornetQException {
                        try {
                             if (packet instanceof SessionSendMessage) {
                                  final SessionSendMessage realPacket = (SessionSendMessage) packet;
                                  final Message msg = realPacket.getMessage();
              
                                  if (msg instanceof ServerMessage) {
                                       String queue =
                                            (msg.getAddress() == null) ? null : msg.getAddress().toString();
              
                                       if (queue == null) {
                                            queue = lastQueue.get(connection.getID());
                                       }
                                       else {
                                            lastQueue.put(connection.getID(), queue);
                                       }
              
                                       if (queue == null) {
                                            System.err.println("No queue for connection ID " + connection.getID());
                                       }
                                       else {
                                            // Record all messages heading for the command, response
                                            // and session queues.
                                            if (queue.startsWith("jms.queue.lgp") || queue.startsWith("jms.queue.session")) {
                                                 logMessage(msg);
              
                                                 System.out.println("Scheduled to ID = " + connection.getID());
                                            }
                                            else {
                                                 System.err.println("Ignoring message to '" + queue + "'");
                                            }
                                       }
                                  }
                             }
                        } catch (final Exception cause) {
                             System.err.println("[INTERCEPTOR] Caught exception " + cause);
                        }
              
                        return true;
                   }
              

              I've performed some light testing on this and seems to be working, so I really just wanted to check that this was a sane approach (i.e. using connection.getID() to work out the last queue name)?

              • 4. Re: Interceptor problem - Unable to get address from message
                clebert.suconic

                The connectionID only worked because you have two distinct connections.

                 

                 

                The sessionn is identified by packet.getChannelID(). That would be more accurate for you.

                 

                 

                Also, why don't you use ConcurrentHashMap<Long, String> instead? you wouldn't need to use a synchronized collection. (better throughput)

                • 5. Re: Interceptor problem - Unable to get address from message
                  clebert.suconic

                  Actually, you have to use both.

                   

                   

                  ConnectionID to identify the connection...

                   

                  And the channelID to identify the session within the connection.

                   

                   

                  Also, even if you use different JMS Connections, the client might use the same connectionID for both if they are on the same VM. This is more about phisical connection than JMS Connections.

                  • 6. Re: Interceptor problem - Unable to get address from message
                    lowecg2004

                    Ah yes, I'll use the connection and channel IDs. And good call on the ConcurrentHashMap.

                     

                    Thanks for your help,

                     

                    Chris.

                    • 7. Re: Interceptor problem - Unable to get address from message
                      ataylor

                      if your not too bothered about hampering performance you can add info you like to the message as a property before sending it.

                      • 8. Re: Interceptor problem - Unable to get address from message
                        lowecg2004

                        That's an option I had considered but I discounted it as I'd rather not bake message logging knowledge into my app.  The interceptor approach means that logging is either on or off and catches everything.

                         

                        Cheers,

                         

                        Chris.