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.
>
>
>