camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nasim Anza <nasmo2...@googlemail.com>
Subject Re: Calling dynamically multiple http endpoints
Date Mon, 18 May 2009 13:56:14 GMT
Thanks Claus for your help.

Actually the problem I got is not related to the FailOverProcessor mechanism
but in the global route:
I would like that the result of a given HTTP endoint  goes into another HTTP
endpoint.
For example the result of HTTP endpointA will be redirected to the HTTP
endpoint B.... etc

I've pasted my route and my FailOver Processor on pastbin URL :
http://mmo.pastebin.com/m7160e173

Please let me know if I have any error or mistake in the code.

Note : the appliA1, appliA2, .appliX are webservices that return valid SOAP
XMLs

Thanks a lot for any help

Nasmo


On Sat, May 16, 2009 at 4:52 PM, Claus Ibsen <claus.ibsen@gmail.com> wrote:

> Hi
>
> I have created an example how to do your own custom processor as
> failover. Its based on an unit test and the code is here:
>
>
> https://svn.apache.org/repos/asf/camel/trunk/camel-core/src/test/java/org/apache/camel/issues/CustomFailveOverProcessor.java
>
> The code is based on Camel 2.0, but you can do the same in Camel 1.x.
>
>
> On Sat, May 16, 2009 at 4:37 PM, Claus Ibsen <claus.ibsen@gmail.com>
> wrote:
> > Hi
> >
> > Sometimes its easier to read the code when there is quite a bit if you
> > paste it using http://pastebin.com/ or the likes.
> >
> >
> >
> > On Fri, May 15, 2009 at 5:44 PM, Nasim Anza <nasmo2009@googlemail.com>
> wrote:
> >> Thanks Claus for answers.
> >>
> >> My processor is working fine and it finds the URL to invoke but the
> problem
> >> is on the last step : the next endpoint is not called with right XML
> input :
> >>
> >> Just to explain my actual problem :
> >> Let's assume that my route is :
> >>
> >> from("direct:endpointA")
> >> .setHeader(HttpProducer.HTTP_URI).simple("http://myAddressA")
> >> .process(myFailOverProcessor("direct:endpointB")); //forward HTTP
> response
> >> to the direct:endpointB
> >>
> >> from("direct:endpointB")
> >> .to("log:display the XML input"); //just display it to compare XMLs
> >>
> >> The displayed XML on the "log:..." endpoint doesn't correspond to the
> http
> >> response of "http://myAddressA"...
> >>
> >> Here is my Processor class :
> >>
> >>
> >>  public class FailOverProcessor implements Processor{
> >>
> >>  public FailOverProcessor(String endpoint) {
> >>        this.endpoint=endpoint;
> >>    }
> >>
> >>  public void process(Exchange exchange) throws Exception {
> >>        Exchange out = null;
> >>        int index = 0;
> >>        out = processExchange(exchange);
> >>
> >>        while (exchange.getException() != null){
> >>
> >>            //reset the exchange exceptiuon
> >>            exchange.setException(null);
> >>
> >>            if (index++ < 4 ) {
> >>                System.out.println(index+" : processExchange .....");
> >>
> >>                out = processExchange(exchange);
> >>           }
> >>      }
> >>
> >>      if(endpoint != null)
> >>        {
> >>            ProducerTemplate<Exchange> template =
> >> exchange.getContext().createProducerTemplate();
> >>            if(out != null)
> >>            {
> >>
> >>            Message responseOut = exchange.getOut();
> >>            int responseCode =
> >> responseOut.getHeader(HttpProducer.HTTP_RESPONSE_CODE, Integer.class);
> >>            System.out.println("\n\n Response out \\n" + responseCode +
> >> responseOut.getBody(String.class));
> >>
> >>            //I've tried all the these calls but no valid response
> >>            // template.send(endpoint, exchange.getOut().getExchange());
> >>            // template.sendBody(endpoint, exchange.getBody());
> >>            template.send(endpoint, exchange);
> >>             }
> >>        }
> >>    }
> >>
> >>    private Exchange processExchange(Exchange exchange) {
> >>
> >>        Exchange out = null;
> >>
> >>        try {
> >>
> >>            //Define the strategy to use for processing message
> >>            String uri =
> >>
> exchange.getIn().getHeader(org.apache.camel.component.http.HttpProducer.HTTP_URI).toString();
> >>              System.out.println("Current URI ==> "+uri);
> >>
> >>          //just for test
> >>          if(uri.equalsIgnoreCase("http://myAddressA"))
> >>                exchange.getIn().setHeader(HttpProducer.HTTP_URI, "
> >> http://serverA/appli1");
> >>          else if(uri.equalsIgnoreCase("http://myAddressB"))
> >>              exchange.getIn().setHeader(HttpProducer.HTTP_URI, "
> >> http://serverB/appli2");
> >>          else
> >>               exchange.getIn().setHeader(HttpProducer.HTTP_URI, "
> >> http://serverC/error");
> >>
> >>            ProducerTemplate<Exchange> template =
> >> exchange.getContext().createProducerTemplate();
> >>
> >>            out = template.send(uri, exchange);
> >>
> >>        } catch (Throwable th) {
> >>               //Set the thrown exception
> >>            exchange.setException(th.getCause());
> >>        }
> >>
> >>        return out;
> >>  }
> >>  }
> >>
> >> Thanks for your help
> >> Nasmo
> >>
> >>
> >>
> >>
> >> On Fri, May 15, 2009 at 1:00 PM, Claus Ibsen <claus.ibsen@gmail.com>
> wrote:
> >>
> >>> 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
> >>>  ...
> >>> }
> >>>
> >>>
> >>>
> >>>
> >>> >
> >>> > 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
> >>>
> >>
> >
> >
> >
> > --
> > 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
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message