Camel Pojo Routing

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Camel Pojo Routing

RoshanP
I couldn't get the forums to come up, it keeps timing out, so I have to
ask this question on the mailing list.

 

I have two Pojo endpoints, and I want to route based on a String input.
How do I do that? This is my code currently:

 

CamelContext context = new DefaultCamelContext();

                        PojoComponent component1 = (PojoComponent)
context.getComponent("pojo");

                        component1.addService("one", new PojoOne());

                        PojoComponent component2 = (PojoComponent)
context.getComponent("pojo");

                        component2.addService("two", new PojoTwo());

 

                        DirectComponent directComponent =
(DirectComponent) context

                                                .getComponent("direct");

                        directComponent.createEndpoint("hello");

 

                        context.addRoutes(new RouteBuilder() {

                                    public void configure() {

                                                FromBuilder from =
from("direct:hello");

                                                ChoiceBuilder choice =
from.choice();

                                                WhenBuilder when =
choice

 
.when(body().isEqualTo("One"));

                                                when.to("pojo:one")

 
.otherwise().to("pojo:two");

                                    }

                        });

 

                        context.start();

 

                        Endpoint endpoint =
context.getEndpoint("direct:hello");

                        PojoNumInterface pojo = (PojoNumInterface)
PojoComponent.createProxy(

                                                endpoint,
PojoNumInterface.class);

                        pojo.execute("One");

 

 

I'm guessing the body() function only returns a PojoInvocation and not
the actual argument "One".

 

Roshan

Reply | Threaded
Open this post in threaded view
|

Re: Camel Pojo Routing

hadrian
Hi Roshnan,

You are right that the root of the problem is that the "body() function
only returns a PojoInvocation and not the actual argument".  However
this is what you asked camel to do.  As you are dealing with a POJO, you
are not interested in the whole PojoInvocation, but a particular
argument (could have been more than one) or you could have been
interested in the method name to make the choice.  So you might want to
write your code like this:

        context.addRoutes(new RouteBuilder(context) {
            public void configure() {
               
from("direct:hello").choice().when(argument(0).isEqualTo("One"))
                    .to("pojo:one").otherwise().to("pojo:two");
            }

            private ValueBuilder<PojoExchange> argument(int index) {
                Expression<PojoExchange> expression =
PojoExpressionBuilder.argumentExpression(index);
                return new ValueBuilder<PojoExchange>(expression);
            }
        });

Please note that the Predicate for your choice is now "when the 1st
argument of my pojo method call is equal to 'One'".  You would need
though an Expression that evaluates to the n-th argument of a pojo
method call to implement the argument method as above.  Camel does not
provide such as Expression, but here is some code that does the job (a
method that creates an Expression that evaluates to the method name is
also provided).

import org.apache.camel.Expression;

public class PojoExpressionBuilder {

    public static Expression<PojoExchange> methodExpression() {
        return new Expression<PojoExchange>() {
            public Object evaluate(PojoExchange exchange) {
                PojoInvocation body =
(PojoInvocation)exchange.getIn().getBody();
                if (body != null) {
                    return body.getMethod().getName();
                }
                return null;
            }


            @Override
            public String toString() {
                return "method";
            }
        };
    }
   
    public static Expression<PojoExchange> argumentExpression(final int
index) {
        return new Expression<PojoExchange>() {
            public Object evaluate(PojoExchange exchange) {
                PojoInvocation body =
(PojoInvocation)exchange.getIn().getBody();
                if (body != null) {
                    return body.getArgs()[index];
                }
                return null;
            }


            @Override
            public String toString() {
                return "arg(" + index + ")";
            }
        };
    }
}


I hope this helps,
Hadrian


Punnoose, Roshan wrote:

