You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by paquettd <da...@lmco.com> on 2009/02/26 16:52:00 UTC

@RecipientList and ProducerTemplate (Camel 1.6 and 1.5)

I'm seeing a behavior in camel 1.6 I don't understand. when I used the
producerTemplate to kickoff a workflow that
includes a @RecipientList component I seem to get back the result of the
recipient list... but my other services
end up being called (and their results simply lost to the ether).

Here are some details (scrubbed of the real names; but the same idea)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:camel="http://activemq.apache.org/camel/schema/spring"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd
	http://activemq.apache.org/camel/schema/spring
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">

    <bean id="serviceA" class="example.ServiceAImpl"/>
    <bean id="serviceB" class="example.ServiceAImpl"/>
    <bean id="serviceC" class="example.ServiceAImpl"/>

    <bean id="myRouter" class="example.MyRouter">
        <property name="passUrl" value="direct:needABC"/>
        <property name="failUrl" value="direct:needBC"/>
    </bean>

    <camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
        <template id="myCamelTemplate" defaultEndpoint="direct:test"/>

        <route>
            <from uri="direct:test"/>
            <bean ref="myRouter"/>
        </route>

        <route>
            <from uri="direct:needABC"/>
            <bean ref="serviceA"/>
            <to uri="direct:needBC"/>
        </route>
        
        <route>
            <from uri="direct:needBC"/>
            <bean ref="serviceB"/>
            <bean ref="serviceC"/>
        </route>
        
    </camelContext>

    <bean id="myTester" class="example.MyTester">
        <property name="producerTemplate" ref="myCamelTemplate"/>
    </bean>
</beans>



My router class looks like:

public class MyRouter{

	public String passUrl = null;
	public String failUrl = null;
	
	@RecipientList
	public String route(String body) {
		// for testing always return passUrl
		return passUrl;
	}
	
	public void setPassUrl(String url) {
		passUrl = url;
	}
	
	public void setFailUrl(String url) {
		failUrl = url;
	}
}

And finally my "tester" does this:

template.requestBody(template.getDefaultEndpoint(), "Hello World")

All my services expect a String in this test; they just mutate it
(capitalize, reverse, other trival ops)
for the purpose of testing. I get to all those breakpoints.

Anyway.. requestBody returns "direct:needABC" to me... but then I see
services A,B and C getting called.
If I changed direct:test to seda:test I get back my original input... and
services A,B and C still get called.
Both ways the result are lost.

Am I missing something very obvious?

FYI I was trying to avoid using @RecipientList and using <choose><when> etc
with groovy or javascript to do my
content based routing. Unfortunatly I'm using Java 5 without
javax.scripting. I tried installing
the javax.scripting implementation from java.net but couldn't quite get it
going in my OSGi container.
I guess that's a different question; but that would be my preferred
implementation.
-- 
View this message in context: http://www.nabble.com/%40RecipientList-and-ProducerTemplate-%28Camel-1.6-and-1.5%29-tp22227016p22227016.html
Sent from the Camel - Users (activemq) mailing list archive at Nabble.com.


Re: @RecipientList and ProducerTemplate (Camel 1.6 and 1.5)

Posted by paquettd <da...@lmco.com>.
Ok, good news I figured out what I should have been doing instead of a
RecipientList!

For giggles i was trying to route any message that had lower case letters in
it (just playing around)
So I finally discovered methodCall and simple. First i used methodCall to
call a matches method that returns boolean on a bean. Eventually I
discovered the simple language does what I want.

It may seem obvious now; but for some reason I never really landed here in
the directions until today.

<when>
  <!-- <methodCall bean="isLowercaseBean" method="matches"></methodCall> -->
  <simple>${body} regex '.*[a-x].*'</simple>
  <to uri="direct:pathA"/>
</when>
<otherwise>
  <to uri="direct:pathB"/>
</otherwise>

I think I still stand by my reasoning that RecipientList is doing the "right
thing". Since it can route to multiple paths; how could is possibly return
me one of those values in an InOut situation; it wouldn't know which one i
want.


