You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by jelmer <jk...@gmail.com> on 2016/03/02 21:27:28 UTC
Polling http endpoints
Hi as part of a camel route i upload a file to a REST service, the service
will return status 202 and a Content-Location header that points to a json
resource with a status field
i want to wait for the status of this resource to change to completed, and
only then continue. so i need some sort of polling
But i don't see an obvious way to do this in camel
can anyone offer any suggestions?
Re: Polling http endpoints
Posted by Claus Ibsen <cl...@gmail.com>.
On Mon, Mar 7, 2016 at 4:23 PM, Quinn Stevenson
<qu...@pronoia-solutions.com> wrote:
> Sorry - I forgot that the loop DSL doesn’t take a predicate.
>
Yeah its been talked about from time to time about this need.
I have logged a ticket
https://issues.apache.org/jira/browse/CAMEL-9675
> How about this - configure redelivery handling on your main route, and then have the direct route throw an exception if the payload isn’t ready.
>
> Here’s a mocked example:
> public class MyRouteBuilder extends RouteBuilder {
> Processor responseProcessor = new ResponseProcessor();
>
> public void configure() {
> onException(MyException.class)
> .logRetryAttempted(true)
> .retryAttemptedLogLevel(LoggingLevel.INFO)
> .redeliveryDelay(2000)
> .retryWhile(exchangeProperty(ResponseProcessor.RESPONSE_PROPERTY).isNotEqualTo(true))
> ;
>
> fromF("timer://%s?period=%d", "my-timer", 5000)
> .log("Waiting for processor")
> .to( "direct://wait-for-response")
> .to("mock://complete")
> ;
>
> from("direct://wait-for-response")
> .errorHandler(noErrorHandler())
> .log( "looking for response")
> .process(responseProcessor)
> .choice()
> .when( exchangeProperty(ResponseProcessor.RESPONSE_PROPERTY).isNotEqualTo( true ) )
> .throwException( MyException.class, "Not Ready" )
> .otherwise()
> .end()
> ;
> }
>
> }
> My simple processor just sets an exchange property - nothing fancy but hopefully it illustrates what I’m suggesting.
>
>> On Mar 6, 2016, at 6:18 AM, jelmer <jk...@gmail.com> wrote:
>>
>> It does not look like loop takes a predicate, it expects the expression to
>> be a number, which i think makes it unsuited for this sort of thing.
>>
>> I would this expect this to be a fairly common case, i am surprised its
>> this difficult to figure out how to do this
>>
>> On 4 March 2016 at 16:25, Quinn Stevenson <qu...@pronoia-solutions.com>
>> wrote:
>>
>>> The “direct:await-import-complete” calling itself makes me a little
>>> nervous - the call stack could get pretty deep if it has to wait very long.
>>>
>>> Could you use the loop DSL (http://camel.apache.org/loop.html <
>>> http://camel.apache.org/loop.html>)?
>>>
>>>
>>>> On Mar 3, 2016, at 11:44 AM, jelmer <jk...@gmail.com> wrote:
>>>>
>>>> Since no one answered I came up with this :
>>>>
>>>> from("file:/Users/jkuperus/foo")
>>>> .process(ToMultiPartRequestProcessor)
>>>> .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST))
>>>> .setHeader(Exchange.CONTENT_TYPE, constant("multipart/form-data"))
>>>> .setHeader(Exchange.HTTP_PATH, constant("/api/tasks"))
>>>> .to("http4://localhost:11380")
>>>> .transform().header("Content-Location")
>>>> .to("direct:await-import-complete")
>>>>
>>>>
>>>> from("direct:await-import-complete")
>>>> .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
>>>> .setHeader(Exchange.HTTP_PATH, body().convertToString())
>>>> .to("http4://localhost:11380")
>>>> .transform(body().convertToString())
>>>> .choice()
>>>> .when().jsonpath("[?(@.state == 'completed')]")
>>>> .transform().jsonpath("@.campaignId")
>>>> .to("direct:do-stuff")
>>>> .otherwise()
>>>> .log("Task was not yet completed retrying in 2 seconds")
>>>> .delay(2000)
>>>> .transform().header(Exchange.HTTP_PATH)
>>>> .to("direct:await-import-complete")
>>>>
>>>>
>>>> Does this make any sense ?
>>>>
>>>> On 2 March 2016 at 21:27, jelmer <jk...@gmail.com> wrote:
>>>>
>>>>> Hi as part of a camel route i upload a file to a REST service, the
>>> service
>>>>> will return status 202 and a Content-Location header that points to a
>>> json
>>>>> resource with a status field
>>>>> i want to wait for the status of this resource to change to completed,
>>> and
>>>>> only then continue. so i need some sort of polling
>>>>> But i don't see an obvious way to do this in camel
>>>>> can anyone offer any suggestions?
>>>>>
>>>
>>>
>
--
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2
Re: Polling http endpoints
Posted by Quinn Stevenson <qu...@pronoia-solutions.com>.
Sorry - I forgot that the loop DSL doesn’t take a predicate.
How about this - configure redelivery handling on your main route, and then have the direct route throw an exception if the payload isn’t ready.
Here’s a mocked example:
public class MyRouteBuilder extends RouteBuilder {
Processor responseProcessor = new ResponseProcessor();
public void configure() {
onException(MyException.class)
.logRetryAttempted(true)
.retryAttemptedLogLevel(LoggingLevel.INFO)
.redeliveryDelay(2000)
.retryWhile(exchangeProperty(ResponseProcessor.RESPONSE_PROPERTY).isNotEqualTo(true))
;
fromF("timer://%s?period=%d", "my-timer", 5000)
.log("Waiting for processor")
.to( "direct://wait-for-response")
.to("mock://complete")
;
from("direct://wait-for-response")
.errorHandler(noErrorHandler())
.log( "looking for response")
.process(responseProcessor)
.choice()
.when( exchangeProperty(ResponseProcessor.RESPONSE_PROPERTY).isNotEqualTo( true ) )
.throwException( MyException.class, "Not Ready" )
.otherwise()
.end()
;
}
}
My simple processor just sets an exchange property - nothing fancy but hopefully it illustrates what I’m suggesting.
> On Mar 6, 2016, at 6:18 AM, jelmer <jk...@gmail.com> wrote:
>
> It does not look like loop takes a predicate, it expects the expression to
> be a number, which i think makes it unsuited for this sort of thing.
>
> I would this expect this to be a fairly common case, i am surprised its
> this difficult to figure out how to do this
>
> On 4 March 2016 at 16:25, Quinn Stevenson <qu...@pronoia-solutions.com>
> wrote:
>
>> The “direct:await-import-complete” calling itself makes me a little
>> nervous - the call stack could get pretty deep if it has to wait very long.
>>
>> Could you use the loop DSL (http://camel.apache.org/loop.html <
>> http://camel.apache.org/loop.html>)?
>>
>>
>>> On Mar 3, 2016, at 11:44 AM, jelmer <jk...@gmail.com> wrote:
>>>
>>> Since no one answered I came up with this :
>>>
>>> from("file:/Users/jkuperus/foo")
>>> .process(ToMultiPartRequestProcessor)
>>> .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST))
>>> .setHeader(Exchange.CONTENT_TYPE, constant("multipart/form-data"))
>>> .setHeader(Exchange.HTTP_PATH, constant("/api/tasks"))
>>> .to("http4://localhost:11380")
>>> .transform().header("Content-Location")
>>> .to("direct:await-import-complete")
>>>
>>>
>>> from("direct:await-import-complete")
>>> .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
>>> .setHeader(Exchange.HTTP_PATH, body().convertToString())
>>> .to("http4://localhost:11380")
>>> .transform(body().convertToString())
>>> .choice()
>>> .when().jsonpath("[?(@.state == 'completed')]")
>>> .transform().jsonpath("@.campaignId")
>>> .to("direct:do-stuff")
>>> .otherwise()
>>> .log("Task was not yet completed retrying in 2 seconds")
>>> .delay(2000)
>>> .transform().header(Exchange.HTTP_PATH)
>>> .to("direct:await-import-complete")
>>>
>>>
>>> Does this make any sense ?
>>>
>>> On 2 March 2016 at 21:27, jelmer <jk...@gmail.com> wrote:
>>>
>>>> Hi as part of a camel route i upload a file to a REST service, the
>> service
>>>> will return status 202 and a Content-Location header that points to a
>> json
>>>> resource with a status field
>>>> i want to wait for the status of this resource to change to completed,
>> and
>>>> only then continue. so i need some sort of polling
>>>> But i don't see an obvious way to do this in camel
>>>> can anyone offer any suggestions?
>>>>
>>
>>
Re: Polling http endpoints
Posted by jelmer <jk...@gmail.com>.
It does not look like loop takes a predicate, it expects the expression to
be a number, which i think makes it unsuited for this sort of thing.
I would this expect this to be a fairly common case, i am surprised its
this difficult to figure out how to do this
On 4 March 2016 at 16:25, Quinn Stevenson <qu...@pronoia-solutions.com>
wrote:
> The “direct:await-import-complete” calling itself makes me a little
> nervous - the call stack could get pretty deep if it has to wait very long.
>
> Could you use the loop DSL (http://camel.apache.org/loop.html <
> http://camel.apache.org/loop.html>)?
>
>
> > On Mar 3, 2016, at 11:44 AM, jelmer <jk...@gmail.com> wrote:
> >
> > Since no one answered I came up with this :
> >
> > from("file:/Users/jkuperus/foo")
> > .process(ToMultiPartRequestProcessor)
> > .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST))
> > .setHeader(Exchange.CONTENT_TYPE, constant("multipart/form-data"))
> > .setHeader(Exchange.HTTP_PATH, constant("/api/tasks"))
> > .to("http4://localhost:11380")
> > .transform().header("Content-Location")
> > .to("direct:await-import-complete")
> >
> >
> > from("direct:await-import-complete")
> > .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
> > .setHeader(Exchange.HTTP_PATH, body().convertToString())
> > .to("http4://localhost:11380")
> > .transform(body().convertToString())
> > .choice()
> > .when().jsonpath("[?(@.state == 'completed')]")
> > .transform().jsonpath("@.campaignId")
> > .to("direct:do-stuff")
> > .otherwise()
> > .log("Task was not yet completed retrying in 2 seconds")
> > .delay(2000)
> > .transform().header(Exchange.HTTP_PATH)
> > .to("direct:await-import-complete")
> >
> >
> > Does this make any sense ?
> >
> > On 2 March 2016 at 21:27, jelmer <jk...@gmail.com> wrote:
> >
> >> Hi as part of a camel route i upload a file to a REST service, the
> service
> >> will return status 202 and a Content-Location header that points to a
> json
> >> resource with a status field
> >> i want to wait for the status of this resource to change to completed,
> and
> >> only then continue. so i need some sort of polling
> >> But i don't see an obvious way to do this in camel
> >> can anyone offer any suggestions?
> >>
>
>
Re: Polling http endpoints
Posted by Quinn Stevenson <qu...@pronoia-solutions.com>.
The “direct:await-import-complete” calling itself makes me a little nervous - the call stack could get pretty deep if it has to wait very long.
Could you use the loop DSL (http://camel.apache.org/loop.html <http://camel.apache.org/loop.html>)?
> On Mar 3, 2016, at 11:44 AM, jelmer <jk...@gmail.com> wrote:
>
> Since no one answered I came up with this :
>
> from("file:/Users/jkuperus/foo")
> .process(ToMultiPartRequestProcessor)
> .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST))
> .setHeader(Exchange.CONTENT_TYPE, constant("multipart/form-data"))
> .setHeader(Exchange.HTTP_PATH, constant("/api/tasks"))
> .to("http4://localhost:11380")
> .transform().header("Content-Location")
> .to("direct:await-import-complete")
>
>
> from("direct:await-import-complete")
> .setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
> .setHeader(Exchange.HTTP_PATH, body().convertToString())
> .to("http4://localhost:11380")
> .transform(body().convertToString())
> .choice()
> .when().jsonpath("[?(@.state == 'completed')]")
> .transform().jsonpath("@.campaignId")
> .to("direct:do-stuff")
> .otherwise()
> .log("Task was not yet completed retrying in 2 seconds")
> .delay(2000)
> .transform().header(Exchange.HTTP_PATH)
> .to("direct:await-import-complete")
>
>
> Does this make any sense ?
>
> On 2 March 2016 at 21:27, jelmer <jk...@gmail.com> wrote:
>
>> Hi as part of a camel route i upload a file to a REST service, the service
>> will return status 202 and a Content-Location header that points to a json
>> resource with a status field
>> i want to wait for the status of this resource to change to completed, and
>> only then continue. so i need some sort of polling
>> But i don't see an obvious way to do this in camel
>> can anyone offer any suggestions?
>>
Re: Polling http endpoints
Posted by jelmer <jk...@gmail.com>.
Since no one answered I came up with this :
from("file:/Users/jkuperus/foo")
.process(ToMultiPartRequestProcessor)
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST))
.setHeader(Exchange.CONTENT_TYPE, constant("multipart/form-data"))
.setHeader(Exchange.HTTP_PATH, constant("/api/tasks"))
.to("http4://localhost:11380")
.transform().header("Content-Location")
.to("direct:await-import-complete")
from("direct:await-import-complete")
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
.setHeader(Exchange.HTTP_PATH, body().convertToString())
.to("http4://localhost:11380")
.transform(body().convertToString())
.choice()
.when().jsonpath("[?(@.state == 'completed')]")
.transform().jsonpath("@.campaignId")
.to("direct:do-stuff")
.otherwise()
.log("Task was not yet completed retrying in 2 seconds")
.delay(2000)
.transform().header(Exchange.HTTP_PATH)
.to("direct:await-import-complete")
Does this make any sense ?
On 2 March 2016 at 21:27, jelmer <jk...@gmail.com> wrote:
> Hi as part of a camel route i upload a file to a REST service, the service
> will return status 202 and a Content-Location header that points to a json
> resource with a status field
> i want to wait for the status of this resource to change to completed, and
> only then continue. so i need some sort of polling
> But i don't see an obvious way to do this in camel
> can anyone offer any suggestions?
>