View Source

{section}
{column}

{multi-excerpt-include:Petals-SE-Camel|name=features|nopanel=true}

{warning}This version must be installed on [Petals ESB 5.3.0|petalsesb530:Petals ESB 5.3.0]+{warning}
{column}

{column:width=40%}
{panel:title=Table of contents}{toc:outline=true}{panel}
{panel:title=Contributors}{contributors:order=name|mode=list|showAnonymous=true|showCount=true|showLastTime=true}{panel}
{column}
{section}

h1. Introduction

This implementation of the SE Camel uses Apache Camel version 2.20.4.

Routes can be defined using any of the JVM based DSL, as well as using the XML notation.
A Camel route always starts with a *from* declaration, a consumer, and often ends with one or many *to* declaration, producers.
Consumers and producers refers to service external to Camel using an URI: Petals services have their own URI scheme identified with *petals*.

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 one 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.
This is because from the route point of view, messages arriving to the provided service are then consumed by the rule.
{tip}

{tip}
The SOA terminology is sometimes confusing: in the following we will use the general term *service* and operation interchangeably.
{tip}

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

h1. Overview of a Camel Service Unit at Runtime

Each SU has its own Camel context: the Camel context is the runtime entity responsible of executing the routes.
Routes in the same context can refer to each others when needed.

When a JBI exchange arrives for a provided service (an operation), it is transformed to a Camel exchange and dispatched to the route with a petals consumer (in the Camel terminology, i.e. with a *from* declaration using the *petals* URI scheme) the service.

When a Camel exchange is dispatched in a route to a petals producer (in the Camel terminology, i.e. with a *to* declaration using the *petals* URI scheme), it is transformed to a Petals exchange and sent to the corresponding consumes service.

