On Mon, May 18, 2009 at 3:56 PM, Nasim Anza <[email protected]> wrote:
> 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
That is the pipes and filters EIP pattern:
http://camel.apache.org/pipes-and-filters.html
So basically its like
.to("a", "b", "c");
where the output from a is input to b and output from b is input to c and so on.
I will suggest that you try without the failover and get this
implemented so you got the "normal situation" covered.
When that is working we can take a look again how to do error handling
and failover.
>
> 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 <[email protected]> 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 <[email protected]>
>> 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 <[email protected]>
>> 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 <[email protected]>
>> 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 <[email protected]
>> >
>> >>> 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 <
>> [email protected]>
>> >>> >> 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 <
>> [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
>> >>> >> >>
>> >>> >> >
>> >>> >>
>> >>> >>
>> >>> >>
>> >>> >> --
>> >>> >> 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