camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > CXFRS
Date Thu, 17 Dec 2009 04:00: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/CXFRS">CXFRS</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~njiang">willem
jiang</a>
    </h4>
     CAMEL-1909 
          <div id="versionComment" class="noteMacro" style="display:none; padding: 5px;">
     CAMEL-1909 <br />
     </div>
          <br/>
     <div class="notificationGreySide">
         <h2><a name="CXFRS-CXFRSComponent"></a>CXFRS Component</h2>

<p>The <b>cxfrs:</b> component provides integration with <a href="http://incubator.apache.org/cxf/"
rel="nofollow">Apache CXF</a> for connecting to JAX-RS services hosted in CXF.</p>

<p>Maven users will need to add the following dependency to their pom.xml for this component:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
&lt;dependency&gt;
   &lt;groupId&gt;org.apache.camel&lt;/groupId&gt;
   &lt;artifactId&gt;camel-cxf&lt;/artifactId&gt;
   &lt;version&gt;x.x.x&lt;/version&gt;  &lt;!-- use the same version
as your Camel core version --&gt;
&lt;/dependency&gt;
</pre>
</div></div>

<h3><a name="CXFRS-URIformat"></a>URI format</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
cxfrs:<span class="code-comment">//address?options</span>
</pre>
</div></div>
<p>Where <b>address</b> represents the CXF endpoint's address</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
cxfrs:bean:rsEndpoint
</pre>
</div></div>
<p>Where <b>rsEndpoint</b> represents the spring bean's name which presents
the CXFRS client or server</p>

<p>For either style above, you can append options to the URI as follows:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
cxf:bean:cxfEndpoint?resourceClass=org.apache.camel.rs.Example
</pre>
</div></div>

<h3><a name="CXFRS-Options"></a>Options</h3>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Name </th>
<th class='confluenceTh'> Description </th>
<th class='confluenceTh'> Example </th>
<th class='confluenceTh'> Required? </th>
<th class='confluenceTh'> default value </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>resourcesClass</tt> </td>
<td class='confluenceTd'> The resource classes which you want to export as REST service
</td>
<td class='confluenceTd'> <tt>resourcesClass=org.apache.camel.rs.Example1,org.apache.camel.rs.Exchange2</tt>
</td>
<td class='confluenceTd'> No </td>
<td class='confluenceTd'> <em>None</em> </td>
</tr>
<tr>
<td class='confluenceTd'> <tt>httpClientAPI</tt> </td>
<td class='confluenceTd'> <b>new to Camel 2.1</b> If it is true, the CxfRsProducer
will use the HttpClientAPI to invoke the service <br/>
If it is false, the CxfRsProducer will use the ProxyClientAPI to invoke the service</td>
<td class='confluenceTd'> httpClientAPI=true  </td>
<td class='confluenceTd'>No </td>
<td class='confluenceTd'> <em>true</em> </td>
</tr>
</tbody></table>

<p>You can also configure the CXF REST endpoint through the spring configuration. Since
there are lots of difference between the CXF REST client and CXF REST Server, we provides
different configuration for them.<br/>
Please check out the <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/main/resources/schema/cxfEndpoint.xsd"
rel="nofollow">schema file</a> and <a href="http://cwiki.apache.org/CXF20DOC/jax-rs.html"
rel="nofollow">CXF REST user guide</a> for more information.</p>

<h3><a name="CXFRS-HowtoconfiguretheRESTendpointinCamel%3F"></a>How to configure
the REST endpoint in Camel ?</h3>
<p>In <a href="http://svn.apache.org/repos/asf/camel/trunk/components/camel-cxf/src/main/resources/schema/cxfEndpoint.xsd"
rel="nofollow">camel-cxf schema file</a>, there are two elements for the REST endpoint
definition. <b>cxf:rsServer</b> for REST consumer, <b>cxf:rsClient</b>
for REST producer.<br/>
You can find an camel REST service route configuration example here.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span>
       <span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
       <span class="code-keyword">xmlns:cxf</span>=<span class="code-quote">"http://camel.apache.org/schema/cxf"</span>
       <span class="code-keyword">xmlns:jaxrs</span>=<span class="code-quote">"http://cxf.apache.org/jaxrs"</span>
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
       http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
    "&gt;
  <span class="code-tag"><span class="code-comment">&lt;!-- Defined the real
