Petals-SE-Camel 1.0.0-SNAPSHOT

Features

The component SE Camel embeds the Apache Camel routing engine to execute enterprise integration patterns (EIP) in Petals.

Service Units can be written to describe, for a given provided Petals endpoint, how and where messages should be routed.

Even if it is recommended to route messages toward other Petals services, it is still always possible to exploit Camel transports to integrate with non-Petals external services.

Contributors
No contributors found for: authors on selected page(s)

Introduction

This implementation of the SE Camel uses Camel version 2.15.0.

Routes can be defined using any of the JVM based DSL, as well as using the XML notation.
For each provides section, exactly one route must be present and will be activated when a message is received.
Each route can call any service declared in a consumes section.

Consumes corresponds to an operation of a service and have a MEP defined.
*Provides corresponds to a service defined with WSDL and for which every operation has a corresponding route.

The terminology used by Camel is apparently counter-intuitive to the one used in JBI terminology: a camel route consumes a service while an SU provides this same service.
This is because from the route point of view, messages arriving to the provided service are then consumed by the rule.

We show in the next section a general overview of a typical Service Unit.

Overview of a Camel Service Unit at Implementation Time

Service Unit Content

A Camel SU typically contains the following elements:

su-camel-ServiceName-provide.zip
   + META-INF
     - jbi.xml
   + service.wsdl (one or several)
   + route-implementation.jar (none, one or several)
   + route-implementation.xml (none, one or several)

There must be at least one route implementation per operation of the provides, in a jar file or an xml file, a WSDL description for every service declared in the JBI descriptor and of course a JBI descriptor.

A Camel Route

Here is an example of a Camel route defined in XML:

  <!-- we must still use the http://camel.apache.org/schema/spring namespace so Camel can load the routes
       though Spring JARs is not required -->
  <routes xmlns="http://camel.apache.org/schema/spring">
    <route>
      <from uri="petals:incomingOrders" />
      <convertBodyTo type="java.lang.String" />
      <choice>
        <when>
          <simple>${body} contains '?xml'</simple>
          <unmarshal>
            <jaxb contextPath="org.fusesource.camel" />
          </unmarshal>
          <to uri="petals:orders" />
        </when>
        <otherwise>
          <unmarshal>
            <bindy packages="org.fusesource.camel" type="Csv" />
          </unmarshal>
          <to uri="petals:orders2" />
        </otherwise>
      </choice>
    </route>
  <routes>

TODO. make that a real example, this is copied from an example on the web...

The only specificity of this route are the URIs used to identify the services consumed by the route (from element) and to which messages are then sent (to element).
The protocol reserved to petals is petals and it is followed by : and then the unique id identifying a service's operation.

One can refer to provides services with from() and to consumes services with to().

TODO. Add some explanation on how to use direct: and seda: URIs from Camel to call local routes, how to marshal and unmarshal, how to convert bodies, etc

JBI Descriptor and WSDL definition

The JBI descriptor contains:

  • The services that are provided by this SU for which routes will handle messages, and
  • The services consumed by this SU that will be callable from the route.

In order to identify a service's operation, each of the operation, provided or consumed, must have a unique id.
Of course, a provided service's operation will be only usable by from elements and consumed services by to elements.

<?xml version="1.0" encoding="UTF-8"?>
<jbi:jbi version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jbi="http://java.sun.com/xml/ns/jbi"
   xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-5" xmlns:petals-se-camel="http://petals.ow2.org/components/petals-se-camel/jbi/version-1.0"
   xmlns:hello="http://petals.ow2.org">

   <jbi:services binding-component="false">

      <jbi:provides interface-name="hello:HelloInterface" service-name="hello:HelloService" endpoint-name="autogenerate">
         <petalsCDK:wsdl>service.wsdl</petalsCDK:wsdl>
      </jbi:provides>

      <jbi:consumes interface-name="hello:HelloInterface" service-name="hello:HelloService">
         
         <!-- CDK specific elements -->
         <petalsCDK:operation>hello:sayHello</petalsCDK:operation>
         <petalsCDK:mep>InOut</petalsCDK:mep>

         <!-- Component specific elements -->
         <petals-se-camel:service-id>theConsumesId</petals-se-camel:service-id>
      </jbi:consumes>

      <petals-se-camel:routes>
         <petals-se-camel:xml-file>routes.xml</petals-se-camel:xml-file>
         <petals-se-camel:java-class>org.test.ASimpleRoute</petals-se-camel:java-class>
      </petals-se-camel:routes>

   </jbi:services>
