camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Claus Ibsen <claus.ib...@gmail.com>
Subject Re: Calling dynamically multiple http endpoints
Date Fri, 15 May 2009 11:00:40 GMT
On Fri, May 15, 2009 at 11:58 AM, Nasim Anza <nasmo2009@googlemail.com> wrote:
> I I understood, the route should be similar to the folllowing :
>
> from("direct:endpointA")
> .setHeader(HttpProducer.HTTP_URI).simple("http://myAddressA<http://myaddressa/>
> ")
> .process(myFailOverProcessor("direct:endPointB"));
>
> from("direct:endpointB")
> .setHeader(HttpProducer.HTTP_URI).simple("http://myAddressB<http://myaddressa/>
> ")
> .process(myFailOverProcessor("direct:endPointC"));
>
> from("direct:endPointC")
> .to("xquery:response.xml");*
>
> I added a constructor with the name of the next endpoint to which the result
> will be sent at the end of the failOverProcessor.process and the code to
> send exchange to the next endpoint:
>
> //After finding valid URL, we send the exchange to the next endpoint
>  if(endpoint != null)
>   {
>            ProducerTemplate<Exchange> template =
> exchange.getContext().createProducerTemplate();
>            template.send(endpoint, exchange);
>   }
You need to test the exchange afterwards if there was an exception.

template.send(endpoint, exchange);
if (exchange.getException() != null) {
  // ops it failed so call the next URI as fallback
  ...
}

and in case you want to reset the exception, you just call
exchange.setException(null);

and in your constructor you can have multiple endpoints, eg using a
List or varargs then you can loop the list of URI and try the next
one.


>
> Unfortunately this doesn't change anything on the SMIX console. I have the
> same error :
>
> FATAL - DeadLetterChannel              - Failed delivery for exchangeId:
> ID-ROME/1982-1242375956166/0-
> Handled by the failure processor:sendTo(Endpoint[direct:deadLetterChannel])
>
> Thanks for help
>
> On Fri, May 15, 2009 at 11:10 AM, Claus Ibsen <claus.ibsen@gmail.com> wrote:
>
>> Hi
>>
>> You should *not* route after your custom failover processor. You
>> custom failover processor should be the end of the route (eg no more
>> .to after your processor).
>>
>>
>>
>> On Fri, May 15, 2009 at 11:05 AM, Nasim Anza <nasmo2009@googlemail.com>
>> wrote:
>> > 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 <claus.ibsen@gmail.com>
>> 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 <claus.ibsen@gmail.com>
>> >> wrote:
>> >> > On Thu, May 14, 2009 at 4:55 PM, Nasim Anza <nasmo2009@googlemail.com
>> >
>> >> 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 <claus.ibsen@gmail.com
>> >
>> >> 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 <
>> nasmo2009@googlemail.com
>> >> >
>> >> >>> 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
>> >>
>> >
>>
>>
>>
>> --
>> 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

Mime
View raw message