camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Using CamelProxy
Date Thu, 22 Oct 2009 14:07:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/Using+CamelProxy">Using
CamelProxy</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~davsclaus">Claus
Ibsen</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h2><a name="UsingCamelProxy-UsingCamelProxy"></a>Using CamelProxy</h2>

<p>Camel allows you to proxy a producer sending to an <a href="/confluence/display/CAMEL/Endpoint"
title="Endpoint">Endpoint</a> by a regular interface. Then when clients using this
interface can work with it as if its regular java code but in reality its proxied and does
a <a href="/confluence/display/CAMEL/Request+Reply" title="Request Reply">Request Reply</a>
to a given endpoint.</p>

<h3><a name="UsingCamelProxy-ProxyfromSpring"></a>Proxy from Spring</h3>

<p>You can define a proxy in the spring XML file as shown below</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml"><span class="code-tag">&lt;camelContext id=<span
class="code-quote">"myCamel"</span> xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>

    <span class="code-tag"><span class="code-comment">&lt;!-- create a proxy
that will route to the direct:start endpoint when invoked --&gt;</span></span>
    &lt;proxy id=<span class="code-quote">"myProxySender"</span>
           serviceInterface=<span class="code-quote">"org.apache.camel.spring.config.MyProxySender"</span>
           serviceUrl=<span class="code-quote">"direct:start"</span>/&gt;

    &lt;!-- this is the route that our proxy will routed when invoked
         and the output from this route is returned as reply on the proxy --&gt; 
    <span class="code-tag">&lt;route&gt;</span>
        <span class="code-tag">&lt;from uri=<span class="code-quote">"direct:start"</span>/&gt;</span>
        <span class="code-tag">&lt;transform&gt;</span>
            <span class="code-tag">&lt;simple&gt;</span>Bye ${body}<span
class="code-tag">&lt;/simple&gt;</span>
        <span class="code-tag">&lt;/transform&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>

<span class="code-tag">&lt;/camelContext&gt;</span>
</pre>
</div></div>

<p>Now the client can grab this bean using regular spring bean coding and invoke it
as if its just another bean.<br/>
The code is based on an unit test but proves the point:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">ApplicationContext ac = <span class="code-keyword">new</span>
ClassPathXmlApplicationContext(<span class="code-quote">"org/apache/camel/spring/config/AnotherCamelProxyTest.xml"</span>);

MyProxySender sender = (MyProxySender) ac.getBean(<span class="code-quote">"myProxySender"</span>);
<span class="code-object">String</span> reply = sender.hello(<span class="code-quote">"Camel"</span>);

assertEquals(<span class="code-quote">"Bye Camel"</span>, reply);
</pre>
</div></div>

<h3><a name="UsingCamelProxy-ProxyfromJava"></a>Proxy from Java</h3>

<p>You can also create a proxy from regular Java using a ProxyHelper as shown below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
    Endpoint endpoint = context.getEndpoint(<span class="code-quote">"direct:start"</span>);
    MyProxySender sender = ProxyHelper.createProxy(endpoint, MyProxySender.class);
</pre>
</div></div>

<h3><a name="UsingCamelProxy-WhatissendontheMessage"></a>What is send on
the Message</h3>
<p>When using a proxy Camel will send the message payload as a <tt>org.apache.camel.component.bean.BeanInvocation</tt>
object which holds the details of which method was invoked and what the argument was.</p>

<h3><a name="UsingCamelProxy-TurningtheBeanInvocationintoafirstclasspayload"></a>Turning
the BeanInvocation into a first class payload</h3>
<p><b>Available as of Camel 2.1</b></p>

<p>If you proxied method signature only have one parameter such as:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-object">String</span> hello(<span class="code-object">String</span>
name);
</pre>
</div></div>

<p>Then it gives another advantage in Camel as it allows Camel to regard the value passed
in to this single parameter as the <em>real</em> payload. In other words if you
pass in <tt>Camel</tt> to the hello method, then Camel can <em>see</em>
that as a <tt>java.lang.String</tt> payload with the value of <tt>Camel</tt>.
This gives you a great advantage as you can use the proxy as first class services with Camel.</p>

<p>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 <em>just</em> the message payload.</p>

<p>Okay lets try that with an example</p>