Claus Ibsen-2 wrote:
> 
> On Thu, Feb 26, 2009 at 6:45 PM, paquettd <da...@lmco.com> wrote:
>>
>> Looking into this more it seems to be because I am ending up in a
>> BeanProcessor. Line 120 of the bean processor is where the output of the
>> @RecipientList method is overwriting the Out part of the exchange (which
>> actually has the right data in it at that point).
>>
>> Using the Spring DSL is there a way for me to change the Processor being
>> used? Or declare my @RecipientList pojo within the <RecipientList> tag.
> If you POJO is @RecipientList then you can just route to it from Spring
> DSL
> 
> <to uri="bean:MyPOJOWithRecipeintListAnnotation"/>
> 
> 
>>
>>
>> paquettd wrote:
>>>
>>> I'm seeing a behavior in camel 1.6 I don't understand. when I used the
>>> producerTemplate to kickoff a workflow that
>>> includes a @RecipientList component I seem to get back the result of the
>>> recipient list... but my other services
>>> end up being called (and their results simply lost to the ether).
>>>
>>> Here are some details (scrubbed of the real names; but the same idea)
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <beans xmlns="http://www.springframework.org/schema/beans"
>>>       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>       xmlns:camel="http://activemq.apache.org/camel/schema/spring"
>>>       xsi:schemaLocation="http://www.springframework.org/schema/beans
>>>
>>> http://www.springframework.org/schema/beans/spring-beans.xsd
>>>       http://activemq.apache.org/camel/schema/spring
>>> http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">
>>>
>>>     <bean id="serviceA" class="example.ServiceAImpl"/>
>>>     <bean id="serviceB" class="example.ServiceAImpl"/>
>>>     <bean id="serviceC" class="example.ServiceAImpl"/>
>>>
>>>     <bean id="myRouter" class="example.MyRouter">
>>>         <property name="passUrl" value="direct:needABC"/>
>>>         <property name="failUrl" value="direct:needBC"/>
>>>     </bean>
>>>
>>>     <camelContext
>>> xmlns="http://activemq.apache.org/camel/schema/spring">
>>>         <template id="myCamelTemplate" defaultEndpoint="direct:test"/>
>>>
>>>         <route>
>>>             <from uri="direct:test"/>
>>>             <bean ref="myRouter"/>
>>>         </route>
>>>
>>>         <route>
>>>             <from uri="direct:needABC"/>
>>>             <bean ref="serviceA"/>
>>>             <to uri="direct:needBC"/>
>>>         </route>
>>>
>>>         <route>
>>>             <from uri="direct:needBC"/>
>>>             <bean ref="serviceB"/>
>>>             <bean ref="serviceC"/>
>>>         </route>
>>>
>>>     </camelContext>
>>>
>>>     <bean id="myTester" class="example.MyTester">
>>>         <property name="producerTemplate" ref="myCamelTemplate"/>
>>>     </bean>
>>> </beans>
>>>
>>>
>>>
>>> My router class looks like:
>>>
>>> public class MyRouter{
>>>
>>>       public String passUrl = null;
>>>       public String failUrl = null;
>>>
>>>       @RecipientList
>>>       public String route(String body) {
>>>               // for testing always return passUrl
>>>               return passUrl;
>>>       }
>>>
>>>       public void setPassUrl(String url) {
>>>               passUrl = url;
>>>       }
>>>
>>>       public void setFailUrl(String url) {
>>>               failUrl = url;
>>>       }
>>> }
>>>
>>> And finally my "tester" does this:
>>>
>>> template.requestBody(template.getDefaultEndpoint(), "Hello World")
>>>
>>> All my services expect a String in this test; they just mutate it
>>> (capitalize, reverse, other trival ops)
>>> for the purpose of testing. I get to all those breakpoints.
>>>
>>> Anyway.. requestBody returns "direct:needABC" to me... but then I see
>>> services A,B and C getting called.
>>> If I changed direct:test to seda:test I get back my original input...
>>> and
>>> services A,B and C still get called.
>>> Both ways the result are lost.
>>>
>>> Am I missing something very obvious?
>>>
>>> FYI I was trying to avoid using @RecipientList and using <choose><when>
>>> etc with groovy or javascript to do my
>>> content based routing. Unfortunatly I'm using Java 5 without
>>> javax.scripting. I tried installing
>>> the javax.scripting implementation from java.net but couldn't quite get
>>> it
>>> going in my OSGi container.
>>> I guess that's a different question; but that would be my preferred
>>> implementation.
>>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/%40RecipientList-and-ProducerTemplate-%28Camel-1.6-and-1.5%29-tp22227016p22229622.html
>> Sent from the Camel - Users (activemq) mailing list archive at
>> Nabble.com.
>>
>>
> 
> 
> 
> -- 
> Claus Ibsen
> Apache Camel Committer
> 
> Open Source Integration: http://fusesource.com
> Blog: http://davsclaus.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/Re%3A-%40RecipientList-and-ProducerTemplate-%28Camel-1.6-and-1.5%29-tp22229754p22245800.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: @RecipientList and ProducerTemplate (Camel 1.6 and 1.5)

Posted by paquettd <da...@lmco.com>.
I still end up in the BeanProcessor using this technique and I get the same
results....