For details on the transformation, see the section [Petals to Camel to Petals|#transformations] below.

h1. Overview of a Camel Service Unit at Implementation Time

h2. Maven Project

When developing with Maven, the pom.xml file must contains the following kind of declarations:
{code:lang=xml}
<!-- ... -->

<!-- We are producing a service unit -->
<groupId>my.group</groupId>
<artifactId>my-service-unit</artifactId>
<version>1.0.0</version>
<packaging>jbi-service-unit</packaging>

<!-- ... -->

<dependencies>
<!-- First a jbi-component dependency to the component (note that it won't provide anything in the classpath!) -->
<dependency>
<groupId>org.ow2.petals</groupId>
<artifactId>petals-se-camel</artifactId>
<version>1.1.0-SNAPSHOT</version>
<type>jbi-component</type>
</dependency>
<!-- Then a dependency to camel, only if you plan to implement routes in Java -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.17.1</version>
<!-- camel-core is provided by the component! -->
<scope>provided</scope>
</dependency>
<!-- optionally, camel-petals provides some Java helpers in org.ow2.petals.camel.helpers -->
<dependency>
<groupId>org.ow2.petals</groupId>
<artifactId>camel-petals</artifactId>
<version>1.1.0-SNAPSHOT</version>
<!-- camel-petals is provided by the component! -->
<scope>provided</scope>
</dependency>
<!-- optionally, petals-se-camel-junit provides some Java testing helpers in org.ow2.petals.camel.junit -->
<dependency>
<groupId>org.ow2.petals</groupId>
<artifactId>petals-se-camel-junit</artifactId>
<version>1.1.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<!-- Maybe other dependencies if you relies on other camel extensions (for xml and java routes).
Note: these extensions are NOT provided by the component and must thus be present with the (default) scope compile. -->
</dependencies>

<!-- ... -->

<build>
<!-- Finally the petals maven plugins to generate JBI zip files -->
<plugins>
<plugin>
<groupId>org.ow2.petals</groupId>
<artifactId>maven-petals-plugin</artifactId>
</plugin>
</plugins>
</build>

<!-- ... -->
{code}

The project structure will follow typical maven projects :
{noformat}
my-service-unit/
+ pom.xml
+ src/
+ main/
+ jbi/
+ jbi.xml
+ service.wsdl (none, one or several)
+ java/.../MyRoutes.java (none, one or several)
+ resources/myroutes.xml (none, one or several)
{noformat}

On top of the typical pom.xml, 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 provides service of the JBI descriptor and of course a JBI descriptor.

h2. Service Unit Content

A Camel SU generated from the previous Maven projects, named my-service-unit-1.0.0.zip will contains the following elements:

{noformat}
my-service-unit-1.0.0.zip
+ META-INF/
+ jbi.xml
+ service.wsdl (none, one or several)
+ my-service-unit-1.0.0.jar
{noformat}

Note that the jar is the generated Jar Maven artefact, and it is included in the generated Zip artefact by the petals maven plugin.

h2. A Camel Route

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

{code:lang=xml}
<!-- we must use the http://camel.apache.org/schema/spring namespace so Camel can load the routes
but Spring JARs are 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>
{code}

{color:red}{*}TODO. make that a real example...*{color}

The only specificity for Petals 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 scheme reserved to petals is *petals*: it is followed by *:* and then the unique id identifying a service's operation.

The rest is typical Camel but some Camel processors are particularly useful to handle Petals exchange from within Camel, such as the jaxb marshaller/unmarshaller or the body conversion.
See the section [Camel Routes|#camel-routes] below for details.

h2. 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 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: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">

<!-- Mandatory CDK specific elements -->
<petalsCDK:operation>hello:sayHello</petalsCDK:operation>
<petalsCDK:mep>InOut</petalsCDK:mep>

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

<!-- These are found in the jar packaged by Maven and included in the JBI Zip -->
<petals-se-camel:xml-routes>routes.xml</petals-se-camel:xml-routes>
<petals-se-camel:java-routes>org.test.ASimpleRoute</petals-se-camel:java-routes>

</jbi:services>
</jbi:jbi>
{code}

{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 (or a default one (imposed by the Camel SE) is used, that is InOut) 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 (or the default one (imposed by the WSDL specification) is used, that is Inout).

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: [Camel DSL Page|http://camel.apache.org/dsl.html].
XML files refer to routes defined used the XML DSL from Camel: [Camel XML Examples|http://camel.apache.org/walk-through-another-example.html].

h1. Semantics of the Send operation (synchronicity, timeouts, etc)

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 [Camel Asynchronous Routing Engine|http://camel.apache.org/asynchronous-routing-engine.html] and [Camel Asynchronous Processing|http://camel.apache.org/asynchronous-processing.html] for technical details.

Nevertheless, it is possible to force synchronous execution:
- of a whole 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 (both 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 and as usual, the value *0* means no timeout.

{anchor:transformations}

h1. Petals to Camel to Petals

Petals (i.e. JBI) and Camel share many concepts to format exchanges.
They both have exchanges with a WSDL MEP, In, Out and Fault messages, as well as Errors.
The main difference is that Camel exchanges do not make mandatory the use of XML for the messages content and that they have no explicit status (the status of Camel exchange is inferred from their content).

{warning}
An error seems to be present in Camel: the InOptionalOut MEP has the wrong URI (ending with in-optional-out instead of in-opt-out according to the WSDL specification).
Note: this will be fixed in Camel 2.16.x and will most certainly be included in version 1.0.0 of the SE.
{warning}

h2. From Petals to Camel

When a new exchange arrives on a provides endpoint, the following happen:

The JBI exchange is transformed to a Camel exchange.
Its properties are put (by reference) into the Camel exchange properties, prefixed by "PetalsOriginalProperty."
Its interface and service names, the endpoint, the operation name and the MEP are put into the Camel exchange properties "PetalsOriginalInterface" (as a QName), "PetalsOriginalService" (as a QName), "PetalsOriginalEndpoint" (as a ServiceEndpoint), "PetalsOriginalOperation" (as a QName), "PetalsOriginalPattern" (as an URI).
Its In normalized message is transformed to a Camel message.
Its properties are put into the Camel message headers (by reference).
Its attachments are put into the Camel message attachments (by reference).
The content of the normalized message (a Source object in Java, containing XML) is put in the body of the Camel message without change.

h3. Service provider configuration

All needed information must be defined in the service-unit JBI descriptor. This JBI descriptor is configured through parameters divided in following groups:
* *JBI parameters* that defines the service provider identification,
* *CDK parameters* that are parameters driving the service provider implementation at CDK layer,
* *CDK interceptor parameters* that are parameters driving interceptors at CDK layer,
* *Dedicated parameters* that are parameters driving the service provider implementation at component layer.

h3. CDK parameters defining service provider implementation
The following parameters correspond to the CDK configuration of the service provider implementation.

{include:0 CDK SU Provide Configuration 5.8.0}

h3. CDK parameters driving interceptors
The following parameters drive interceptors at CDK layer.

{include:0 CDK SU Interceptor configuration 5.8.0}

h3. Dedicated configuration

No specific configuration exists.

h2. From Camel to Petals

When an exchange is sent from Camel to Petals through a consumes endpoint, the following happen:
* The Camel exchange is transformed to a JBI exchange.
* Its properties prefixed by "PetalsProperty." are put (by reference) into the JBI exchange properties (without the prefix).
* Its "In" message is transformed to a normalized message.
* Its headers are put into the normalized exchange properties (by reference).
* Its attachments are put into the normalized message attachments (by reference).
* The body is transformed, using available [Camel type converters|http://camel.apache.org/type-converter.html], to a DOMSource object (or if it is already a Source, it stays as a Source) and put in the content of the normalized message.

The Camel's endpoint "*to*" is defined through an identifier ('{{service-id}}') refering to a service consumer definition in the service unit JBI descriptor.

h3. Specifying the service consumer

The definition of the service consumer is declared in the service unit JBI descriptor, in a section "consumes".

All needed information must be defined in the service-unit JBI descriptor. This JBI descriptor is configured through parameters divided in following groups:
* *JBI parameters* that defines the service provider identification,
* *CDK parameters* that are parameters driving the service consumer implementation at CDK layer,
* *CDK interceptor parameters* that are parameters driving interceptors at CDK layer,
* *Dedicated parameters* that are parameters driving the service consumer implementation at component layer.

h4. CDK parameters defining service provider implementation
The following parameters correspond to the CDK configuration of the service consumer implementation.

{include:0 CDK SU SE Consume Configuration 5.8.0}

h4. CDK parameters driving interceptors
The following parameters drive interceptors at CDK layer.

{include:0 CDK SU Interceptor configuration 5.8.0}

h4. Dedicated configuration

{table-plus}
|| Parameter || Description || Default || Required ||
| service-id | The reference of the service consumer. This value is used, prefixed with '{{petals:}}', in the Camel route's endpoint "*to*". | {center}\-{center} | {center}Yes{center} |
{table-plus}

h4. Override parameters of the service consumer directly from the Camel's route

One way to influence the service, endpoint, operation names and the MEP is to set parameters on the endpoint URI in the Camel route like this:

{code:lang=java}
@Override
public void configure() throws Exception {
from("petals:theProvidesId").to("petals:theConsumesId?serviceName={http://a.com/namespace}AService&endpointName=edpt-name&operation={http://a.com/namespace}anOperation&exchangePattern=InOut");
}
{code}

Of course each can be used alone or together, but the following rules always apply:
* If a parameter is set in the Consumes, it can't be set in the Camel endpoint URI
* endpointName can only be set if either the Consumes or the endpoint URI have a serviceName set

h4. Using the MEP of the Camel exchange

Even though it's not the most recommended (because of its implicit nature), if no MEP is set neither on the Consumes or the Camel endpoint URI, then the MEP of the Camel exchange will be used.

h2. Back to Camel from Petals

When an answer to an exchange sent to Petals arrives back to Camel through a consumes endpoint, the following happen:
* The Camel exchange properties prefixed by "*PetalsProperty.*" are updated from the JBI exchange properties (by reference).
* If the exchange has the *error* status, the exception is put in the exchange.
* If the exchange has a *Fault*, it is transformed to a Camel message (same process as before), the fault status is set on it and put as the exchange's Out.
* If the exchange has an *Out*, it is transformed to a Camel message (same process as before) and put as the exchange's Out.

h2. Back to Petals from Camel

When an answer to an exchange sent to Camel from Petals arrives back to Petals through a provides endpoint, the following happen:
* The JBI exchange properties are updated (by reference) with the Camel exchange properties prefixed by "*PetalsOriginalProperty*." (without the prefix).
* If the exchange has an *Exception*, the exception is put as the JBI exchange's error and its status is set to "*error*".
* If the exchange has a *Fault*, it is transformed to a normalized message of type "*fault*" (same process as before) and put as the JBI exchange's Fault.
* If the exchange has an "*Out*" and it is an "*InOut*" or an "*InOptionalOut*", it is transformed to a normalized message (same process as before) and put as the JBI exchange's Out.
* If the exchange has no "*Out*" and it is an "*InOut*" exchange, its In message is transformed to a normalized message (same process as before) and put as the JBI exchange's Out.
* In all the other cases, the exchange's status is changed to done.

{warning}
Some Camel processors are made to work in-place with an "*In*" message without making an "*Out*" message: because of this practice (see http://camel.apache.org/using-getin-or-getout-methods-on-exchange.html), we have to make the assumption that an "*InOptionalOut*" Camel message MUST have an "*Out*" message for the exchange to be considered not done!
In other words: before sending an "*InOptionalOut*" message that has an "*Out*" message back to Petals, make sure that the answer is not in the "*In*" but in the "*Out*" message of the Camel exchange.
{warning}

h1. Manipulating JBI faults in a Camel route

Apache Camel does not support advanced manipulation of faults through their {{Exchange}}/{{Message}} API:
* if a message is marked as being a fault (via {{Message.isFault}}), it won't be possible in a Camel route to process it as a normal message.
* The route will simply stop its processing.
* This is because Camel does not encourage a WSDL-oriented paradigm of defining exchanges like JBI do.

Hence, the Camel SE introduces some helpers (in {{camel-petals}}'s {{PetalsRouteBuilder}}) to reand and mark messages as faults outside of the facilities provided by Camel.

Basically, static methods are available to test if an {{Exchange}} is failed or a {{Message}} is a fault, as well as to set them as fault.
They add an extra header to the exchange to mark the out message.
The message itself is just a message like any other.

The helpers also allow for stopping the routing when setting a fault, if desired.

h1. Examples

Some examples are available with the SE.
They show how to define Java or XML-based Camel routes in a Petals SU.

They also illustrates the use of the route helpers available from {{camel-petals}} and of the junit helpers available from {{petals-se-camel-junit}}.

See https://github.com/petalslink/petals-se-camel/tree/master/samples.

h1. Configuring the component

The component can be configured through the parameters of its JBI descriptor file. These parameters are divided in following groups:
* *JBI parameters* that have not to be changed otherwise the component will not work,
* *CDK parameters* that are parameters driving the processing of the CDK layer,
* *Dedicated parameters* that are parameters specific to this component.

h2. CDK parameters
The component configuration includes the configuration of the CDK. The following parameters correspond to the CDK configuration.

{include:0 CDK Component Configuration Table 5.8.0}

h2. Interception configuration
{include:0 CDK Component Interceptor configuration 5.8.0}

h2. Dedicated configuration

No dedicated configuration parameter is available.

h1. Monitoring the component

h2. Using metrics

Several probes providing metrics are included in the component, and are available through the JMX MBean '{{org.ow2.petals:type=custom,name=monitoring_*<component-id>*}}', where {{*<component-id>*}} is the unique JBI identifier of the component.

h3. Common metrics

{include:0 CDK Component Monitoring Metrics 5.6.0}

h3. Dedicated metrics

No dedicated metric is available.

h2. Receiving alerts

Several alerts are notified by the component through notification of the JMX MBean '{{org.ow2.petals:type=custom,name=monitoring_*<component-id>*}}', where {{*<component-id>*}} is the unique JBI identifier of the component.

{tip}To integrate these alerts with Nagios, see [petalsesbsnapshot:Receiving Petals ESB defects in Nagios].{tip}

h3. Common alerts

{include:0 CDK Component Monitoring Alerts 5.6.0}

h3. Dedicated alerts

No dedicated alert is available.

h1. Business monitoring

h2. MONIT traces

{include:0 CDK SE Business Monitoring Traces 5.8.0}

h2. Flow tracing activation

{include:0 CDK SE Business Monitoring Flow Tracing Activation 5.8.0}

h2. Flow tracing propagation

{include:0 CDK SE Business Monitoring Flow Tracing Propagation 5.8.0}