You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by John <Jo...@ateb.com> on 2010/12/10 22:10:07 UTC

route scoped onException

Hi,

I'm using camel 2.2 to create an aggregation route with an onException.
Unfortunately it appears the onException.end() and
aggregate().groupExchanges() are exclusive? I know the .end() is required on
the onException, but adding it causes the groupExchanges to warn "the method
groupExchanges is undefined for the type Object".

Here's my route:

        from(activemq:somequeue)
            .routeId("myRoute")
           
.onException(ConnectException.class).maximumRedeliveries(-1).redeliverDelay(30000)
            .aggregate().constant(true).groupExchanges().batchTimeout(5000)
                .beanRef("processAggregationBean")
                .to("http://some_web_service");

How can I use onException in this route?

Thanks,

-john
-- 
View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3300994.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: route scoped onException

Posted by Claus Ibsen <cl...@gmail.com>.
On Mon, Dec 20, 2010 at 3:30 PM, John <Jo...@ateb.com> wrote:
>
> Thanks Claus. Though I didn't understand why, I had already come to the
> realization that I had to check the exchange headers directly in the
> processor.
>
> Now for hopefully my last question on this issue.
>
> My route builder has two similar routes that communicate with web services,
> so I have two separate onExceptions defined in the two different routes.
> This seems to break my onException unit tests.
>
> I believe I recreated the issue by adding a second route to your test:
>
> RouteScopedOnExceptionWithInterceptSendToEndpointIssueWithPredicateTest
>
> I just added
>
>                from("direct:start2")
>                // no redelivery delay for faster unit tests
>
> .onException(ConnectException.class).maximumRedeliveries(5).redeliveryDelay(0)
>
> .logRetryAttempted(true).retryAttemptedLogLevel(LoggingLevel.WARN)
>                // send to mock when we are exhausted
>                .to("mock:exhausted")
>                .end()
>                .to("seda:bar");
>
> below the first route. I believe this second route should be innocuous and
> never get exercised.
>

Ah well spotted. Its in fact a bug, when you are using the same class
type in onException on route scope.

I will get this fixed
https://issues.apache.org/jira/browse/CAMEL-3448


> Thanks again for all of your help,
>
> -john
> --
> View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3312060.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



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

Re: route scoped onException

Posted by John <Jo...@ateb.com>.
Thanks Claus. Though I didn't understand why, I had already come to the
realization that I had to check the exchange headers directly in the
processor.

Now for hopefully my last question on this issue. 

My route builder has two similar routes that communicate with web services,
so I have two separate onExceptions defined in the two different routes.
This seems to break my onException unit tests.

I believe I recreated the issue by adding a second route to your test:

RouteScopedOnExceptionWithInterceptSendToEndpointIssueWithPredicateTest

I just added

                from("direct:start2")
                // no redelivery delay for faster unit tests
               
.onException(ConnectException.class).maximumRedeliveries(5).redeliveryDelay(0)
               
.logRetryAttempted(true).retryAttemptedLogLevel(LoggingLevel.WARN)
                // send to mock when we are exhausted
                .to("mock:exhausted")
                .end()
                .to("seda:bar");

below the first route. I believe this second route should be innocuous and
never get exercised.

Thanks again for all of your help,

-john
-- 
View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3312060.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: route scoped onException

