You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by sim085 <si...@hotmail.com> on 2017/01/08 23:48:11 UTC
How to call a route, wait to finish, and ignore any changes when
this returns?
Hello,
I have a route "A" which calls a route "B", route "B" adds some headers,
removes some others, changes the body, etc. Is there a way how I can call
route "B" from route "A", wait for route "B" to finish and once route "B"
returns, route "A" will be in the same state as before calling route "B"
(i.e. - same headers, same body)?
I tried using the SEDA component with the "waitForTaskToComplete" set to
"Always" but this does not seem to work, i.e. - if I use
InOnly("seda:B?waitForTaskToComplete=Always") then this works as if calling
the SEDA component with inOut(...).
For example:
[code]
from("seda:A")
.log("Hello From A")
.setHeader("MyHeader", constant("A-HEADER"))
.transform(constant("A-BODY"))
.inOnly("seda:B?waitForTaskToComplete=Always")
.log("MyHeader is ${in.header.MyHeader}")
.log("Body is ${body}")
;
from("seda:B")
.log("Hello From B")
.setHeader("MyHeader", constant("B-HEADER"))
.transform(constant("B-BODY"))
.log("Ready from B")
;
[/code]
Will Print:
[(camel-1) thread #0 - seda://A] route2 INFO Hello
From A
[(camel-1) thread #1 - seda://B] route3 INFO Hello
From B
[(camel-1) thread #1 - seda://B] route3 INFO Ready
from B
[(camel-1) thread #0 - seda://A] route2 INFO
MyHeader is B-HEADER
[(camel-1) thread #0 - seda://A] route2 INFO Body
is B-BODY
I was under the impression that calling seda:B with InOnly would force the
component not to return however it seems that waitForTaskToComplete=Always
makes it work like InOut rather than just wait for the task to complete.
Is there a way how I can achieve the above? i.e. - call a route, wait for
this to finish, but message from the caller route (in my case "A") remains
the same as before calling the second route.
--
View this message in context: http://camel.465427.n5.nabble.com/How-to-call-a-route-wait-to-finish-and-ignore-any-changes-when-this-returns-tp5792288.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: How to call a route, wait to finish, and ignore any changes
when this returns?
Posted by Christian Schaefer <sy...@yahoo.de.INVALID>.
UNSUBSCRIBE
Taariq Levack <ta...@gmail.com> schrieb am 18:28 Dienstag, 10.Januar 2017:
In that scenario you might consider multicasting to a route that processes
the deletes in order, as well as to the next/result route.
Just don't process in parallel in that case.
Also, I wouldn't suggest the enricher for each delete like in your example,
perhaps rather route to something that splits and aggregates and then you
might enrich your original exchange with the aggregated result, or
disregard as you did just now.
On 10 Jan 2017 10:15, "sim085" <si...@hotmail.com> wrote:
However thinking out loud ... is this the right way to do it? This is
actually the opposite of message enriching.
It works, I just wonder if it is the right approach.
For example imagine a scenario where you have a CSV file which has a list of
users that have to be deleted from a system. You load the CSV file, loop
through each line and then have to call a route "seda:deleteuser" but want
to keep the original message when this returns. You want to do this
synchronous so everything is in order in the logs (so one user after the
other). The route "seda:deleteuser" does not enrich the message, it actually
does an action on a system (delete a user).
So is it correct to call this route with enrich()?
sim085 wrote
> thanks for pointing this out. This worked fine.
--
View this message in context: http://camel.465427.n5.nabble.
com/How-to-call-a-route-wait-to-finish-and-ignore-any-change
s-when-this-returns-tp5792288p5792341.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: How to call a route, wait to finish, and ignore any changes when
this returns?
Posted by Taariq Levack <ta...@gmail.com>.
In that scenario you might consider multicasting to a route that processes
the deletes in order, as well as to the next/result route.
Just don't process in parallel in that case.
Also, I wouldn't suggest the enricher for each delete like in your example,
perhaps rather route to something that splits and aggregates and then you
might enrich your original exchange with the aggregated result, or
disregard as you did just now.
On 10 Jan 2017 10:15, "sim085" <si...@hotmail.com> wrote:
However thinking out loud ... is this the right way to do it? This is
actually the opposite of message enriching.
It works, I just wonder if it is the right approach.
For example imagine a scenario where you have a CSV file which has a list of
users that have to be deleted from a system. You load the CSV file, loop
through each line and then have to call a route "seda:deleteuser" but want
to keep the original message when this returns. You want to do this
synchronous so everything is in order in the logs (so one user after the
other). The route "seda:deleteuser" does not enrich the message, it actually
does an action on a system (delete a user).
So is it correct to call this route with enrich()?
sim085 wrote
> thanks for pointing this out. This worked fine.
--
View this message in context: http://camel.465427.n5.nabble.
com/How-to-call-a-route-wait-to-finish-and-ignore-any-change
s-when-this-returns-tp5792288p5792341.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: How to call a route, wait to finish, and ignore any changes
when this returns?
Posted by sim085 <si...@hotmail.com>.
However thinking out loud ... is this the right way to do it? This is
actually the opposite of message enriching.
It works, I just wonder if it is the right approach.
For example imagine a scenario where you have a CSV file which has a list of
users that have to be deleted from a system. You load the CSV file, loop
through each line and then have to call a route "seda:deleteuser" but want
to keep the original message when this returns. You want to do this
synchronous so everything is in order in the logs (so one user after the
other). The route "seda:deleteuser" does not enrich the message, it actually
does an action on a system (delete a user).
So is it correct to call this route with enrich()?
sim085 wrote
> thanks for pointing this out. This worked fine.
--
View this message in context: http://camel.465427.n5.nabble.com/How-to-call-a-route-wait-to-finish-and-ignore-any-changes-when-this-returns-tp5792288p5792341.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: How to call a route, wait to finish, and ignore any changes
when this returns?
Posted by sim085 <si...@hotmail.com>.
Hi taariq,
thanks for pointing this out. This worked fine.
[code]
class KeepOriginalAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange original, Exchange resource) {
return original;
}
}
from("seda:A")
.log("Hello From A")
.setHeader("MyHeader", constant("A-HEADER"))
.transform(constant("A-BODY"))
.enrich("seda:B", new KeepOriginalAggregationStrategy())
.log("MyHeader is ${in.header.MyHeader}")
.log("Body is ${body}")
;
from("seda:B")
.log("Hello From B")
.log("MyHeader value frm B is : '${in.header.MyHeader}'")
.setHeader("MyHeader", constant("B-HEADER"))
.transform(constant("B-BODY"))
.log("Ready from B")
;
[/code]
Result:
[(camel-1) thread #0 - seda://A] route2 INFO Hello
From A
[(camel-1) thread #1 - seda://B] route3 INFO Hello
From B
[(camel-1) thread #1 - seda://B] route3 INFO
MyHeader value frm B is : 'A-HEADER'
[(camel-1) thread #1 - seda://B] route3 INFO Ready
from B
[(camel-1) thread #0 - seda://A] route2 INFO
MyHeader is A-HEADER
[(camel-1) thread #0 - seda://A] route2 INFO Body
is A-BODY
--
View this message in context: http://camel.465427.n5.nabble.com/How-to-call-a-route-wait-to-finish-and-ignore-any-changes-when-this-returns-tp5792288p5792339.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: How to call a route, wait to finish, and ignore any changes when
this returns?
Posted by Taariq Levack <ta...@gmail.com>.
Hi,
Content enricher seems like a good fit.
Cheers
On 09 Jan 2017 20:35, "sim085" <si...@hotmail.com> wrote:
Hi Colin,
Thanks for your answer. I tried your example:
[code]
from("seda:A")
.log("Hello From A")
.setHeader("MyHeader", constant("A-HEADER"))
.transform(constant("A-BODY"))
//.inOnly("seda:B")
.process(exchange ->
exchange.getContext().createProducerTemplate().sendBody("seda:B",
exchange.getIn().getBody()))
.log("MyHeader is ${in.header.MyHeader}")
.log("Body is ${body}")
;
from("seda:B")
.log("Hello From B")
.setHeader("MyHeader", constant("B-HEADER"))
.transform(constant("B-BODY"))
.log("Ready from B")
;
[/code]
However this gives me the following:
[(camel-1) thread #0 - seda://A] route2 INFO Hello
From A
[(camel-1) thread #1 - seda://B] route3 INFO Hello
From B
[(camel-1) thread #0 - seda://A] route2 INFO
MyHeader is A-HEADER
[(camel-1) thread #0 - seda://A] route2 INFO Body
is A-BODY
[(camel-1) thread #1 - seda://B] route3 INFO Ready
from B
If I add "?waitForTaskToComplete=Always" when calling "B" I get the correct
answer:
[(camel-1) thread #0 - seda://A] route2 INFO Hello
From A
[(camel-1) thread #0 - seda://A] SedaEndpoint INFO
Endpoint Endpoint[seda://B?waitForTaskToComplete=Always] is using shared
queue: seda://B with size: 2147483647
[(camel-1) thread #1 - seda://B] route3 INFO Hello
From B
[(camel-1) thread #1 - seda://B] route3 INFO Ready
from B
[(camel-1) thread #0 - seda://A] route2 INFO
MyHeader is A-HEADER
[(camel-1) thread #0 - seda://A] route2 INFO Body
is A-BODY
So it looks that like that it works.
Likewise I would like to know if there are more "standard" options - if
any...
--
View this message in context: http://camel.465427.n5.nabble.
com/How-to-call-a-route-wait-to-finish-and-ignore-any-change
s-when-this-returns-tp5792288p5792331.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: How to call a route, wait to finish, and ignore any changes
when this returns?
Posted by sim085 <si...@hotmail.com>.
Hi Colin,
Thanks for your answer. I tried your example:
[code]
from("seda:A")
.log("Hello From A")
.setHeader("MyHeader", constant("A-HEADER"))
.transform(constant("A-BODY"))
//.inOnly("seda:B")
.process(exchange ->
exchange.getContext().createProducerTemplate().sendBody("seda:B",
exchange.getIn().getBody()))
.log("MyHeader is ${in.header.MyHeader}")
.log("Body is ${body}")
;
from("seda:B")
.log("Hello From B")
.setHeader("MyHeader", constant("B-HEADER"))
.transform(constant("B-BODY"))
.log("Ready from B")
;
[/code]
However this gives me the following:
[(camel-1) thread #0 - seda://A] route2 INFO Hello
From A
[(camel-1) thread #1 - seda://B] route3 INFO Hello
From B
[(camel-1) thread #0 - seda://A] route2 INFO
MyHeader is A-HEADER
[(camel-1) thread #0 - seda://A] route2 INFO Body
is A-BODY
[(camel-1) thread #1 - seda://B] route3 INFO Ready
from B
If I add "?waitForTaskToComplete=Always" when calling "B" I get the correct
answer:
[(camel-1) thread #0 - seda://A] route2 INFO Hello
From A
[(camel-1) thread #0 - seda://A] SedaEndpoint INFO
Endpoint Endpoint[seda://B?waitForTaskToComplete=Always] is using shared
queue: seda://B with size: 2147483647
[(camel-1) thread #1 - seda://B] route3 INFO Hello
From B
[(camel-1) thread #1 - seda://B] route3 INFO Ready
from B
[(camel-1) thread #0 - seda://A] route2 INFO
MyHeader is A-HEADER
[(camel-1) thread #0 - seda://A] route2 INFO Body
is A-BODY
So it looks that like that it works.
Likewise I would like to know if there are more "standard" options - if
any...
--
View this message in context: http://camel.465427.n5.nabble.com/How-to-call-a-route-wait-to-finish-and-ignore-any-changes-when-this-returns-tp5792288p5792331.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: How to call a route, wait to finish, and ignore any changes when
this returns?
Posted by Colin Sharples <ct...@ctg.co.nz>.
I just had a very similar situation, which I got round by using a
ProducerTemplate to call the second route. So instead of the inOnly() in
route A, you would have a Processor which invokes route B synchronously,
which will leave the Exchange in route A unaltered. For example:
.transform(constant("A-BODY"))
.process(exchange -> template.sendBody("seda:B", exchange.getIn().getBody()))
.log("MyHeader is ${in.header.MyHeader}")
which produces the following output:
21:40:35.673 [Camel (camel-1) thread #0 - seda://A] INFO route1 - Hello
From A
21:40:35.676 [Camel (camel-1) thread #1 - seda://B] INFO route2 - Hello
From B
21:40:35.676 [Camel (camel-1) thread #1 - seda://B] INFO route2 - Ready
from B
21:40:35.676 [Camel (camel-1) thread #0 - seda://A] INFO route1 -
MyHeader is A-HEADER
21:40:35.677 [Camel (camel-1) thread #0 - seda://A] INFO route1 - Body
is A-BODY
Happy for someone to point out a better way, but this worked for me.
-- ctg
On 9/01/2017 12:48 p.m., sim085 wrote:
> Hello,
>
> I have a route "A" which calls a route "B", route "B" adds some headers,
> removes some others, changes the body, etc. Is there a way how I can call
> route "B" from route "A", wait for route "B" to finish and once route "B"
> returns, route "A" will be in the same state as before calling route "B"
> (i.e. - same headers, same body)?
>
> I tried using the SEDA component with the "waitForTaskToComplete" set to
> "Always" but this does not seem to work, i.e. - if I use
> InOnly("seda:B?waitForTaskToComplete=Always") then this works as if calling
> the SEDA component with inOut(...).
>
> For example:
>
> [code]
> from("seda:A")
> .log("Hello From A")
> .setHeader("MyHeader", constant("A-HEADER"))
> .transform(constant("A-BODY"))
> .inOnly("seda:B?waitForTaskToComplete=Always")
> .log("MyHeader is ${in.header.MyHeader}")
> .log("Body is ${body}")
> ;
>
> from("seda:B")
> .log("Hello From B")
> .setHeader("MyHeader", constant("B-HEADER"))
> .transform(constant("B-BODY"))
> .log("Ready from B")
> ;
> [/code]
>
> Will Print:
>
> [(camel-1) thread #0 - seda://A] route2 INFO Hello
> >From A
> [(camel-1) thread #1 - seda://B] route3 INFO Hello
> >From B
> [(camel-1) thread #1 - seda://B] route3 INFO Ready
> from B
> [(camel-1) thread #0 - seda://A] route2 INFO
> MyHeader is B-HEADER
> [(camel-1) thread #0 - seda://A] route2 INFO Body
> is B-BODY
>
> I was under the impression that calling seda:B with InOnly would force the
> component not to return however it seems that waitForTaskToComplete=Always
> makes it work like InOut rather than just wait for the task to complete.
>
> Is there a way how I can achieve the above? i.e. - call a route, wait for
> this to finish, but message from the caller route (in my case "A") remains
> the same as before calling the second route.
>
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/How-to-call-a-route-wait-to-finish-and-ignore-any-changes-when-this-returns-tp5792288.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>
>