> I couldn't get the forums to come up, it keeps timing out, so I have to
> ask this question on the mailing list.
>
>  
>
> I have two Pojo endpoints, and I want to route based on a String input.
> How do I do that? This is my code currently:
>
>  
>
> CamelContext context = new DefaultCamelContext();
>
>                         PojoComponent component1 = (PojoComponent)
> context.getComponent("pojo");
>
>                         component1.addService("one", new PojoOne());
>
>                         PojoComponent component2 = (PojoComponent)
> context.getComponent("pojo");
>
>                         component2.addService("two", new PojoTwo());
>
>  
>
>                         DirectComponent directComponent =
> (DirectComponent) context
>
>                                                 .getComponent("direct");
>
>                         directComponent.createEndpoint("hello");
>
>  
>
>                         context.addRoutes(new RouteBuilder() {
>
>                                     public void configure() {
>
>                                                 FromBuilder from =
> from("direct:hello");
>
>                                                 ChoiceBuilder choice =
> from.choice();
>
>                                                 WhenBuilder when =
> choice
>
>  
> .when(body().isEqualTo("One"));
>
>                                                 when.to("pojo:one")
>
>  
> .otherwise().to("pojo:two");
>
>                                     }
>
>                         });
>
>  
>
>                         context.start();
>
>  
>
>                         Endpoint endpoint =
> context.getEndpoint("direct:hello");
>
>                         PojoNumInterface pojo = (PojoNumInterface)
> PojoComponent.createProxy(
>
>                                                 endpoint,
> PojoNumInterface.class);
>
>                         pojo.execute("One");
>
>  
>
>  
>
> I'm guessing the body() function only returns a PojoInvocation and not
> the actual argument "One".
>
>  
>
> Roshan
>
>
>  
Reply | Threaded
Open this post in threaded view
|

Re: Camel Pojo Routing

hadrian
Roshnan,

James Strachan pointed out another solution that does not require any
extra code:
                from("direct:hello").choice().when(
                    new
ValueBuilder(el("${in.body.args[0]}")).isEqualTo("One"))
                    .to("pojo:one").otherwise().to("pojo:two");

you would need to
import static org.apache.camel.language.juel.JuelExpression.el;

Thanks James,
Hadrian

Hadrian Zbarcea wrote:

> Hi Roshnan,
>
> You are right that the root of the problem is that the "body()
> function only returns a PojoInvocation and not the actual argument".  
> However this is what you asked camel to do.  As you are dealing with a
> POJO, you are not interested in the whole PojoInvocation, but a
> particular argument (could have been more than one) or you could have
> been interested in the method name to make the choice.  So you might
> want to write your code like this:
>
>        context.addRoutes(new RouteBuilder(context) {
>            public void configure() {
>                
> from("direct:hello").choice().when(argument(0).isEqualTo("One"))
>                    .to("pojo:one").otherwise().to("pojo:two");
>            }
>
>            private ValueBuilder<PojoExchange> argument(int index) {
>                Expression<PojoExchange> expression =
> PojoExpressionBuilder.argumentExpression(index);
>                return new ValueBuilder<PojoExchange>(expression);
>            }
>        });
>
> Please note that the Predicate for your choice is now "when the 1st
> argument of my pojo method call is equal to 'One'".  You would need
> though an Expression that evaluates to the n-th argument of a pojo
> method call to implement the argument method as above.  Camel does not
> provide such as Expression, but here is some code that does the job (a
> method that creates an Expression that evaluates to the method name is
> also provided).
>
> import org.apache.camel.Expression;
>
> public class PojoExpressionBuilder {
>
>    public static Expression<PojoExchange> methodExpression() {
>        return new Expression<PojoExchange>() {
>            public Object evaluate(PojoExchange exchange) {
>                PojoInvocation body =
> (PojoInvocation)exchange.getIn().getBody();
>                if (body != null) {
>                    return body.getMethod().getName();
>                }
>                return null;
>            }
>
>
>            @Override
>            public String toString() {
>                return "method";
>            }
>        };
>    }
>      public static Expression<PojoExchange> argumentExpression(final
> int index) {
>        return new Expression<PojoExchange>() {
>            public Object evaluate(PojoExchange exchange) {
>                PojoInvocation body =
> (PojoInvocation)exchange.getIn().getBody();
>                if (body != null) {
>                    return body.getArgs()[index];
>                }
>                return null;
>            }
>
>
>            @Override
>            public String toString() {
>                return "arg(" + index + ")";
>            }
>        };
>    }
> }
>
>
> I hope this helps,
> Hadrian
>
>
> Punnoose, Roshan wrote:
>> I couldn't get the forums to come up, it keeps timing out, so I have to
>> ask this question on the mailing list.
>>
>>  
>>
>> I have two Pojo endpoints, and I want to route based on a String input.
>> How do I do that? This is my code currently:
>>
>>  
>>
>> CamelContext context = new DefaultCamelContext();
>>
>>                         PojoComponent component1 = (PojoComponent)
>> context.getComponent("pojo");
>>
>>                         component1.addService("one", new PojoOne());
>>
>>                         PojoComponent component2 = (PojoComponent)
>> context.getComponent("pojo");
>>
>>                         component2.addService("two", new PojoTwo());
>>
>>  
>>
>>                         DirectComponent directComponent =
>> (DirectComponent) context
>>
>>                                                 .getComponent("direct");
>>
>>                         directComponent.createEndpoint("hello");
>>
>>  
>>
>>                         context.addRoutes(new RouteBuilder() {
>>
>>                                     public void configure() {
>>
>>                                                 FromBuilder from =
>> from("direct:hello");
>>
>>                                                 ChoiceBuilder choice =
>> from.choice();
>>
>>                                                 WhenBuilder when =
>> choice
>>
>>  
>> .when(body().isEqualTo("One"));
>>
>>                                                 when.to("pojo:one")
>>
>>  
>> .otherwise().to("pojo:two");
>>
>>                                     }
>>
>>                         });
>>
>>  
>>
>>                         context.start();
>>
>>  
>>
>>                         Endpoint endpoint =
>> context.getEndpoint("direct:hello");
>>
>>                         PojoNumInterface pojo = (PojoNumInterface)
>> PojoComponent.createProxy(
>>
>>                                                 endpoint,
>> PojoNumInterface.class);
>>
>>                         pojo.execute("One");
>>
>>  
>>
>>  
>>
>> I'm guessing the body() function only returns a PojoInvocation and not
>> the actual argument "One".
>>
>>  
>>
>> Roshan
>>
>>
>>  
>
Reply | Threaded
Open this post in threaded view
|

