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
>