Petals-SE-Camel 1.0.0-SNAPSHOT

compared with
Version 9 by Victor NOËL
on Mar 26, 2015 14:50.

Key
This line was removed.
This word was removed. This word was added.
This line was added.

Changes (45)

View Page History
h1. Introduction

This implementation of the SE Camel uses Camel version 2.14.X. 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, one or many routes can be activated when a message is received.
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.

{tip}
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.
{noformat}

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

h2. A Camel Route

{code:lang=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 id="NormalizeMessageData">
<from uri="petals:incomingOrders" />
<convertBodyTo type="java.lang.String" />
</choice>
</route>
<routes>
{code}


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, and optionally an operation to be invoked. service's operation.

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

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

{petalslink}
{color:red}{*}TODO-1: An alternative solution proposed by Bertrand is to assign to each provides a list of route-ids that are defined in the camel routes: the problem with that is that we go outside of the camel philosophy that prefer to have self-contained routes.*{color}
CDE:
* Cette solution implique une double synchro entre "jbi.xml" et la description des routes Camel:
** la description des routes va référencer les consumes et provides définis dans le jbi.xml
** le route-id présent dans le jbi.xml devant être aligné avec celui de la description des routes.
Je ne suis pas très partisan de ces route-id qui me semblent n'apportent rien à part etre obligé à une double modification au cas où.
h2. JBI Descriptor and WSDL definition

{color:red}{*}TODO-2: An alternative solution proposed by Bertrand is to directly refer to the service-oriented naming of endpoints (Interface/Service/Endpoint) in the routes and then to verify if they are things declared in the JBI.*{color}
CDE: Pour le from, la notion d'endpoint ne sert à rien car quand on recoit le message on est déjà dans le context du endpoint. Pour le 'to' la difficulté va être une invaocation avec l'endpoint autogénéré. Et là je pense qu'il va falloir prévoir le keyword 'autogenerate' comme pour le WSDL.
{petalslink}

h2. JBI Descriptor

The JBI descriptor contains:
* The services that are provided by this SU and for which routes will handle messages, and
* The services consumed by this SU and that will be callable from the route.

In order to identify a service, each of the, provided or consumed, service must have a unique id.
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.


{code:lang=xml}
<?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:xsi="http://www.w3.org/2001/XMLSchema-instance" 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:jbi="http://java.sun.com/xml/ns/jbi" xmlns:hello="http://petals.ow2.org">
xmlns:petalsCDK="http://petals.ow2.org/components/extensions/version-5"
xmlns:helloworld="http://petals.ow2.org/helloworld"
xmlns:camel="http://petals.ow2.org/components/camel/version-1">

<jbi:services binding-component="false">
<jbi:provides
interface-name="helloworld:Helloworld"
service-name="helloworld:HelloworldService"
endpoint-name="HelloworldEndpoint">
<petalsCDK:wsdl>service.wsdl</petalsCDK:wsdl>
<camel:service-id>incomingOrders</camel:class>
</jbi:provides>
<jbi:consumes
interface-name="sample:calledInterface1"
service-name="sample:calledService1"
endpoint-name="calledEndpoint1">
<camel:service-id>orders</camel:class>
</jbi:consumes>
<jbi:consumes
interface-name="sample:calledInterface2"
service-name="sample:calledService2"
endpoint-name="calledEndpoint2">
<camel:service-id>orders2</camel:class>
</jbi:consumes>
<camel:routes>
<camel:xml-route>route-implementation.xml</camel:xml-route>
<camel:jvm-route>org.example.RouteImplementation</camel:jvm-route>
<camel:jvm-route>org.example.RouteImplementation2</camel:jvm-route>
</camel:routes>
</jbi:services>
</jbi:jbi>
{code}

{color:red}{*}TODO. make that a real example, this is copied from jsi181 with bits of EIP and a mock-up for camel:routes...*{color}
<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>

h3. Provides Section
<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>

{include:0 CDK SU Provide Configuration}
</jbi:services>
</jbi:jbi>
{code}

{center}{*}Configuration of a Service Unit to provide a service (Camel)*{center}
{table-plus} {code:lang=xml}
<?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>
{code}

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.

|| Parameter || Description || Default || Required ||
| service-id | The unique id in the SU for the provided service. It will be visible from the route to refer to this service. | {center}\-{center} | {center}Yes{center} |
{table-plus}

h3. Consumes Section

{include:0 JBI SU Consume Configuration}

{center}{*}Configuration of a Service Unit to consume a service (Camel)*{center}
{table-plus}





|| Parameter || Description || Default || Required ||
| service-id | The unique id in the SU for the consumed service. It will be visible from the route to refer to this service. | {center}\-{center} | {center}Yes{center} |
{table-plus}

h3. Services Section

{color:red}{*}TODO. Not sure this should be in the service section... this seems to be the natural place for it to be because it is not bound to a specific service but to the whole SU...*{color}
{color:red}{*}TODO. Is there an include also with a table for the whole services section?*{color}

h1. Overview of a Camel Service Unit at Runtime

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 all the routes that consumes the service.
There is no guarantee of order of the route executed nor guarantee of either parallel or sequential execution of the routes.

{color:red}{*}TODO. This is of course open to discussion.*{color}
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.