Problem with InOut pattern and JMS component

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Problem with InOut pattern and JMS component

S.R.-2
Hi,

I'm new to Camel, but this problem looks like the bug in JMS component.

I have a following route:

from("jms:sourceQueue").to("bean:testBean?methodName=test").to("jms:AQueue").to("jms:BQueue").

Scenario:
1. Initial message producer (IMP) sends the message (with JMSReplyTo field set to "jms:replies") to the jms:sourceQueue, and starts listening the jms:replies queue for replies;
2. Camel router gets the message from jms:sourceQueue and passes it to the testBean.test(exchange) method, that creates new message and set it to exchange.out field (see code bellow);
3. New Out message sends as In message to the jms:AQueue. Then other listener (AQueueListener, see code bellow) listens the jms:AQueue for new message and replies to its JMSReplyTo destination (that is
changed by Camel to some temp dest.)
4. Camel gets reply from AQueueListener (from temp Camel's queue) and sends it as In message to jms:BQueue;
5. The third listener (BQueueListener) listens the jms:BQueue message and replies to its JMSReplyTo destination (that was also replaced with Camel's temp queue);
6. Last step - Camel gets reply from BQueueListener (also from temp Camel's queue) and sends it as a response message to the jms:replies queue that is listened by IMP.

So If IMP sends the message like "abcd", finally it will get response like "[BQueueListener] Reply for [[AQueueListener] Reply for [[testBean] Reply for [abcd]]]"

That's all OK, but...

Then I want to change the endpoint's order to set JMS endpoint to the first place, like:

from("jms:sourceQueue").to("jms:AQueue").to("bean:testBean?methodName=test").to("jms:BQueue")

It is obviously that if IMP would send message "abcd", it would get response like "[BQueueListener] Reply for [[testBean] Reply for [[AQueueListener] Reply for [abcd]]]",
but actually it gets the "[AQueueListener] Reply for [abcd]"!

It means that after AQueueListener has responded on the message "abcd", the response "[AQueueListener] Reply for [abcd]" is immediately sent to the IMP's jms:replies queue as well as to further endpoints of route (I checked it by loging); and after BQueueListener (last element in chain) has responded on the message, the response isn't sent to the IMP's jms:replies.

Why? Is that expected behaviour? Or this is a bug?

Code Examples:
AQueueListener and BQueueListener (the same as AQueueListener):
public class AQueueListener implements MessageListener {
    private JmsTemplate jmsTemplate = ...;
    public void onMessage(Message message) {
            final TextMessage msg = (TextMessage) message;
            try {
                if (msg.getJMSReplyTo() != null) {
                    // do reply
                    jmsTemplate.convertAndSend(msg.getJMSReplyTo(), "[AQueueListener] Reply for [" + msg.getText() + "]",  new MessagePostProcessor() {
                            public Message postProcessMessage(Message message) throws JMSException {
                            message.setJMSCorrelationID(msg.getJMSCorrelationID());
                            return message;
                        }                        
                    });
                }
            } catch (JMSException e) {
                throw new RuntimeException(e);
            }
    }
}
TestBean:
class TestBean {
    public void test(Exchange ex) {
        Message msg = new JmsMessage();
        msg.setBody("[testBean] Reply for [" + ex.getIn().getBody().toString() + "]");
        ex.setOut(msg);
    }
}

I'm looking forward to your response.

Thanks in advance.

Sergey
Reply | Threaded
Open this post in threaded view
|

RE: Problem with InOut pattern and JMS component

Claus Ibsen
Hi

I got curious with your problem and hacked a small unit test in camel-jms component that mimic your routes. I am able to with success to get the reponse regardless in what order the bean is place in the route path.

Check out the unit test at:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsInOutPipelineWithBeanTest.java?view=markup


Note: This is on Camel 1.4-SNAPSHOT that is soon to be released in a new RC that hopefully gets voted as final.

What version of Camel are you using?


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk
-----Original Message-----
From: S.R. [mailto:[hidden email]]
Sent: 6. juli 2008 15:43
To: [hidden email]
Subject: Problem with InOut pattern and JMS component


Hi,

I'm new to Camel, but this problem looks like the bug in JMS component.

I have a following route:

from("jms:sourceQueue").to("bean:testBean?methodName=test").to("jms:AQueue").to("jms:BQueue").

Scenario:
1. Initial message producer (IMP) sends the message (with JMSReplyTo field
set to "jms:replies") to the jms:sourceQueue, and starts listening the
jms:replies queue for replies;
2. Camel router gets the message from jms:sourceQueue and passes it to the
testBean.test(exchange) method, that creates new message and set it to
exchange.out field (see code bellow);
3. New Out message sends as In message to the jms:AQueue. Then other
listener (AQueueListener, see code bellow) listens the jms:AQueue for new
message and replies to its JMSReplyTo destination (that is
changed by Camel to some temp dest.)
4. Camel gets reply from AQueueListener (from temp Camel's queue) and sends
it as In message to jms:BQueue;
5. The third listener (BQueueListener) listens the jms:BQueue message and
replies to its JMSReplyTo destination (that was also replaced with Camel's
temp queue);
6. Last step - Camel gets reply from BQueueListener (also from temp Camel's
queue) and sends it as a response message to the jms:replies queue that is
listened by IMP.

So If IMP sends the message like "abcd", finally it will get response like
"[BQueueListener] Reply for [[AQueueListener] Reply for [[testBean] Reply
for [abcd]]]"

That's all OK, but...

Then I want to change the endpoint's order to set JMS endpoint to the first
place, like:

from("jms:sourceQueue").to("jms:AQueue").to("bean:testBean?methodName=test").to("jms:BQueue")

It is obviously that if IMP would send message "abcd", it would get response
like "[BQueueListener] Reply for [[testBean] Reply for [[AQueueListener]
Reply for [abcd]]]",
but actually it gets the "[AQueueListener] Reply for [abcd]"!