JAXRS back end service  --&gt;</span></span>
  &lt;jaxrs:server id=<span class="code-quote">"restService"</span>
		        address=<span class="code-quote">"http://localhost:9002"</span> 
		        staticSubresourceResolution=<span class="code-quote">"true"</span>&gt;
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"customerService"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>       
  <span class="code-tag">&lt;/jaxrs:server&gt;</span>
  
  <span class="code-tag">&lt;bean id=<span class="code-quote">"jsonProvider"</span>
class=<span class="code-quote">"org.apache.cxf.jaxrs.provider.JSONProvider"</span>/&gt;</span>

  <span class="code-tag">&lt;bean id=<span class="code-quote">"customerService"</span>
class=<span class="code-quote">"org.apache.camel.component.cxf.jaxrs.testbean.CustomerService"</span>
/&gt;</span>
   
  <span class="code-tag"><span class="code-comment">&lt;!-- Defined the server
endpoint to create the cxf-rs consumer --&gt;</span></span> 
  &lt;cxf:rsServer id=<span class="code-quote">"rsServer"</span> address=<span
class="code-quote">"http://localhost:9000"</span>
    serviceClass=<span class="code-quote">"org.apache.camel.component.cxf.jaxrs.testbean.CustomerService"</span>
/&gt;

  <span class="code-tag"><span class="code-comment">&lt;!-- Defined the client
endpoint to create the cxf-rs consumer --&gt;</span></span>
  &lt;cxf:rsClient id=<span class="code-quote">"rsClient"</span> address=<span
class="code-quote">"http://localhost:9002"</span>
    serviceClass=<span class="code-quote">"org.apache.camel.component.cxf.jaxrs.testbean.CustomerService"</span>/&gt;
  
  <span class="code-tag"><span class="code-comment">&lt;!-- The camel route
context --&gt;</span></span>
  <span class="code-tag">&lt;camelContext id=<span class="code-quote">"camel"</span>
xmlns=<span class="code-quote">"http://camel.apache.org/schema/spring"</span>&gt;</span>
    <span class="code-tag">&lt;route&gt;</span>
       <span class="code-tag">&lt;from uri=<span class="code-quote">"cxfrs://bean://rsServer"</span>/&gt;</span>
       <span class="code-tag"><span class="code-comment">&lt;!-- We can remove
this configure as the CXFRS producer is using the HttpAPI by default --&gt;</span></span>
       <span class="code-tag">&lt;setHeader headerName=<span class="code-quote">"CamelCxfRsUsingHttpAPI"</span>&gt;</span>
         <span class="code-tag">&lt;constant&gt;</span>True<span class="code-tag">&lt;/constant&gt;</span>
       
       <span class="code-tag">&lt;/setHeader&gt;</span>
       <span class="code-tag">&lt;to uri=<span class="code-quote">"cxfrs://bean://rsClient"</span>/&gt;</span>
    <span class="code-tag">&lt;/route&gt;</span>
  <span class="code-tag">&lt;/camelContext&gt;</span>
  
<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>


<h3><a name="CXFRS-HowtoconsumertheRESTrequestinCamel%3F"></a>How to consumer
the REST request in Camel ?</h3>
<p><a href="http://cwiki.apache.org/CXF20DOC/jax-rs.html" rel="nofollow">CXF JAXRS
front end</a> implements the <a href="https://jsr311.dev.java.net/" rel="nofollow">JAXRS(JSR311)
API</a>, so we can export the resources classes as a REST service. And we leverage the
<a href="http://cwiki.apache.org/confluence/display/CXF20DOC/Invokers" rel="nofollow">CXF
Invoker API</a> to turn a REST request into a normal Java object method invocation.<br/>
Unlike the <tt>camel-restlet</tt>, you don't need to specify the URI template
within your restlet endpoint, CXF take care of the REST request URI to resource class method
mapping according to the JSR311 specification. All you need to do in Camel is delegate this
method request to a right processor or endpoint.</p>

