[Q] Camel header set in the fluent route builder gets lost

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[Q] Camel header set in the fluent route builder gets lost

zachpn
Hello Everybody!

I am relatively new to camel, so this might be a common mistake.
Also I am new to the mailing list, so please excuse me when I am doing something wrong here or if I am not sticking to the proper procedure.

I am trying to set up an application with several routes, inluding a scather-gather, and content-enricher.
A recepientList broadcasts a message to some query engines, they perform its task and send the result to the content enricher.
The content enricher needs to know from which engine the message is coming from, so he can properly enrich the message.
The content enricher will finally send the results to the aggregator.

To keep track where the message is coming from, I set the header in the query-engine-route by copying the value of the JMSDestination header.

I got the enricher working when I add it directly after the processor, but with an activemq:queue in between the exchange seems to loose the header I set earlier.
I can access the header in the query engine processor, but not anymore in the enricher processor.
I do only use exchange.getIn() in the processors, so this is not an exchange In/Out Problem like stated in the camel FAQs.
Also the header remains when I use constant() instead of getting the header dynamically with simple().

My route:
        // recipient list to broadcast the message
        from("activemq:queue:recipientlist").recipientList(header("recipients"));

        //query engines (currently only one, but more to come):
        from("activemq:queue:engine1")
                .setHeader("queryEngine", simple("${in.header.JMSDestination}"))
                .process(new queryProcessor())
                .to ("activemq:queue:enricher");

        //content enricher adds a certain Schema to the query Results, depending on the query engine the message is coming from
        from("activemq:queue:enricher")
                .process(new SchemaEnricher())
                .to("activemq:queue:aggregator");


I know the quick fix would be to write something like .setHeader("queryEngine", constant("queryEngine1")) , but this would mean more maintenance when adding new query engines.
So I really like to do it this way (or any other way where I can track from where the message is coming from).
Setting the header in the query-engine-processor would be an option too, but I kinda want it visible in the route.

Thanks for your help and best regards!

Philipp
Reply | Threaded
Open this post in threaded view
|

Re: [Q] Camel header set in the fluent route builder gets lost

John Poth
Hello Philipp! Welcome!