As I said; the message DOES get routed to the recipient list; it's just the
result the ultimately winds it way back is the recipient list itself.

The more I think about it maybe that is the only behavior... after all, what
if I sent to 2 outputs; which answer could it possibly respond with.


Claus Ibsen-2 wrote:
> 
> On Thu, Feb 26, 2009 at 6:45 PM, paquettd <da...@lmco.com> wrote:
>>
>> Looking into this more it seems to be because I am ending up in a
>> BeanProcessor. Line 120 of the bean processor is where the output of the
>> @RecipientList method is overwriting the Out part of the exchange (which
>> actually has the right data in it at that point).
>>
>> Using the Spring DSL is there a way for me to change the Processor being
>> used? Or declare my @RecipientList pojo within the <RecipientList> tag.
> If you POJO is @RecipientList then you can just route to it from Spring
> DSL
> 
> <to uri="bean:MyPOJOWithRecipeintListAnnotation"/>
> 
> 
>>
>>
>> paquettd wrote:
>>>
>>> I'm seeing a behavior in camel 1.6 I don't understand. when I used the
>>> producerTemplate to kickoff a workflow that
>>> includes a @RecipientList component I seem to get back the result of the
>>> recipient list... but my other services
>>> end up being called (and their results simply lost to the ether).
>>>
>>> Here are some details (scrubbed of the real names; but the same idea)
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <beans xmlns="http://www.springframework.org/schema/beans"
>>>       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>       xmlns:camel="http://activemq.apache.org/camel/schema/spring"
>>>       xsi:schemaLocation="http://www.springframework.org/schema/beans
>>>
>>> http://www.springframework.org/schema/beans/spring-beans.xsd
>>>       http://activemq.apache.org/camel/schema/spring
>>> http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">
>>>
>>>     <bean id="serviceA" class="example.ServiceAImpl"/>
>>>     <bean id="serviceB" class="example.ServiceAImpl"/>
>>>     <bean id="serviceC" class="example.ServiceAImpl"/>
>>>
>>>     <bean id="myRouter" class="example.MyRouter">
>>>         <property name="passUrl" value="direct:needABC"/>
>>>         <property name="failUrl" value="direct:needBC"/>
>>>     </bean>
>>>
>>>     <camelContext
>>> xmlns="http://activemq.apache.org/camel/schema/spring">
>>>         <template id="myCamelTemplate" defaultEndpoint="direct:test"/>
>>>
>>>         <route>
>>>             <from uri="direct:test"/>
>>>             <bean ref="myRouter"/>
>>>         </route>
>>>
>>>         <route>
>>>             <from uri="direct:needABC"/>
>>>             <bean ref="serviceA"/>
>>>             <to uri="direct:needBC"/>
>>>         </route>
>>>
>>>         <route>
>>>             <from uri="direct:needBC"/>
>>>             <bean ref="serviceB"/>
>>>             <bean ref="serviceC"/>
>>>         </route>
>>>
>>>     </camelContext>
>>>
>>>     <bean id="myTester" class="example.MyTester">
>>>         <property name="producerTemplate" ref="myCamelTemplate"/>
>>>     </bean>
>>> </beans>
>>>
>>>
>>>
>>> My router class looks like:
>>>
>>> public class MyRouter{
>>>
>>>       public String passUrl = null;
>>>       public String failUrl = null;
>>>
>>>       @RecipientList
>>>       public String route(String body) {
>>>               // for testing always return passUrl
>>>               return passUrl;
>>>       }
>>>
>>>       public void setPassUrl(String url) {
>>>               passUrl = url;
>>>       }
>>>
>>>       public void setFailUrl(String url) {
>>>               failUrl = url;
>>>       }
>>> }
>>>
>>> And finally my "tester" does this:
>>>
>>> template.requestBody(template.getDefaultEndpoint(), "Hello World")
>>>
>>> All my services expect a String in this test; they just mutate it
>>> (capitalize, reverse, other trival ops)
>>> for the purpose of testing. I get to all those breakpoints.
>>>
>>> Anyway.. requestBody returns "direct:needABC" to me... but then I see
>>> services A,B and C getting called.
>>> If I changed direct:test to seda:test I get back my original input...
>>> and
>>> services A,B and C still get called.
>>> Both ways the result are lost.
>>>
>>> Am I missing something very obvious?
>>>
>>> FYI I was trying to avoid using @RecipientList and using <choose><when>
>>> etc with groovy or javascript to do my
>>> content based routing. Unfortunatly I'm using Java 5 without
>>> javax.scripting. I tried installing
>>> the javax.scripting implementation from java.net but couldn't quite get
>>> it
>>> going in my OSGi container.
>>> I guess that's a different question; but that would be my preferred
>>> implementation.
>>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/%40RecipientList-and-ProducerTemplate-%28Camel-1.6-and-1.5%29-tp22227016p22229622.html
>> Sent from the Camel - Users (activemq) mailing list archive at
>> Nabble.com.
>>
>>
> 
> 
> 
> -- 
> Claus Ibsen
> Apache Camel Committer
> 
> Open Source Integration: http://fusesource.com
> Blog: http://davsclaus.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/Re%3A-%40RecipientList-and-ProducerTemplate-%28Camel-1.6-and-1.5%29-tp22229754p22245557.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: @RecipientList and ProducerTemplate (Camel 1.6 and 1.5)