Posted by Claus Ibsen <cl...@gmail.com>.
On Thu, Dec 16, 2010 at 9:09 PM, John <Jo...@ateb.com> wrote:
>
> I'm now working off 2.6-SNAPSHOT.
>
> To get around the onException/aggregate.groupBy DSL warning AND put the
> onException at the start of the route, I moved the actual send to the web
> service to it's own route. Unfortunately, I don't seem to be able to trigger
> the onException handling while testing the route. The global error handler
> kicks in after the 5 retries it is configured for.
>
> Am I doing something wrong with my onException configuration in the route?
> The code is below.
>
> Thanks,
>
> -john
>
>    errorHandler(deadLetterChannel("direct:emailSupport")
>        .maximumRedeliveries(5)
>        .redeliveryDelay(1000)
>        .backOffMultiplier(2)
>        .retryAttemptedLogLevel(LoggingLevel.WARN));
>
>    from("direct.sendToWs")
>        .routeId("sendToWs")
>
> .onException(java.net.ConnectException.class).maximumRedeliveries(-1).redeliveryDelay(30000).end()
>        .to("http:host//some_ws");
>
> In my test I created an interceptor like:
>
>    Predicate p1 = header(Exchange.REDELIVERY_COUNTER).isLessThan(7);
>    Predicate p =
> PredicateBuilder.or(header(Exchange.REDELIVERY_COUNTER).isNull(), p1);
>
>    interceptSendToEndpoint("http*")
>        .skipSendToOriginalEndpoint()
>        .choice()
>            .when(p)
>                .process(new Processor()
>                {
>                    public void process(Exchange exchange) throws Exception
>                    {
>                        System.out.println("---------------- throw
> ConnectException");
>                        throw new java.net.ConnectException();
>                    }
>                })
>            .otherwise()
>                .log("--------------- sending it on")
>                .to(postingAcceptWsEndpoint);
>

Ah I spotted it now. When Camel performs a redelivery its at *the
point of original* so it happens in the intercepted route. So what
happens is that it will just retry invoking that process method on
Processor because it threw the exception. It does not start all over
again, which means that the logic in the choice / when is not executed
on redelivery.

You will have to put that logic *inside* the Processor because that
being invoked again on redelivery attempts.

See the following unit tests added
http://svn.apache.org/viewvc?rev=1050690&view=rev
http://svn.apache.org/viewvc?rev=1050691&view=rev


> --
> View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3308494.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



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

Re: route scoped onException

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

How do you use the interceptSendToEndpoint in your test?
Do you use adviceWith ?

Can you post how you do that?


On Thu, Dec 16, 2010 at 9:09 PM, John <Jo...@ateb.com> wrote:
>
> I'm now working off 2.6-SNAPSHOT.
>
> To get around the onException/aggregate.groupBy DSL warning AND put the
> onException at the start of the route, I moved the actual send to the web
> service to it's own route. Unfortunately, I don't seem to be able to trigger
> the onException handling while testing the route. The global error handler
> kicks in after the 5 retries it is configured for.
>
> Am I doing something wrong with my onException configuration in the route?
> The code is below.
>
> Thanks,
>
> -john
>
>    errorHandler(deadLetterChannel("direct:emailSupport")
>        .maximumRedeliveries(5)
>        .redeliveryDelay(1000)
>        .backOffMultiplier(2)
>        .retryAttemptedLogLevel(LoggingLevel.WARN));
>
>    from("direct.sendToWs")
>        .routeId("sendToWs")
>
> .onException(java.net.ConnectException.class).maximumRedeliveries(-1).redeliveryDelay(30000).end()
>        .to("http:host//some_ws");
>
> In my test I created an interceptor like:
>
>    Predicate p1 = header(Exchange.REDELIVERY_COUNTER).isLessThan(7);
>    Predicate p =
> PredicateBuilder.or(header(Exchange.REDELIVERY_COUNTER).isNull(), p1);
>
>    interceptSendToEndpoint("http*")
>        .skipSendToOriginalEndpoint()
>        .choice()
>            .when(p)
>                .process(new Processor()
>                {
>                    public void process(Exchange exchange) throws Exception
>                    {
>                        System.out.println("---------------- throw
> ConnectException");
>                        throw new java.net.ConnectException();
>                    }
>                })
>            .otherwise()
>                .log("--------------- sending it on")
>                .to(postingAcceptWsEndpoint);
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3308494.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



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

Re: route scoped onException

Posted by John <Jo...@ateb.com>.
I'm now working off 2.6-SNAPSHOT.

To get around the onException/aggregate.groupBy DSL warning AND put the
onException at the start of the route, I moved the actual send to the web
service to it's own route. Unfortunately, I don't seem to be able to trigger
the onException handling while testing the route. The global error handler
kicks in after the 5 retries it is configured for.

Am I doing something wrong with my onException configuration in the route?
The code is below.

Thanks,

-john

    errorHandler(deadLetterChannel("direct:emailSupport")
        .maximumRedeliveries(5)
        .redeliveryDelay(1000)
        .backOffMultiplier(2)
        .retryAttemptedLogLevel(LoggingLevel.WARN));

    from("direct.sendToWs")
        .routeId("sendToWs")
       
.onException(java.net.ConnectException.class).maximumRedeliveries(-1).redeliveryDelay(30000).end()
        .to("http:host//some_ws");

In my test I created an interceptor like:

    Predicate p1 = header(Exchange.REDELIVERY_COUNTER).isLessThan(7);
    Predicate p =
PredicateBuilder.or(header(Exchange.REDELIVERY_COUNTER).isNull(), p1);
                
    interceptSendToEndpoint("http*")
        .skipSendToOriginalEndpoint()
        .choice()
            .when(p)
                .process(new Processor()
                {
                    public void process(Exchange exchange) throws Exception
                    {
                        System.out.println("---------------- throw
ConnectException");
                        throw new java.net.ConnectException();
                    }
                })
            .otherwise()
                .log("--------------- sending it on")
                .to(postingAcceptWsEndpoint);

-- 
View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3308494.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: route scoped onException

Posted by John <Jo...@ateb.com>.
Hi Claus,

As Ashwin pointed out, I'm really trying to use the onException to manage
retries to the web service. The aggregation collects requests together, then
calls a bean to create the web service call with all the aggregated
messages.

The problem I ran hit was that putting the onException before the
aggregation in the route causes issues with "groupExchanges".

If I'm allowed to use the route that Ashwin suggested, the DSL errors go
away.

Thanks,

-john
-- 
View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3303109.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: route scoped onException

Posted by Claus Ibsen <cl...@gmail.com>.
On Fri, Dec 10, 2010 at 10:10 PM, John <Jo...@ateb.com> wrote:
>
> Hi,
>
> I'm using camel 2.2 to create an aggregation route with an onException.
> Unfortunately it appears the onException.end() and
> aggregate().groupExchanges() are exclusive? I know the .end() is required on
> the onException, but adding it causes the groupExchanges to warn "the method
> groupExchanges is undefined for the type Object".
>
> Here's my route:
>
>        from(activemq:somequeue)
>            .routeId("myRoute")
>
> .onException(ConnectException.class).maximumRedeliveries(-1).redeliverDelay(30000)
>            .aggregate().constant(true).groupExchanges().batchTimeout(5000)
>                .beanRef("processAggregationBean")
>                .to("http://some_web_service");
>
> How can I use onException in this route?
>

Is the aggregate part of the onException or not?

Add .end() where you want the onException to end.


> Thanks,
>
> -john
> --
> View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3300994.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



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

Re: route scoped onException

Posted by Claus Ibsen <cl...@gmail.com>.
On Sun, Dec 12, 2010 at 6:55 AM, John <Jo...@ateb.com> wrote:
>
> Thanks Ashwin. I'll give that a shot. I thought I had read where onException
> had to be at the start of the route, so I didn't realize I could place it
> there.

No you should not put onException inside the route. Its supposed to be
in the start of the route.
In Camel 3.0 we will tighten this up so the DSL don't allow this.


> --
> View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3301973.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



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

Re: route scoped onException

Posted by John <Jo...@ateb.com>.
Thanks Ashwin. I'll give that a shot. I thought I had read where onException
had to be at the start of the route, so I didn't realize I could place it
there.
-- 
View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3301973.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: route scoped onException

Posted by Ashwin Karpe <ak...@fusesource.com>.
Hi,

A ConnectException is really meant to catch exceptions encountered when you
send your request to a web service.

You can do the following without side-effects and only apply this to the web
service producer.

         from(activemq:somequeue) 
            .routeId("myRoute")  
            .aggregate().constant(true).groupExchanges().batchTimeout(5000) 
                .beanRef("processAggregationBean")
               
.onException(ConnectException.class).maximumRedeliveries(-1).redeliverDelay(30000).end() 
                .to("http://some_web_service"); 

Cheers,

Ashwin...

-----
---------------------------------------------------------
Ashwin Karpe
Apache Camel Committer & Sr Principal Consultant
FUSESource (a Progress Software Corporation subsidiary)
http://fusesource.com http://fusesource.com 

Blog: http://opensourceknowledge.blogspot.com
http://opensourceknowledge.blogspot.com 
---------------------------------------------------------
-- 
View this message in context: http://camel.465427.n5.nabble.com/route-scoped-onException-tp3300994p3301524.html
Sent from the Camel - Users mailing list archive at Nabble.com.