It means that after AQueueListener has responded on the message "abcd", the
response "[AQueueListener] Reply for [abcd]" is immediately sent to the
IMP's jms:replies queue as well as to further endpoints of route (I checked
it by loging); and after BQueueListener (last element in chain) has
responded on the message, the response isn't sent to the IMP's jms:replies.

Why? Is that expected behaviour? Or this is a bug?

Code Examples:
AQueueListener and BQueueListener (the same as AQueueListener):
public class AQueueListener implements MessageListener {
    private JmsTemplate jmsTemplate = ...;
    public void onMessage(Message message) {
            final TextMessage msg = (TextMessage) message;
            try {
                if (msg.getJMSReplyTo() != null) {
                    // do reply
                    jmsTemplate.convertAndSend(msg.getJMSReplyTo(),
"[AQueueListener] Reply for [" + msg.getText() + "]",  new
MessagePostProcessor() {
                            public Message postProcessMessage(Message
message) throws JMSException {
                           
message.setJMSCorrelationID(msg.getJMSCorrelationID());
                            return message;
                        }                        
                    });
                }
            } catch (JMSException e) {
                throw new RuntimeException(e);
            }
    }
}
TestBean:
class TestBean {
    public void test(Exchange ex) {
        Message msg = new JmsMessage();
        msg.setBody("[testBean] Reply for [" +
ex.getIn().getBody().toString() + "]");
        ex.setOut(msg);
    }
}

I'm looking forward to your response.

Thanks in advance.

Sergey
--
View this message in context: http://www.nabble.com/Problem-with-InOut-pattern-and-JMS-component-tp18302249s22882p18302249.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|

RE: Problem with InOut pattern and JMS component

S.R.-2
Thank you for your response!

I'm using last release version 1.3.0.

I've just tried your test case and it has failed for testB() and testC() tests.
Test ouputs:
testA() Hello World,From Bean,From A,From B
testB() Hello World              (expected "Hello World,From A,From Bean,From B")
testC() Hello World              (expected "Hello World,From A,From B,From Bean")

In those cases we don't have processed reply at all (???).

Currently trying use 1.4.0-snapshot (there are some troubles because I have activemq-core-5.1.0 and it directly depends on camel-core-1.3.0). When I'm done I'll reply with results.

Claus Ibsen wrote
Hi

I got curious with your problem and hacked a small unit test in camel-jms component that mimic your routes. I am able to with success to get the reponse regardless in what order the bean is place in the route path.

Check out the unit test at:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsInOutPipelineWithBeanTest.java?view=markup


Note: This is on Camel 1.4-SNAPSHOT that is soon to be released in a new RC that hopefully gets voted as final.