Posted by Claus Ibsen <cl...@gmail.com>.
On Thu, Feb 26, 2009 at 6:45 PM, paquettd <da...@lmco.com> wrote:
>
> Looking into this more it seems to be because I am ending up in a
> BeanProcessor. Line 120 of the bean processor is where the output of the
> @RecipientList method is overwriting the Out part of the exchange (which
> actually has the right data in it at that point).
>
> Using the Spring DSL is there a way for me to change the Processor being
> used? Or declare my @RecipientList pojo within the <RecipientList> tag.
If you POJO is @RecipientList then you can just route to it from Spring DSL

<to uri="bean:MyPOJOWithRecipeintListAnnotation"/>


>
>
> paquettd wrote:
>>
>> I'm seeing a behavior in camel 1.6 I don't understand. when I used the
>> producerTemplate to kickoff a workflow that
>> includes a @RecipientList component I seem to get back the result of the
>> recipient list... but my other services
>> end up being called (and their results simply lost to the ether).
>>
>> Here are some details (scrubbed of the real names; but the same idea)
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>> <beans xmlns="http://www.springframework.org/schema/beans"
>>       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>       xmlns:camel="http://activemq.apache.org/camel/schema/spring"
>>       xsi:schemaLocation="http://www.springframework.org/schema/beans
>>
>> http://www.springframework.org/schema/beans/spring-beans.xsd
>>       http://activemq.apache.org/camel/schema/spring
>> http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">
>>
>>     <bean id="serviceA" class="example.ServiceAImpl"/>
>>     <bean id="serviceB" class="example.ServiceAImpl"/>
>>     <bean id="serviceC" class="example.ServiceAImpl"/>
>>
>>     <bean id="myRouter" class="example.MyRouter">
>>         <property name="passUrl" value="direct:needABC"/>
>>         <property name="failUrl" value="direct:needBC"/>
>>     </bean>
>>
>>     <camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
>>         <template id="myCamelTemplate" defaultEndpoint="direct:test"/>
>>
>>         <route>
>>             <from uri="direct:test"/>
>>             <bean ref="myRouter"/>
>>         </route>
>>
>>         <route>
>>             <from uri="direct:needABC"/>
>>             <bean ref="serviceA"/>
>>             <to uri="direct:needBC"/>
>>         </route>
>>
>>         <route>
>>             <from uri="direct:needBC"/>
>>             <bean ref="serviceB"/>
>>             <bean ref="serviceC"/>
>>         </route>
>>
>>     </camelContext>
>>
>>     <bean id="myTester" class="example.MyTester">
>>         <property name="producerTemplate" ref="myCamelTemplate"/>
>>     </bean>
>> </beans>
>>
>>
>>
>> My router class looks like:
>>
>> public class MyRouter{
>>
>>       public String passUrl = null;
>>       public String failUrl = null;
>>
>>       @RecipientList
>>       public String route(String body) {
>>               // for testing always return passUrl
>>               return passUrl;
>>       }
>>
>>       public void setPassUrl(String url) {
>>               passUrl = url;
>>       }
>>
>>       public void setFailUrl(String url) {
>>               failUrl = url;
>>       }
>> }
>>
>> And finally my "tester" does this:
>>
>> template.requestBody(template.getDefaultEndpoint(), "Hello World")
>>
>> All my services expect a String in this test; they just mutate it
>> (capitalize, reverse, other trival ops)
>> for the purpose of testing. I get to all those breakpoints.
>>
>> Anyway.. requestBody returns "direct:needABC" to me... but then I see
>> services A,B and C getting called.
>> If I changed direct:test to seda:test I get back my original input... and
>> services A,B and C still get called.
>> Both ways the result are lost.
>>
>> Am I missing something very obvious?
>>
>> FYI I was trying to avoid using @RecipientList and using <choose><when>
>> etc with groovy or javascript to do my
>> content based routing. Unfortunatly I'm using Java 5 without
>> javax.scripting. I tried installing
>> the javax.scripting implementation from java.net but couldn't quite get it
>> going in my OSGi container.
>> I guess that's a different question; but that would be my preferred
>> implementation.
>>
>
> --
> View this message in context: http://www.nabble.com/%40RecipientList-and-ProducerTemplate-%28Camel-1.6-and-1.5%29-tp22227016p22229622.html
> Sent from the Camel - Users (activemq) mailing list archive at Nabble.com.
>
>