<p>Here is an example</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java"><span class="code-keyword">protected</span> RouteBuilder
createRouteBuilder() <span class="code-keyword">throws</span> Exception {
    <span class="code-keyword">return</span> <span class="code-keyword">new</span>
RouteBuilder() {
        <span class="code-keyword">public</span> void configure() {
            errorHandler(<span class="code-keyword">new</span> NoErrorHandlerBuilder());
            from(CXF_RS_ENDPOINT_URI).process(<span class="code-keyword">new</span>
Processor() {

                <span class="code-keyword">public</span> void process(Exchange
exchange) <span class="code-keyword">throws</span> Exception {
                    Message inMessage = exchange.getIn();                        
                    <span class="code-comment">// Get the operation name from in message
</span>                    <span class="code-object">String</span> operationName
= inMessage.getHeader(CxfConstants.OPERATION_NAME, <span class="code-object">String</span>.class);
                    <span class="code-comment">// The parameter of the invocation is
stored in the body of in message
</span>                    <span class="code-object">String</span> id =
(<span class="code-object">String</span>) inMessage.getBody(<span class="code-object">Object</span>[].class)[0];
                    <span class="code-keyword">if</span> (<span class="code-quote">"getCustomer"</span>.equals(operationName))
{
                        <span class="code-object">String</span> httpMethod = inMessage.getHeader(Exchange.HTTP_METHOD,
<span class="code-object">String</span>.class);
                        assertEquals(<span class="code-quote">"Get a wrong http method"</span>,
<span class="code-quote">"GET"</span>, httpMethod);
                        <span class="code-object">String</span> uri = inMessage.getHeader(Exchange.HTTP_URI,
<span class="code-object">String</span>.class);
                        <span class="code-keyword">if</span> (<span class="code-quote">"/customerservice/customers/126"</span>.equals(uri))
{                            
                            Customer customer = <span class="code-keyword">new</span>
Customer();
                            customer.setId(<span class="code-object">Long</span>.parseLong(id));
                            customer.setName(<span class="code-quote">"Willem"</span>);
                            <span class="code-comment">// We just put the response <span
class="code-object">Object</span> into the out message body
</span>                            exchange.getOut().setBody(customer);
                        } <span class="code-keyword">else</span> {
                            Response r = Response.status(404).entity(<span class="code-quote">"Can't
found the customer with uri "</span> + uri).build();
                            <span class="code-keyword">throw</span> <span class="code-keyword">new</span>
WebApplicationException(r);
                        }
                    }
                }
                
            });
        }
    };
}
</pre>
</div></div>


<h3><a name="CXFRS-HowtoinvoketheRESTservicethroughcamelcxfrsproducer%3F"></a>How
to invoke the REST service through camel-cxfrs producer ?</h3>
<p><a href="http://cwiki.apache.org/CXF20DOC/jax-rs.html" rel="nofollow">CXF JAXRS
front end</a> implements <a href="http://cwiki.apache.org/CXF20DOC/jax-rs.html#JAX-RS-ProxybasedAPI"
rel="nofollow">a proxy based client API</a>, with this API you can invoke the remote
REST service through a proxy. <br/>
<tt>camel-cxfrs</tt> producer is based on this <a href="http://cwiki.apache.org/CXF20DOC/jax-rs.html#JAX-RS-ProxybasedAPI"
rel="nofollow">proxy API</a>. <br/>
So, you just need to specify the operation name in the message header and prepare the parameter
in the message body, camel-cxfrs producer will generate right REST request for you.</p>

<p>Here is an example</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exchange exchange = template.send(<span class="code-quote">"direct:<span
class="code-comment">//proxy"</span>, <span class="code-keyword">new</span>
Processor() {
</span>
    <span class="code-keyword">public</span> void process(Exchange exchange) <span
class="code-keyword">throws</span> Exception {
        exchange.setPattern(ExchangePattern.InOut);
        Message inMessage = exchange.getIn();
        <span class="code-comment">// set the operation name 
</span>        inMessage.setHeader(CxfConstants.OPERATION_NAME, <span class="code-quote">"getCustomer"</span>);
        <span class="code-comment">// using the proxy client API
</span>        inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, <span
class="code-object">Boolean</span>.FALSE);
        <span class="code-comment">// set the parameters , <span class="code-keyword">if</span>
you just have one parameter 
</span>        <span class="code-comment">// camel will put <span class="code-keyword">this</span>
object into an <span class="code-object">Object</span>[] itself
</span>        inMessage.setBody(<span class="code-quote">"123"</span>);
    }
    
});
     
<span class="code-comment">// get the response message 
</span>Customer response = (Customer) exchange.getOut().getBody();