What version of Camel are you using?


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk
-----Original Message-----
From: S.R. [mailto:srassokhin@gmail.com]
Sent: 6. juli 2008 15:43
To: camel-user@activemq.apache.org
Subject: Problem with InOut pattern and JMS component


Hi,

I'm new to Camel, but this problem looks like the bug in JMS component.

I have a following route:

from("jms:sourceQueue").to("bean:testBean?methodName=test").to("jms:AQueue").to("jms:BQueue").

Scenario:
1. Initial message producer (IMP) sends the message (with JMSReplyTo field
set to "jms:replies") to the jms:sourceQueue, and starts listening the
jms:replies queue for replies;
2. Camel router gets the message from jms:sourceQueue and passes it to the
testBean.test(exchange) method, that creates new message and set it to
exchange.out field (see code bellow);
3. New Out message sends as In message to the jms:AQueue. Then other
listener (AQueueListener, see code bellow) listens the jms:AQueue for new
message and replies to its JMSReplyTo destination (that is
changed by Camel to some temp dest.)
4. Camel gets reply from AQueueListener (from temp Camel's queue) and sends
it as In message to jms:BQueue;
5. The third listener (BQueueListener) listens the jms:BQueue message and
replies to its JMSReplyTo destination (that was also replaced with Camel's
temp queue);
6. Last step - Camel gets reply from BQueueListener (also from temp Camel's
queue) and sends it as a response message to the jms:replies queue that is
listened by IMP.

So If IMP sends the message like "abcd", finally it will get response like
"[BQueueListener] Reply for [[AQueueListener] Reply for [[testBean] Reply
for [abcd]]]"

That's all OK, but...

Then I want to change the endpoint's order to set JMS endpoint to the first
place, like:

from("jms:sourceQueue").to("jms:AQueue").to("bean:testBean?methodName=test").to("jms:BQueue")

It is obviously that if IMP would send message "abcd", it would get response
like "[BQueueListener] Reply for [[testBean] Reply for [[AQueueListener]
Reply for [abcd]]]",
but actually it gets the "[AQueueListener] Reply for [abcd]"!

It means that after AQueueListener has responded on the message "abcd", the
response "[AQueueListener] Reply for [abcd]" is immediately sent to the
IMP's jms:replies queue as well as to further endpoints of route (I checked
it by loging); and after BQueueListener (last element in chain) has
responded on the message, the response isn't sent to the IMP's jms:replies.

Why? Is that expected behaviour? Or this is a bug?

Code Examples:
AQueueListener and BQueueListener (the same as AQueueListener):
public class AQueueListener implements MessageListener {
    private JmsTemplate jmsTemplate = ...;
    public void onMessage(Message message) {
            final TextMessage msg = (TextMessage) message;
            try {
                if (msg.getJMSReplyTo() != null) {
                    // do reply
                    jmsTemplate.convertAndSend(msg.getJMSReplyTo(),
"[AQueueListener] Reply for [" + msg.getText() + "]",  new
MessagePostProcessor() {
                            public Message postProcessMessage(Message
message) throws JMSException {
                           
message.setJMSCorrelationID(msg.getJMSCorrelationID());
                            return message;
                        }                        
                    });
                }
            } catch (JMSException e) {
                throw new RuntimeException(e);
            }
    }
}
TestBean:
class TestBean {
    public void test(Exchange ex) {
        Message msg = new JmsMessage();
        msg.setBody("[testBean] Reply for [" +
ex.getIn().getBody().toString() + "]");
        ex.setOut(msg);
    }
}

I'm looking forward to your response.

Thanks in advance.

Sergey
--
View this message in context: http://www.nabble.com/Problem-with-InOut-pattern-and-JMS-component-tp18302249s22882p18302249.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Reply | Threaded
Open this post in threaded view
|

RE: Problem with InOut pattern and JMS component

S.R.-2
Yes, it works for 1.4.0. Perfect!

Thank you again.

S.R. wrote
Thank you for your response!

I'm using last release version 1.3.0.

I've just tried your test case and it has failed for testB() and testC() tests.
Test ouputs:
testA() Hello World,From Bean,From A,From B
testB() Hello World              (expected "Hello World,From A,From Bean,From B")
testC() Hello World              (expected "Hello World,From A,From B,From Bean")

In those cases we don't have processed reply at all (???).

