4 Replies Latest reply on Dec 20, 2005 11:22 AM by genman

    Destination bridge

    gquintana

      Hello,

      Is it possible to create "destination bridges" in JBoss MQ: every JMS message sent to the bridge is forwarded to another Queue or Topic on another JMS server as soon as it is available.

      Other J2EE servers already do this



        • 1. Re: Destination bridge
          genman


          No. But I imagine it would be fairly simple to code using an MDB.

          • 2. Re: Destination bridge
            gquintana

            Fairly easy?

            • Handle all message types: Text, Map, Object, Bytes...
            • Handle header properties
            • Handle sending options: priority, time to live, delivery mode


              I guess I am not the only one who needs such a behaviour. JBoss can not do this in generic way?


            • 3. Re: Destination bridge
              gquintana

              I followed your advice and wrote a MDB:

               public void onMessage(Message sourceMessage) {
               Connection connection = null;
               try {
               connection = getTargetConnectionFactory().createConnection();
               Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
              
               // Body
               Message targetMessage;
               if (sourceMessage instanceof TextMessage) {
               // Text
               TextMessage sourceTextMessage = (TextMessage) sourceMessage;
               targetMessage = session.createTextMessage(sourceTextMessage.getText());
               } else if (sourceMessage instanceof BytesMessage) {
               // Bytes
               BytesMessage sourceBytesMessage = (BytesMessage) sourceMessage;
               BytesMessage targetBytesMessage = session.createBytesMessage();
               byte[] bytes = new byte[getByteBufferSize()];
               int byteCount;
               while((byteCount=sourceBytesMessage.readBytes(bytes))>0) {
               targetBytesMessage.writeBytes(bytes, 0, byteCount);
               }
               targetMessage = targetBytesMessage;
               } else if (sourceMessage instanceof MapMessage) {
               // Map
               MapMessage sourceMapMessage = (MapMessage) sourceMessage;
               MapMessage targetMapMessage = session.createMapMessage();
               Enumeration mapNameEnum = sourceMapMessage.getMapNames();
               while (mapNameEnum.hasMoreElements()) {
               String mapName = (String) mapNameEnum.nextElement();
               targetMapMessage.setObjectProperty(mapName, sourceMapMessage.getObject(mapName));
               }
               targetMessage = targetMapMessage;
               } else if (sourceMessage instanceof ObjectMessage) {
               // Object
               ObjectMessage sourceObjectMessage = (ObjectMessage) sourceMessage;
               targetMessage = session.createObjectMessage(sourceObjectMessage.getObject());
               } else if (sourceMessage instanceof StreamMessage) {
               // Stream
               StreamMessage sourceStreamMessage = (StreamMessage) sourceMessage;
               StreamMessage targetStreamMessage = session.createStreamMessage();
               byte[] bytes = new byte[getByteBufferSize()];
               int byteCount;
               while((byteCount=sourceStreamMessage.readBytes(bytes))>0) {
               targetStreamMessage.writeBytes(bytes, 0, byteCount);
               }
               targetMessage = targetStreamMessage;
               } else {
               targetMessage = null;
               }
              
               if (targetMessage == null) {
               log.error("Message couldn't be copied");
               } else {
               // Header
               Enumeration propertyNameEnum = sourceMessage.getPropertyNames();
               while (propertyNameEnum.hasMoreElements()) {
               String propertyName = (String) propertyNameEnum.nextElement();
               targetMessage.setObjectProperty(propertyName, sourceMessage.getObjectProperty(propertyName));
               }
              
               // Message producer
               MessageProducer messageProducer = session.createProducer(getTargetDestination());
               messageProducer.setDeliveryMode(sourceMessage.getJMSDeliveryMode());
               messageProducer.setPriority(sourceMessage.getJMSPriority());
               final long timestamp = sourceMessage.getJMSTimestamp();
               if (timestamp>0) {
               final long expiration = sourceMessage.getJMSExpiration();
               if ((expiration>0)&&(expiration>timestamp)) {
               messageProducer.setTimeToLive(timestamp);
               }
               } else {
               messageProducer.setDisableMessageTimestamp(true);
               }
               messageProducer.send(targetMessage);
               }
               } catch(JMSException jmsExc) {
               log.error("Bridge message", jmsExc);
               } finally {
               if (connection != null) {
               try {
               connection.close();
               } catch (JMSException e) {
               }
               }
               }
               }
              


              I couldn't find an easier way to do it, could you?

              • 4. Re: Destination bridge
                genman


                The JBoss messages support a clone via "myClone()" so you can use that method instead of copying by hand from JBoss -> to some other provider. Or use the "SpyEncapsulatedMessage" to copy from other provider -> JBoss.

                It's not that elegant, I admit.