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

Reply via email to