RE: Camel Pojo Routing

RoshanP
Thanks for all the help!

Roshan Punnoose
Phone: 301-497-6039
-----Original Message-----
From: Hadrian Zbarcea [mailto:[hidden email]]
Sent: Thursday, August 02, 2007 10:24 AM
To: [hidden email]
Subject: Re: Camel Pojo Routing

Roshnan,

James Strachan pointed out another solution that does not require any
extra code:
                from("direct:hello").choice().when(
                    new
ValueBuilder(el("${in.body.args[0]}")).isEqualTo("One"))
                    .to("pojo:one").otherwise().to("pojo:two");

you would need to
import static org.apache.camel.language.juel.JuelExpression.el;

Thanks James,
Hadrian

Hadrian Zbarcea wrote:
> Hi Roshnan,
>
> You are right that the root of the problem is that the "body()
> function only returns a PojoInvocation and not the actual argument".  
> However this is what you asked camel to do.  As you are dealing with a

> POJO, you are not interested in the whole PojoInvocation, but a
> particular argument (could have been more than one) or you could have
> been interested in the method name to make the choice.  So you might
> want to write your code like this:
>
>        context.addRoutes(new RouteBuilder(context) {
>            public void configure() {
>                
> from("direct:hello").choice().when(argument(0).isEqualTo("One"))
>                    .to("pojo:one").otherwise().to("pojo:two");
>            }
>
>            private ValueBuilder<PojoExchange> argument(int index) {
>                Expression<PojoExchange> expression =
> PojoExpressionBuilder.argumentExpression(index);
>                return new ValueBuilder<PojoExchange>(expression);
>            }
>        });
>
> Please note that the Predicate for your choice is now "when the 1st
> argument of my pojo method call is equal to 'One'".  You would need
> though an Expression that evaluates to the n-th argument of a pojo
> method call to implement the argument method as above.  Camel does not

