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 Sat, 16 May 2009 14:37:57 GMT
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

Mime
View raw message