assertNotNull(<span class="code-quote">"The response should not be <span class="code-keyword">null</span>
"</span>, response);
assertEquals(<span class="code-quote">"Get a wrong customer id "</span>, <span
class="code-object">String</span>.valueOf(response.getId()), <span class="code-quote">"123"</span>);
assertEquals(<span class="code-quote">"Get a wrong customer name"</span>, response.getName(),
<span class="code-quote">"John"</span>);
</pre>
</div></div> 

<p><a href="http://cwiki.apache.org/CXF20DOC/jax-rs.html" rel="nofollow">CXF JAXRS
front end</a> also provides <a href="http://cxf.apache.org/docs/jax-rs.html#JAX-RS-HTTPcentricclients"
rel="nofollow">a http centric client API</a>, You can also invoke this API from <tt>camel-cxfrs</tt>
producer. You need to specify the HTTP_PATH and Http method and let the the producer know
to use the http centric client by using the URI option <b>httpClientAPI</b> or
set the message header with CxfConstants.CAMEL_CXF_RS_USING_HTTP_API. You can turn the response
object to the type class that you specify with CxfConstants.CAMEL_CXF_RS_RESPONSE_CLASS.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exchange exchange = template.send(<span class="code-quote">"direct:<span
class="code-comment">//http"</span>, <span class="code-keyword">new</span>
Processor() {
</span>
    <span class="code-keyword">public</span> void process(Exchange exchange) <span
class="code-keyword">throws</span> Exception {
        exchange.setPattern(ExchangePattern.InOut);
        Message inMessage = exchange.getIn();
        <span class="code-comment">// using the http central client API
</span>        inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, <span
class="code-object">Boolean</span>.TRUE);
        <span class="code-comment">// set the Http method
</span>        inMessage.setHeader(Exchange.HTTP_METHOD, <span class="code-quote">"GET"</span>);
        <span class="code-comment">// set the relative path
</span>        inMessage.setHeader(Exchange.HTTP_PATH, <span class="code-quote">"/customerservice/customers/123"</span>);
               
        <span class="code-comment">// Specify the response class , cxfrs will use InputStream
as the response object type 
</span>        inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_RESPONSE_CLASS, Customer.class);
        <span class="code-comment">// since we use the Get method, so we don't need
to set the message body
</span>        inMessage.setBody(<span class="code-keyword">null</span>);
               
    }
    
});
     
<span class="code-comment">// get the response message 
</span>Customer response = (Customer) exchange.getOut().getBody();

assertNotNull(<span class="code-quote">"The response should not be <span class="code-keyword">null</span>
"</span>, response);
assertEquals(<span class="code-quote">"Get a wrong customer id "</span>, <span
class="code-object">String</span>.valueOf(response.getId()), <span class="code-quote">"123"</span>);
assertEquals(<span class="code-quote">"Get a wrong customer name"</span>, response.getName(),
<span class="code-quote">"John"</span>);
</pre>
</div></div> 

<p>From Camel 2.1, we also support to specify the query parameters from cxfrs URI for
the CXFRS http centric client.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Exchange exchange = template.send(<span class="code-quote">"cxfrs:<span
class="code-comment">//http://localhost:9003/testQuery?httpClientAPI=<span class="code-keyword">true</span>&amp;q1=12&amp;q2=13"</span></span>
</pre>
</div></div> 
<p>To support the Dynamical routing, you can override the URI's query parameters by
using the CxfConstants.CAMEL_CXF_RS_QUERY_MAP header to set the parameter map for it.To support
the Dynamical routing, you can override the URI's query parameters by using the CxfConstants.CAMEL_CXF_RS_QUERY_MAP
header to set the parameter map for it.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">Map&lt;<span class="code-object">String</span>,
<span class="code-object">String</span>&gt; queryMap = <span class="code-keyword">new</span>
LinkedHashMap&lt;<span class="code-object">String</span>, <span class="code-object">String</span>&gt;();
                   
queryMap.put(<span class="code-quote">"q1"</span>, <span class="code-quote">"<span
class="code-keyword">new</span>"</span>);
queryMap.put(<span class="code-quote">"q2"</span>, <span class="code-quote">"world"</span>);
                   
inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_QUERY_MAP, queryMap);
</pre>
</div></div> 
     </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/CXFRS">View Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=119513&revisedVersion=9&originalVersion=8">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/CXFRS?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message