If I'm reading this correctly, you are setting the "queryEngine" header to
simple("${in.header.JMSDestination}" which at runtime will translate to
a org.apache.activemq.command.ActiveMQQueue object I believe. This will get
dropped by Camel [1]. You can verify this by setting your log level to
DEBUG.

Alternatively, you could use the JMS Queue's qualified name as so:

.setHeader("queryEngine", simple("${in.header.JMSDestination.toString}"))

HTH,

John.

[1]
https://github.com/apache/camel/blob/camel-2.22.0/components/camel-jms/src/main/docs/jms-component.adoc;
specifically

For the exchange.in.header, the following rules apply for the header
*values*:

   -

   The values must be primitives or their counter objects (such as Integer,
   Long, Character). The types, String, CharSequence, Date, BigDecimal and
   BigInteger are all converted to their toString() representation. All
   other types are dropped.

Camel will log with category org.apache.camel.component.jms.JmsBinding at
*DEBUG* level if it drops a given header value. For example:

2008-07-09 06:43:04,046 [main           ] DEBUG JmsBinding
  - Ignoring non primitive header: order of class:
org.apache.camel.component.jms.issues.DummyOrder with value:
DummyOrder{orderId=333, itemId=4444, quantity=2}



On Thu, Jul 5, 2018 at 4:09 PM, Philipp Zach <[hidden email]> wrote:

> Hello Everybody!
>
> I am relatively new to camel, so this might be a common mistake.
> Also I am new to the mailing list, so please excuse me when I am doing
> something wrong here or if I am not sticking to the proper procedure.
>
> I am trying to set up an application with several routes, inluding a
> scather-gather, and content-enricher.
> A recepientList broadcasts a message to some query engines, they perform
> its task and send the result to the content enricher.
> The content enricher needs to know from which engine the message is coming
> from, so he can properly enrich the message.
> The content enricher will finally send the results to the aggregator.
>
> To keep track where the message is coming from, I set the header in the
> query-engine-route by copying the value of the JMSDestination header.
>
> I got the enricher working when I add it directly after the processor, but
> with an activemq:queue in between the exchange seems to loose the header I
> set earlier.
> I can access the header in the query engine processor, but not anymore in
> the enricher processor.
> I do only use exchange.getIn() in the processors, so this is not an
> exchange In/Out Problem like stated in the camel FAQs.
> Also the header remains when I use constant() instead of getting the
> header dynamically with simple().
>
> My route:
>         // recipient list to broadcast the message
>         from("activemq:queue:recipientlist").recipientList(
> header("recipients"));
>
>         //query engines (currently only one, but more to come):
>         from("activemq:queue:engine1")
>                 .setHeader("queryEngine", simple("${in.header.JMSDestination}"))
>
>                 .process(new queryProcessor())
>                 .to ("activemq:queue:enricher");
>
>         //content enricher adds a certain Schema to the query Results,
> depending on the query engine the message is coming from
>         from("activemq:queue:enricher")
>                 .process(new SchemaEnricher())
>                 .to("activemq:queue:aggregator");
>
>
> I know the quick fix would be to write something like
> .setHeader("queryEngine", constant("queryEngine1")) , but this would mean
> more maintenance when adding new query engines.
> So I really like to do it this way (or any other way where I can track
> from where the message is coming from).
> Setting the header in the query-engine-processor would be an option too,
> but I kinda want it visible in the route.
>
> Thanks for your help and best regards!
>
> Philipp
>
Reply | Threaded
Open this post in threaded view
|

AW: [Q] Camel header set in the fluent route builder gets lost

zachpn
Hello John!

Thanks a lot for your solution. The header is set now correctly.

Best regards,

Philipp.

________________________________
Von: John Poth <[hidden email]>
Gesendet: Donnerstag, 5. Juli 2018 20:33:18
An: [hidden email]
Betreff: Re: [Q] Camel header set in the fluent route builder gets lost

Hello Philipp! Welcome!

If I'm reading this correctly, you are setting the "queryEngine" header to
simple("${in.header.JMSDestination}" which at runtime will translate to
a org.apache.activemq.command.ActiveMQQueue object I believe. This will get
dropped by Camel [1]. You can verify this by setting your log level to
DEBUG.

Alternatively, you could use the JMS Queue's qualified name as so:

.setHeader("queryEngine", simple("${in.header.JMSDestination.toString}"))

HTH,

John.

[1]
https://github.com/apache/camel/blob/camel-2.22.0/components/camel-jms/src/main/docs/jms-component.adoc;
specifically

For the exchange.in.header, the following rules apply for the header
*values*:

   -

   The values must be primitives or their counter objects (such as Integer,
   Long, Character). The types, String, CharSequence, Date, BigDecimal and
   BigInteger are all converted to their toString() representation. All
   other types are dropped.

Camel will log with category org.apache.camel.component.jms.JmsBinding at
*DEBUG* level if it drops a given header value. For example:

2008-07-09 06:43:04,046 [main           ] DEBUG JmsBinding
  - Ignoring non primitive header: order of class:
org.apache.camel.component.jms.issues.DummyOrder with value:
DummyOrder{orderId=333, itemId=4444, quantity=2}



On Thu, Jul 5, 2018 at 4:09 PM, Philipp Zach <[hidden email]> wrote:

> Hello Everybody!
>
> I am relatively new to camel, so this might be a common mistake.
> Also I am new to the mailing list, so please excuse me when I am doing
> something wrong here or if I am not sticking to the proper procedure.
>
> I am trying to set up an application with several routes, inluding a
> scather-gather, and content-enricher.
> A recepientList broadcasts a message to some query engines, they perform
> its task and send the result to the content enricher.
> The content enricher needs to know from which engine the message is coming
> from, so he can properly enrich the message.
> The content enricher will finally send the results to the aggregator.
>
> To keep track where the message is coming from, I set the header in the
> query-engine-route by copying the value of the JMSDestination header.
>
> I got the enricher working when I add it directly after the processor, but
> with an activemq:queue in between the exchange seems to loose the header I
> set earlier.
> I can access the header in the query engine processor, but not anymore in
> the enricher processor.
> I do only use exchange.getIn() in the processors, so this is not an
> exchange In/Out Problem like stated in the camel FAQs.
> Also the header remains when I use constant() instead of getting the
> header dynamically with simple().
>
> My route:
>         // recipient list to broadcast the message
>         from("activemq:queue:recipientlist").recipientList(
> header("recipients"));
>
>         //query engines (currently only one, but more to come):
>         from("activemq:queue:engine1")
>                 .setHeader("queryEngine", simple("${in.header.JMSDestination}"))
>
>                 .process(new queryProcessor())
>                 .to ("activemq:queue:enricher");
>
>         //content enricher adds a certain Schema to the query Results,
> depending on the query engine the message is coming from
>         from("activemq:queue:enricher")
>                 .process(new SchemaEnricher())
>                 .to("activemq:queue:aggregator");
>
>
> I know the quick fix would be to write something like
> .setHeader("queryEngine", constant("queryEngine1")) , but this would mean
> more maintenance when adding new query engines.
> So I really like to do it this way (or any other way where I can track
> from where the message is coming from).
> Setting the header in the query-engine-processor would be an option too,
> but I kinda want it visible in the route.
>
> Thanks for your help and best regards!
>
> Philipp
>