> provide such as Expression, but here is some code that does the job (a

> method that creates an Expression that evaluates to the method name is

> also provided).
>
> import org.apache.camel.Expression;
>
> public class PojoExpressionBuilder {
>
>    public static Expression<PojoExchange> methodExpression() {
>        return new Expression<PojoExchange>() {
>            public Object evaluate(PojoExchange exchange) {
>                PojoInvocation body =
> (PojoInvocation)exchange.getIn().getBody();
>                if (body != null) {
>                    return body.getMethod().getName();
>                }
>                return null;
>            }
>
>
>            @Override
>            public String toString() {
>                return "method";
>            }
>        };
>    }
>      public static Expression<PojoExchange> argumentExpression(final
> int index) {
>        return new Expression<PojoExchange>() {
>            public Object evaluate(PojoExchange exchange) {
>                PojoInvocation body =
> (PojoInvocation)exchange.getIn().getBody();
>                if (body != null) {
>                    return body.getArgs()[index];
>                }
>                return null;
>            }
>
>
>            @Override
>            public String toString() {
>                return "arg(" + index + ")";
>            }
>        };
>    }
> }
>
>
> I hope this helps,
> Hadrian
>
>
> Punnoose, Roshan wrote:
>> I couldn't get the forums to come up, it keeps timing out, so I have
to
>> ask this question on the mailing list.
>>
>>  
>>
>> I have two Pojo endpoints, and I want to route based on a String
input.

>> How do I do that? This is my code currently:
>>
>>  
>>
>> CamelContext context = new DefaultCamelContext();
>>
>>                         PojoComponent component1 = (PojoComponent)
>> context.getComponent("pojo");
>>
>>                         component1.addService("one", new PojoOne());
>>
>>                         PojoComponent component2 = (PojoComponent)
>> context.getComponent("pojo");
>>
>>                         component2.addService("two", new PojoTwo());
>>
>>  
>>
>>                         DirectComponent directComponent =
>> (DirectComponent) context
>>
>>
.getComponent("direct");

>>
>>                         directComponent.createEndpoint("hello");
>>
>>  
>>
>>                         context.addRoutes(new RouteBuilder() {
>>
>>                                     public void configure() {
>>
>>                                                 FromBuilder from =
>> from("direct:hello");
>>
>>                                                 ChoiceBuilder choice
=

>> from.choice();
>>
>>                                                 WhenBuilder when =
>> choice
>>
>>  
>> .when(body().isEqualTo("One"));
>>
>>                                                 when.to("pojo:one")
>>
>>  
>> .otherwise().to("pojo:two");
>>
>>                                     }
>>
>>                         });
>>
>>  
>>
>>                         context.start();
>>
>>  
>>
>>                         Endpoint endpoint =
>> context.getEndpoint("direct:hello");
>>
>>                         PojoNumInterface pojo = (PojoNumInterface)
>> PojoComponent.createProxy(
>>
>>                                                 endpoint,
>> PojoNumInterface.class);
>>
>>                         pojo.execute("One");
>>
>>  
>>
>>  
>>
>> I'm guessing the body() function only returns a PojoInvocation and
not
>> the actual argument "One".
>>
>>  
>>
>> Roshan
>>
>>
>>  
>
Reply | Threaded
Open this post in threaded view
|

Re: Camel Pojo Routing

jstrachan
In reply to this post by RoshanP
On 8/1/07, Punnoose, Roshan <[hidden email]> wrote:
> I couldn't get the forums to come up, it keeps timing out, so I have to
> ask this question on the mailing list.

Strange! You using one of the nabble.com links like this?
http://www.nabble.com/Camel-f22882.html

I've used Nabble alot on many different lists including Camel and
never seen a glitch yet. Never mind; they sync to each other so it
doesn't matter which one you pick really


> I have two Pojo endpoints, and I want to route based on a String input.
> How do I do that? This is my code currently:

It looks like Hadrian has jumped in and answered your question.

Incidentally as part of CAMEL-86 I've just rationalised lots of the
bean code and bean binding code; the POJO component has now merged
into the Bean component. As a result in 1.1 of Camel the body will be
of type BeanInvocation. However if you are using an expression
language - like EL as Hadrian mentioned, your code will still work -
as its just looking in the arguments property.

Another minor change is that in trunk (and 1.1 when we release that
soon, next week I hope) is that the POJO/bean component uses the
Registry to find beans into invoke. So this could be JNDI or Spring
ApplicationContext depending on what kinda environment you want.

More details here...
http://cwiki.apache.org/CAMEL/bean.html
--
James
-------
http://macstrac.blogspot.com/