camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Claus Ibsen <claus.ib...@gmail.com>
Subject Re: How to implement dynamic JmsConstants.JMS_DESTINATION_NAME w/Processor component?
Date Thu, 01 Dec 2011 19:07:58 GMT
Hi

Seems a bit odd, as using a Processor gives you directly access to the
Exchange, so if you add an header on the Exchange, then it ought to be
there, when the JmsProducer is invoked.

Could you check whether the exchange has also an OUT message in the processor?
But it should really not have that, as Camel uses the
pipes-and-filters EIP by default
http://camel.apache.org/pipes-and-filters

See this FAQ
http://camel.apache.org/using-getin-or-getout-methods-on-exchange.html

Btw did you write which Camel version you are using?


On Wed, Nov 30, 2011 at 9:21 PM, Jason Dillon <jason@planet57.com> wrote:
> On Nov 29, 2011, at 11:52 PM, Willem Jiang wrote:
>>> I spent a few hours (I think again) trying to implement a dynamic
>>> destination based on IN message using a Processor only to find out
>>> that it didn't work as I expected.  Quite possible because I don't
>>> understand the full contract for what a processor component needs to
>>> do.  I did find that using a bean() component worked, but I'd really
>>> like to avoid any reflection overhead involved.  I simply need to
>>> filter the messages passed to a route so I can select the correct
>>> destination.  I figured a processor was the way to do this, but
>>> simply adding a processor and setting the IN.header didn't work,
>>> actually it messed up the in message that ended up at the jms
>>> component (had null body, no headers).
>> I need to have a look at your processor code :)
>
> I basically did what the example showed on this page http://camel.apache.org/jms.html,
except in a processor instead of a pojo:
>
> <snip>
> public class DestinationSelector
>    implements Processor
> {
>    @Override
>    public void process(Exchange exchange) throws Exception {
>        checkNotNull(exchange);
>        Message message = exchange.getIn();
>        EventMessage event = message.getBody(EventMessage.class);
>        String name = String.format(TOPIC_FORMAT, event.getRepoId());
>        message.setHeader(JmsConstants.JMS_DESTINATION_NAME, name);
>    }
> }
> </snip>
>
> And then hooked it up with:
>
> <snip>
> camel.addRoutes(new RouteBuilder()
> {
>    @Override
>    public void configure() throws Exception {
>        from("direct:dispatch")
>            .routeId("route1")
>            .process(new DestinationSelector())
>            .to("local-jms:topic:ignored"); // calculated by selector
>    }
> });
> </snip>
>
> This didn't work, and debugging the JmsProducer shows that the in message body is null.
>
> Using a pojo does work however:
>
> <snip>
> public class DestinationSelector
> {
>    public void select(final Exchange exchange) throws Exception {
>        checkNotNull(exchange);
>        Message message = exchange.getIn();
>        EventMessage event = message.getBody(EventMessage.class);
>        String name = String.format(TOPIC_FORMAT, event.getRepoId());
>        message.setHeader(JmsConstants.JMS_DESTINATION_NAME, name);
>    }
> }
> </snip>
>
> hooked up with:
>
> <snip>
> camel.addRoutes(new RouteBuilder()
> {
>    @Override
>    public void configure() throws Exception {
>        from("direct:dispatch")
>            .routeId("route1")
>            .bean(new DestinationSelector())
>            .to("local-jms:topic:ignored"); // calculated by selector
>    }
> });
> </snip>
>
> However I believe this will have to employ some reflection to invoke, which I'd rather
avoid if possible.
>
>
>>> Is the processor intended to set the out message, and that out
>>> message would then be used as the in message for the next step?
>>
>> Yes, camel pipeline process will copy the out message to next exchange in message
if you set the out message body.
>
> What is special about the bean() method vs. the process() method that allows it to work
and the processor to fail?
>
>
>>> I'm just looking for the most efficent way to implement "Reuse
>>> endpoint and send to different destinations computed at runtime" (
>>> http://camel.apache.org/jms.html )... just a direct invocation that
>>> gets the Exchange (like a Processor does) w/o the bean
>>> introspection/invocation overhead.
>>
>> I think you can set the message header in the processor as the bean does.
>
> The same code doesn't work in a processor... which is why I'm confused :-(
>
> If you, or anyone really, could help explain why one works and the other fails it would
be a big help :-)
>
> Thanks,
>
> --jason
>
>



-- 
Claus Ibsen
-----------------
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus, fusenews
Blog: http://davsclaus.blogspot.com/
Author of Camel in Action: http://www.manning.com/ibsen/

Mime
View raw message