Hi,
I’ve tried this solution:
I started by developing a processor that loops on URIs until getting a valid
answer.
The only problem is my route is interrupted at the end of the first
processing, so no way to pass from first block (addressA) to next block
(AddressB).
The process() method loops on all URI until getting the valid URI. This
works but after that I got a fatal error and the route flow was interrupted.
Below the error I got on ServiceMix console:
----------------
FATAL - DeadLetterChannel - Failed delivery for exchangeId:
ID-ROME/1982-1242375956166/0-4. Handled by the failure processor:
sendTo(Endpoint[direct:deadLetterChannel])
15 mai 2009 09:32:37 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
INFO: Interceptor has thrown exception, unwinding now
org.apache.xerces.dom.TextImpl
----------------
Here is my Camel route:
* //Declare Deadletter processor*
*errorHandler(deadLetterChannel("direct:letter").onRedelivery(myProcessor));
*
* //Declare global exception*
*onException(Exception.class).maximumRedeliveries(5) //5 : because I have 5
address maximum to call*
*final Processor myprocessor() = new Processor(Exchange exchange) throws
Exception{*
**
*ProducerTemplate<Exchange> template
exchange.getContext().createProducerTemplate();
String uri = exchange.getIn().getHeader(HttpProducer.**HTTP_URI).toString();
*
*//This method returns the valid list depending on the current http URI*
*List<Strig> uris = getUriList(uri);*
*for (String uri : uris) {*
* try {*
* template.send(uri, exchange);*
* } catch (Exception e) {*
* exchange.setExceptipn(e);*
* }*
* if (exchange.getException() == null) {*
* return;
}
}
}*
* *
*from("direct:endpointA")
.setHeader(HttpProducer.HTTP_URI).simple("http://myAddressA")
.process(myUrlLookerProcessor())
.to("direct:endPointB")*
*from("direct:endpointB")
.setHeader(HttpProducer.HTTP_URI).simple("http://myAddressB")
.process(myUrlLookerProcessor())
.to("direct:endPointC")*
*
from("direct:endPointC")
.to("xquery:response.xml");*
*from("direct:letter")
.to("log:dead_letterChannel?showHeaders=true&level=DEBUG");*
Thanks in advance for help.
Nasmo
On Fri, May 15, 2009 at 9:41 AM, Claus Ibsen <[email protected]> wrote:
> Hi
>
> BTW You can also always just use a Processor and implement the
> failover logic yourself as pure Java with try .. catch and use the
> ProducerTemplate to send the exchange to the endpoint based on the
> URI.
>
> Something like
> ProducerTemplate template = // get it from CamelContext and get it once
> List<Strig> uris = ...
>
> for (String uri : uris) {
> try {
> template.send(uri, exchange);
> } catch (Exception e) {
> exchange.setExceptipn(e);
> }
> if (exchange.getException() == null) {
> return;
> }
> }
>
>
> On Thu, May 14, 2009 at 6:19 PM, Claus Ibsen <[email protected]>
> wrote:
> > On Thu, May 14, 2009 at 4:55 PM, Nasim Anza <[email protected]>
> wrote:
> >> Thanks Claus for your quick answer.
> >>
> >> I downloaded the source of camel 2.0 and I looked at the
> >> FailOverLoadBalancer class. I think that this could answer to my
> question.
> >> I've tried to adapt the code to my requirement but I have some questions
> >> about the list of processors used in this class :
> >>
> >> 1. I don't know How to create or initialize the processors used for
> >> balancing user requests ?
> >>
> >> 2. Shall I create a camel Processor for each HTTP URL ?
> >>
> >> 3. Whait is the syntaxe (maybe something like new Processor(myHttpURL))
> > Hi
> >
> > Yeah there is no nice DSL support for it and the loadbalance() DSL
> > does not have a nice support for custom load balancer.
> > So that is something we might need to improve in the future. I have to
> > remember this thread.
> >
> > So what you basically have to do is to add your custom load balancer
> > as a processor, so use the process() DSL.
> >
> > And your custom fail over loadbalancer can accept a list of endpoints
> > to select among. You can wrap an endpoint to a processor
> > with the SendToProcessor.
> >
> > Something like this
> >
> > MyFailover my = new MyFailoverProcessor()l;
> > my.addEndpoint("foo");
> > my.addEndpoint("bar");
> >
> >
> > And in the route DSL you just route to your processor
> > from(x).process(my);
> >
> > And in the addEndpoint method you add the endpoint by wrapping it with
> > a SendToProcessor so you can add it to the LoadBalancerSupport class.
> >
> > See how it goes and ask again tomorrow when I am back in the office
> > and can better work. As I sit now with the laptop in the living room.
> >
> >
> >>
> >> Thanks for help
> >>
> >>
> >>
> >>
> >> On Thu, May 14, 2009 at 11:59 AM, Claus Ibsen <[email protected]>
> wrote:
> >>
> >>> Hi
> >>>
> >>> There are load balancers with Camel
> >>> http://camel.apache.org/load-balancer.html
> >>>
> >>> And there is a failover load balancer as well that can do a simple try
> >>> the next endpoint until success kinda style.
> >>> Its a bit primitive at the moment and we would like to improve that in
> >>> the future.
> >>>
> >>> But it allows you to implement your own load balancer and do your
> >>> strategy how you like it.
> >>>
> >>> Any feedback for features that could be needed for a more advanced
> >>> failover loadbalancer is much welcome.
> >>>
> >>> Ah the failover loadbalancer is not part of Camel 1.x. But you can
> >>> check the source code for 2.0 and create your own kinda to use in 1.x.
> >>>
> >>>
> https://svn.apache.org/repos/asf/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/loadbalancer/
> >>>
> >>>
> >>>
> >>> On Thu, May 14, 2009 at 11:45 AM, Nasim Anza <[email protected]
> >
> >>> wrote:
> >>> > Hi,
> >>> >
> >>> > I would like to implement the following route with Camel 1.6 :
> >>> >
> >>> > from("direct:endpointA")
> >>> > .setHeader(HttpProducer.HTTP_URI).simple("http://myAddressA")
> >>> > .to("http://xxxxxx")
> >>> > .to("direct:endPointB")
> >>> >
> >>> > from("direct:endpointB")
> >>> > .setHeader(HttpProducer.HTTP_URI).simple("http://myAddressB")
> >>> > .to("http://xxxxxx")
> >>> > .to("direct:endPointC")
> >>> >
> >>> > from("direct:endPointC")
> >>> > .to("xquery:response.xml");
> >>> >
> >>> > This route works fine if both URLs : http://myAddressA and
> >>> > http://myAddressBare accessible and no error occurs during the
> >>> > invocation.
> >>> > Unfortunately, sometimes these services become unreachable and I
> would
> >>> like
> >>> > to try other URLs until getting valid answer:
> >>> >
> >>> > If an exception happens when calling the URL http:/:myAddressA, I
> would
> >>> like
> >>> > to attempt other URLs : myAddressA1, myAddressA2, ...until getting
> valid
> >>> > HTTP response.
> >>> > The same thing with myAddressB ==> myAddressB1, myAddressB2, ...
> >>> >
> >>> > With java this could be simply coded like following :
> >>> >
> >>> > try
> >>> > {
> >>> > call_http(myAddressA)
> >>> > }
> >>> > catch(Throwable th)
> >>> > {
> >>> > try
> >>> > {
> >>> > call_http(myAddressA1)
> >>> > }
> >>> > catch(Exception x)
> >>> > {
> >>> > //Call addressA2
> >>> > ....
> >>> > }
> >>> > }
> >>> >
> >>> > I've tried the onException() mechanism and the deadLetterChannel
> >>> processor
> >>> > but I never get working my route.
> >>> >
> >>>
> >>>
> >>>
> >>> --
> >>> Claus Ibsen
> >>> Apache Camel Committer
> >>>
> >>> Open Source Integration: http://fusesource.com
> >>> Blog: http://davsclaus.blogspot.com/
> >>> Twitter: http://twitter.com/davsclaus
> >>>
> >>
> >
> >
> >
> > --
> > Claus Ibsen
> > Apache Camel Committer
> >
> > Open Source Integration: http://fusesource.com
> > Blog: http://davsclaus.blogspot.com/
> > Twitter: http://twitter.com/davsclaus
> >
>
>
>
> --
> Claus Ibsen
> Apache Camel Committer
>
> Open Source Integration: http://fusesource.com
> Blog: http://davsclaus.blogspot.com/
> Twitter: http://twitter.com/davsclaus
>