Currently trying use 1.4.0-snapshot (there are some troubles because I have activemq-core-5.1.0 and it directly depends on camel-core-1.3.0). When I'm done I'll reply with results.

Claus Ibsen wrote
Hi

I got curious with your problem and hacked a small unit test in camel-jms component that mimic your routes. I am able to with success to get the reponse regardless in what order the bean is place in the route path.

Check out the unit test at:
http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsInOutPipelineWithBeanTest.java?view=markup


Note: This is on Camel 1.4-SNAPSHOT that is soon to be released in a new RC that hopefully gets voted as final.

What version of Camel are you using?


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk
-----Original Message-----
From: S.R. [mailto:srassokhin@gmail.com]
Sent: 6. juli 2008 15:43
To: camel-user@activemq.apache.org
Subject: Problem with InOut pattern and JMS component


Hi,

I'm new to Camel, but this problem looks like the bug in JMS component.

I have a following route:

from("jms:sourceQueue").to("bean:testBean?methodName=test").to("jms:AQueue").to("jms:BQueue").

Scenario:
1. Initial message producer (IMP) sends the message (with JMSReplyTo field
set to "jms:replies") to the jms:sourceQueue, and starts listening the
jms:replies queue for replies;
2. Camel router gets the message from jms:sourceQueue and passes it to the
testBean.test(exchange) method, that creates new message and set it to
exchange.out field (see code bellow);
3. New Out message sends as In message to the jms:AQueue. Then other
listener (AQueueListener, see code bellow) listens the jms:AQueue for new
message and replies to its JMSReplyTo destination (that is
changed by Camel to some temp dest.)
4. Camel gets reply from AQueueListener (from temp Camel's queue) and sends
it as In message to jms:BQueue;
5. The third listener (BQueueListener) listens the jms:BQueue message and
replies to its JMSReplyTo destination (that was also replaced with Camel's
temp queue);
6. Last step - Camel gets reply from BQueueListener (also from temp Camel's
queue) and sends it as a response message to the jms:replies queue that is
listened by IMP.

So If IMP sends the message like "abcd", finally it will get response like
"[BQueueListener] Reply for [[AQueueListener] Reply for [[testBean] Reply
for [abcd]]]"

That's all OK, but...

Then I want to change the endpoint's order to set JMS endpoint to the first
place, like:

from("jms:sourceQueue").to("jms:AQueue").to("bean:testBean?methodName=test").to("jms:BQueue")

It is obviously that if IMP would send message "abcd", it would get response
like "[BQueueListener] Reply for [[testBean] Reply for [[AQueueListener]
Reply for [abcd]]]",
but actually it gets the "[AQueueListener] Reply for [abcd]"!

It means that after AQueueListener has responded on the message "abcd", the
response "[AQueueListener] Reply for [abcd]" is immediately sent to the
IMP's jms:replies queue as well as to further endpoints of route (I checked
it by loging); and after BQueueListener (last element in chain) has
responded on the message, the response isn't sent to the IMP's jms:replies.

Why? Is that expected behaviour? Or this is a bug?

Code Examples:
AQueueListener and BQueueListener (the same as AQueueListener):
public class AQueueListener implements MessageListener {
    private JmsTemplate jmsTemplate = ...;
    public void onMessage(Message message) {
            final TextMessage msg = (TextMessage) message;
            try {
                if (msg.getJMSReplyTo() != null) {
                    // do reply
                    jmsTemplate.convertAndSend(msg.getJMSReplyTo(),
"[AQueueListener] Reply for [" + msg.getText() + "]",  new
MessagePostProcessor() {
                            public Message postProcessMessage(Message
message) throws JMSException {
                           
message.setJMSCorrelationID(msg.getJMSCorrelationID());
                            return message;
                        }                        
                    });
                }
            } catch (JMSException e) {
                throw new RuntimeException(e);
            }
    }
}
TestBean:
class TestBean {
    public void test(Exchange ex) {
        Message msg = new JmsMessage();
        msg.setBody("[testBean] Reply for [" +
ex.getIn().getBody().toString() + "]");
        ex.setOut(msg);
    }
}

I'm looking forward to your response.

Thanks in advance.

Sergey
--
View this message in context: http://www.nabble.com/Problem-with-InOut-pattern-and-JMS-component-tp18302249s22882p18302249.html
Sent from the Camel - Users mailing list archive at Nabble.com.