-- 
Claus Ibsen
Apache Camel Committer

Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/

Re: @RecipientList and ProducerTemplate (Camel 1.6 and 1.5)

Posted by paquettd <da...@lmco.com>.
Looking into this more it seems to be because I am ending up in a
BeanProcessor. Line 120 of the bean processor is where the output of the
@RecipientList method is overwriting the Out part of the exchange (which
actually has the right data in it at that point).

Using the Spring DSL is there a way for me to change the Processor being
used? Or declare my @RecipientList pojo within the <RecipientList> tag.


paquettd wrote:
> 
> I'm seeing a behavior in camel 1.6 I don't understand. when I used the
> producerTemplate to kickoff a workflow that
> includes a @RecipientList component I seem to get back the result of the
> recipient list... but my other services
> end up being called (and their results simply lost to the ether).
> 
> Here are some details (scrubbed of the real names; but the same idea)
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <beans xmlns="http://www.springframework.org/schema/beans"
> 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> 	xmlns:camel="http://activemq.apache.org/camel/schema/spring"
> 	xsi:schemaLocation="http://www.springframework.org/schema/beans 
> 
> http://www.springframework.org/schema/beans/spring-beans.xsd
> 	http://activemq.apache.org/camel/schema/spring
> http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">
> 
>     <bean id="serviceA" class="example.ServiceAImpl"/>
>     <bean id="serviceB" class="example.ServiceAImpl"/>
>     <bean id="serviceC" class="example.ServiceAImpl"/>
> 
>     <bean id="myRouter" class="example.MyRouter">
>         <property name="passUrl" value="direct:needABC"/>
>         <property name="failUrl" value="direct:needBC"/>
>     </bean>
> 
>     <camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
>         <template id="myCamelTemplate" defaultEndpoint="direct:test"/>
> 
>         <route>
>             <from uri="direct:test"/>
>             <bean ref="myRouter"/>
>         </route>
> 
>         <route>
>             <from uri="direct:needABC"/>
>             <bean ref="serviceA"/>
>             <to uri="direct:needBC"/>
>         </route>
>         
>         <route>
>             <from uri="direct:needBC"/>
>             <bean ref="serviceB"/>
>             <bean ref="serviceC"/>
>         </route>
>         
>     </camelContext>
> 
>     <bean id="myTester" class="example.MyTester">
>         <property name="producerTemplate" ref="myCamelTemplate"/>
>     </bean>
> </beans>
> 
> 
> 
> My router class looks like:
> 
> public class MyRouter{
> 
> 	public String passUrl = null;
> 	public String failUrl = null;
> 	
> 	@RecipientList
> 	public String route(String body) {
> 		// for testing always return passUrl
> 		return passUrl;
> 	}
> 	
> 	public void setPassUrl(String url) {
> 		passUrl = url;
> 	}
> 	
> 	public void setFailUrl(String url) {
> 		failUrl = url;
> 	}
> }
> 
> And finally my "tester" does this:
> 
> template.requestBody(template.getDefaultEndpoint(), "Hello World")
> 
> All my services expect a String in this test; they just mutate it
> (capitalize, reverse, other trival ops)
> for the purpose of testing. I get to all those breakpoints.
> 
> Anyway.. requestBody returns "direct:needABC" to me... but then I see
> services A,B and C getting called.
> If I changed direct:test to seda:test I get back my original input... and
> services A,B and C still get called.
> Both ways the result are lost.
> 
> Am I missing something very obvious?
> 
> FYI I was trying to avoid using @RecipientList and using <choose><when>
> etc with groovy or javascript to do my
> content based routing. Unfortunatly I'm using Java 5 without
> javax.scripting. I tried installing
> the javax.scripting implementation from java.net but couldn't quite get it
> going in my OSGi container.
> I guess that's a different question; but that would be my preferred
> implementation.
> 

-- 
View this message in context: http://www.nabble.com/%40RecipientList-and-ProducerTemplate-%28Camel-1.6-and-1.5%29-tp22227016p22229622.html
Sent from the Camel - Users (activemq) mailing list archive at Nabble.com.