<h4><a name="UsingCamelProxy-Examplewithproxyusingsingleparametermethods."></a>Example
with proxy using single parameter methods.</h4>

<p>At first we have the interface we wish to proxy</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">public</span> <span
class="code-keyword">interface</span> OrderService {

    <span class="code-object">String</span> submitOrderStringReturnString(<span
class="code-object">String</span> order);

    Document submitOrderStringReturnDocument(<span class="code-object">String</span>
order);

    <span class="code-object">String</span> submitOrderDocumentReturnString(Document
order);

    Document submitOrderDocumentReturnDocument(Document order);

    void doNothing(<span class="code-object">String</span> s);

    <span class="code-object">Integer</span> invalidReturnType(<span class="code-object">String</span>
s);

}
</pre>
</div></div>

<p>Notice that all methods have single parameters. The return type is optional, as you
can see one of them is void.<br/>
Also what you should know is that Camel uses its <a href="/confluence/display/CAMEL/Type+Converter"
title="Type Converter">Type Converter</a> mechanism to adapt to the types defined
on the methods.</p>

<p>This allows us to easily use <tt>org.w3c.dom.Document</tt> and <tt>String</tt>
types with no hazzle.</p>

<p>Okay then we have the following route where we route using a <a href="/confluence/display/CAMEL/Content+Based+Router"
title="Content Based Router">Content Based Router</a> that is XML based. See that
we use <a href="/confluence/display/CAMEL/XPath" title="XPath">XPath</a> in the
choices to route the message depending on its a book order or not.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">from(<span class="code-quote">"direct:start"</span>)
    .choice()
        .when(xpath(<span class="code-quote">"/order/@type = 'book'"</span>)).to(<span
class="code-quote">"direct:book"</span>)
        .otherwise().to(<span class="code-quote">"direct:other"</span>)
    .end();

from(<span class="code-quote">"direct:book"</span>).transform(constant(<span
class="code-quote">"&lt;order id=\"</span>123\<span class="code-quote">"&gt;OK&lt;/order&gt;"</span>));

from(<span class="code-quote">"direct:other"</span>).transform(constant(<span
class="code-quote">"&lt;order&gt;FAIL&lt;/order&gt;"</span>));
</pre>
</div></div>

<p>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.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Endpoint endpoint = context.getEndpoint(<span class="code-quote">"direct:start"</span>);
OrderService service = ProxyHelper.createProxy(endpoint, OrderService.class);

<span class="code-object">String</span> reply = service.submitOrderStringReturnString(<span
class="code-quote">"&lt;order type=\"</span>book\<span class="code-quote">"&gt;Camel
in action&lt;/order&gt;"</span>);
assertEquals(<span class="code-quote">"&lt;order id=\"</span>123\<span
class="code-quote">"&gt;OK&lt;/order&gt;"</span>, reply);
</pre>
</div></div>

<p>And this one below shows using different types that Camel adapts to.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Endpoint endpoint = context.getEndpoint(<span class="code-quote">"direct:start"</span>);
OrderService service = ProxyHelper.createProxy(endpoint, OrderService.class);

Document doc = context.getTypeConverter().convertTo(Document.class, <span class="code-quote">"&lt;order
type=\"</span>book\<span class="code-quote">"&gt;Camel in action&lt;/order&gt;"</span>);

Document reply = service.submitOrderDocumentReturnDocument(doc);
assertNotNull(reply);
<span class="code-object">String</span> s = context.getTypeConverter().convertTo(<span
class="code-object">String</span>.class, reply);
assertEquals(<span class="code-quote">"&lt;order id=\"</span>123\<span
class="code-quote">"&gt;OK&lt;/order&gt;"</span>, s);
</pre>
</div></div>

<p>Isn't this cool?</p>


<h3><a name="UsingCamelProxy-Seealso"></a>See also</h3>
<ul class="alternate" type="square">
	<li><a href="/confluence/display/CAMEL/User+Guide" title="User Guide">User Guide</a></li>
	<li><a href="/confluence/display/CAMEL/Tutorial-JmsRemoting" title="Tutorial-JmsRemoting">Tutorial&#45;JmsRemoting</a></li>
</ul>

     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Using+CamelProxy">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=5144992&revisedVersion=2&originalVersion=1">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Using+CamelProxy?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message