</jbi:jbi>
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://petals.ow2.org" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
   xmlns:tns="http://petals.ow2.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:petals-camel-wsdl="http://petals.ow2.org/components/petals-se-camel/wsdl/version-1.0">
   <wsdl:types>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://petals.ow2.org"
         elementFormDefault="unqualified" targetNamespace="http://petals.ow2.org" version="1.0">
         <xs:element name="sayHello" type="tns:sayHello" />
         <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />
         <xs:complexType name="sayHello">
            <xs:sequence>
               <xs:element minOccurs="0" name="arg0" type="xs:string" />
            </xs:sequence>
         </xs:complexType>
         <xs:complexType name="sayHelloResponse">
            <xs:sequence>
               <xs:element minOccurs="0" name="return" type="xs:string" />
            </xs:sequence>
         </xs:complexType>
      </xs:schema>
   </wsdl:types>
   <wsdl:message name="sayHelloResponse">
      <wsdl:part name="parameters" element="tns:sayHelloResponse" />
   </wsdl:message>
   <wsdl:message name="sayHello">
      <wsdl:part name="parameters" element="tns:sayHello" />
   </wsdl:message>
   <wsdl:portType name="HelloInterface">
      <wsdl:operation name="sayHello">
         <wsdl:input name="sayHello" message="tns:sayHello" />
         <wsdl:output name="sayHelloResponse" message="tns:sayHelloResponse" />
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="HelloServiceBinding" type="tns:HelloInterface">
      <wsdl:operation name="sayHello">
         <petals-camel-wsdl:operation service-id="theProvidesId" />
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="HelloService">
      <wsdl:port name="autogenerate" binding="tns:HelloServiceBinding" />
   </wsdl:service>
</wsdl:definitions>

In these two snippets, the important parts are the elements with the namespace URI http://petals.ow2.org/components/petals-se-camel/jbi/version-1.0 for the JBI and http://petals.ow2.org/components/petals-se-camel/wsdl/version-1.0 for the WSDL.

The first one enables to define the service id for a consumes in the JBI: notice that the consumes must also have a MEP and an operation set.

The second one enables to define the service id for the operation of a provides in the binding section of the WSDL definition: again the operation must have an MEP set.

Finally, the services section of the JBI contains a list of routes to be loaded by the Camel SE.
Two types of route definitions can be used: java classes and XML files.
Java classes refer to classes that extends the Camel RouteBuilder abstract class, i.e. routes written with any of the JVM-based DSLs: http://camel.apache.org/dsl.html
XML files refer to routes defined used the XML DSL from Camel.

Overview of a Camel Service Unit at Runtime

Camel routes are instantiated in a Camel context.
With the SE Camel, for every SU, there is one Camel context created containing all the routes described in the SU.

When a message arrives on a provided service, it is dispatched to the route that consumes the service.

By default, the execution is asynchronous: it means that if one of the processor or producer on the route needs to do blocking operations, the processing won't keep the CDK thread that received the message busy and it will continue execution when it is time to depending on the blocked processor.
This has no impact on how the routes are implemented, but in term of execution, it means that threads are not blocked and resources are often freed as soon as possible.
See http://camel.apache.org/asynchronous-routing-engine.html and http://camel.apache.org/asynchronous-processing.html for details.

Nevertheless, it is possible to force synchronous execution:

  • of a route either by adding the synchronous argument to the Camel from URI, or
  • of a service invocation when calling an external petals services using a to with the same argument.

It is also possible to have a timeout (for synchronous and asynchronous mode) to specify how long we should wait before failing a service invocation done with to by using the timeout option.
Note: by default, it will use the value specified in the JBI consumes section. The value 0 means no timeout.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.