blob: ed9a5a5a3a8972cf110772d5a5b148a73f6900de [file] [log] [blame]
h1. servicemix-camel
h2. Overview
The servicemix-camel component provides support for using Apache Camel to provide a full set of Enterprise Integration Patterns and flexible routing and transformation in both Java code or Spring XML to route services on the Normalized Message Router.
h3. Namespace and camel-context.xml
When creating a servicemix-camel service unit, we reuse the default Camel namespace {{http://camel.apache.org/schema/spring}}.
This is an example {{camel-context.xml}} which uses the Spring DSL to define the Camel routes
{code:lang=xml}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<!-- route defined in the Spring DSL -->
</route>
</camelContext>
</beans>
{code}
It is also possible to use the Java DSL inside a servicemix-camel service unit by referring to the package that contains the {{RouteBuilder}} classes. An example: this {{camel-context.xml}} file will activate all routes defined by {{RouteBuilder}}s in the {{org.apache.servicemix.example.camel}} package.
{code:lang=xml}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<packages>org.apache.servicemix.examples.camel</packages>
</camelContext>
</beans>
{code}
h2. URI
Camel routes use URIs to interact with the ESB. You can use these URIs to expose new endpoints on the ESB as well as to send message exchanges to existing endpoints.
The snippet below automatically exposes a new endpoint to the bus, where the service QName is {{{http://foo.bar.org}MyService}} and the endpoint name is {{MyEndpoint}}.
{code:lang=java}
from("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")
{code}
When a JBI endpoint appears at the end of a route, as in the example below, that will send
{code:lang=java}
to("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")
{code}
The messages sent by this producer endpoint are sent to the already deployed JBI endpoint.
h3. URI format
{code}
jbi:service:serviceNamespace[sep]serviceName[?options]
jbi:endpoint:serviceNamespace[sep]serviceName[sep]endpointName[?options]
jbi:name:endpointName[?options]
{code}
The separator that should be used in the endpoint URL is:
* {{/}} (forward slash), if {{serviceNamespace}} starts with {{http://}}
* {{:}} (colon), if {{serviceNamespace}} starts with {{urn:}}.
You can append query options to the URI in the following format, {{?option=value&amp;option=value&amp;...}}
h4. Examples
h5. Using {{jbi:service}}
{code}
jbi:service:http://foo.bar.org/MyService
jbi:service:urn:foo:bar:MyService
{code}
h5. Using {{jbi:endpoint}}
{code}
jbi:endpoint:urn:foo:bar:MyService:MyEndpoint
jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint
{code}
h5. Using {{jbi:name}}
When using {{jbi:name}}, the component uses {{http://activemq.apache.org/camel/schema/jbi}endpoint}} as the default Service QName.
{code}
jbi:name:MyEndpoint
{code}
h3. URI options
|| Name || Default value || Description ||
| {{mep}} | MEP of the Camel Exchange | Allows users to override the MEP set on the Exchange object. Valid values for this option are {{in-only}}, {{in-out}}, {{robust-in-out}} and {{in-optional-out}}. |
| {{operation}} | Value of the {{jbi.operation}} header property | Specifies the JBI operation for the {{MessageExchange}}. If no value is supplied, the JBI binding will use the value of the {{jbi.operation}} header property. |
| {{serialization}} | {{basic}} | Default value ({{basic}}) will check if headers are serializable by looking at the type, setting this option to {{strict}} will detect objects that can not be serialized although they implement the {{Serializable}} interface. Set to {{nocheck}} to disable this check altogether, note that this should only be used for in-memory transports like SEDAFlow, otherwise you can expect to get {{NotSerializableException}} thrown at runtime. |
| {{convertException}} | {{false}} | {{false}}: send any exceptions thrown from the Camel route back unmodified \\ {{true}}: convert all exceptions to a JBI FaultException (can be used to avoid non-serializable exceptions or to implement generic error handling |
h4. Examples
{code}
jbi:service:http://foo.bar.org/MyService?mep=in-out (override the MEP, use InOut JBI MessageExchanges)
jbi:endpoint:urn:foo:bar:MyService:MyEndpoint?mep=in (override the MEP, use InOnly JBI MessageExchanges)
jbi:endpoint:urn:foo:bar:MyService:MyEndpoint?operation={http://www.mycompany.org}AddNumbers
(overide the operation for the JBI Exchange to {http://www.mycompany.org}AddNumbers)
{code}
h2. Example routes
h3. Simple Spring route
This simple Spring route registers a new endpoint on the ESB (service {{{urn:org:example}Router}}, endpoint name {{orders}}). The message exchange contents will be logged and then forwarded to another JBI service endpoint (service {{{http://services.example.org}OrderService}})
{code:lang=xml}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="jbi:endpoint:urn:org:example:Router:orders"/>
<to uri="log:OrderLogging"/>
<to uri="jbi:service:http://services.example.org/OrderService" />
</route>
</camelContext>
</beans>
{code}
h3. The same route using the Java DSL
When we implement the same route in the Java DSL, we first code our {{RouteBuilder}} implementation
{code:lang=java}
package org.apache.servicemix.example;
import org.apache.camel.builder.RouteBuilder;
public class JbiRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
from("jbi:endpoint:urn:org:example:Router:orders")
.to("log:OrderLogging")
.to("jbi:service:http://services.example.org/OrderService");
}
}
{code}
In our {{camel-context.xml}} file, we just refer to the {{org.apache.servicemix.example}} package that contains our {{JbiRouteBuilder}}.
{code:lang=xml}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<packageScan>
<package>org.apache.servicemix.example</package>
</packageScan>
</route>
</camelContext>
</beans>
{code}
h2. Special considerations
h3. Stream handling
If you are using a stream type as the message body, you should be aware that a stream is only capable of being read once. So if you enable {{DEBUG}} logging, the body is usually logged and thus read. To deal with this, Camel has a {{streamCaching}} option that can cache the stream, enabling you to read it multiple times.
{code:lang=java}
from("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")
.streamCaching()
.to("xslt:transform.xsl", "bean:doSomething");
{code}
Camel will cache large input streams (by default, over 64K) in a {{temp}} file using {{CachedOutputStream}}. When you close the input stream, the temp file will be deleted.