Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

You can define a proxy in the spring XML file as shown below

Wiki Markup
{snippet:id=e1|lang=xml|url=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/config/AnotherCamelProxyTest.xml}
Now the client can grab this bean using regular spring bean coding and invoke it as if its just another bean.
The code is based on an unit test but proves the point:
Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/config/AnotherCamelProxyTest.java}

Proxy from Java

You can also create a proxy from regular Java using a org.apache.camel.component.bean.ProxyHelper as shown below:

Code Block

    Endpoint endpoint = context.getEndpoint("direct:start");
    MyProxySender sender = ProxyHelper.createProxy(endpoint, MyProxySender.class);

In Camel 2.3 you can use org.apache.camel.builder.ProxyBuilder which may be easier to use than ProxyHelper:

Wiki Markup
{snippet:id=e4|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyTest.java}

Proxy with Annotation

Another way to configure the proxy from java is by using the @Produce annotation. Also see POJO Producing.

Code Block

@Produce(uri="direct:start")
MyProxySender sender;

...

When using a proxy Camel will send the message payload as a org.apache.camel.component.bean.BeanInvocation object which holds the details of which method was invoked and what the argument was.

From Camel 2.16 onwards you can enable binding which will use binding information from the method signature parameters to bind to the Exchange/Message with the following annotations

AnnotationBinds to
@BodyBinds the parameter to the message body
@Header(name)Binds the parameter to the message header with the given name
@ExchangeProperty(name)Binds the parameter to the exchange property with the given name

If a parameter does not have any annotation then the parameter is bound to the message body.

For example given the following interface

Code Block
public interface MyAuditService {
    void auditMessage(@Header("uuid") String uuid, @Body String body);
}

Then from Java DSL we can create a proxy and call the method

Code Block
// must enable binding on proxy
MyAuditService service = new ProxyBuilder(context).endpoint("jms:queue:foo").binding(true).build(MyAuditService.class);
service.auditMessage("1234", "Hello World");

Which will send the message to the JMS queue foo, with the header(uuid)=1234 and body=Hello World. The message is sent as InOnly as the method is void.

Turning the BeanInvocation into a first class payload

...

If you proxied method signature only have one parameter such as:

Code Block

String hello(String name);

...

You can proxy Camel and let clients use the pure and clean interfaces as if Camel newer existed. Then Camel can proxy the invocation and receive the input passed into the single method parameter and regard that as if it was just the message payload.

Info

From Camel 2.16 onwards this is improved as you can enable binding and Camel binds to the message parameters using the annotation listed in the table above. If a parameter has no annotation then the parameter is bound to the message body.

 

Okay lets try that with an example

...

At first we have the interface we wish to proxy

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/OrderService.java}
Notice that all methods have single parameters. The return type is optional, as you can see one of them is void.
Also what you should know is that Camel uses its Type Converter mechanism to adapt to the types defined on the methods.

...

Okay then we have the following route where we route using a Content Based Router that is XML based. See that we use XPath in the choices to route the message depending on its a book order or not.

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyTest.java}
Now there is a couple of tests that shows using the Camel Proxy how we can easily invoke the proxy and do not know its actually Camel doing some routing underneath.
Wiki Markup
{snippet:id=e2|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyTest.java}
And this one below shows using different types that Camel adapts to.
Wiki Markup
{snippet:id=e3|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/BeanProxyTest.java}
Isn't this cool?

Asynchronous using Future

...

For example given this client interface

Wiki Markup
{snippet:id=e1|lang=java|title=Client Interface|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/ProxyReturnFutureTest.java}
The client can use this with a Camel Proxy as shown from the following snippet from an unit test:
Wiki Markup
{snippet:id=e2|lang=java|title=Using Client|url=camel/trunk/camel-core/src/test/java/org/apache/camel/component/bean/ProxyReturnFutureTest.java}
This allows you to fully define your client API without any Camel dependency at all, and decide whether the invocation should be synchronous or asynchronous.

...