JBI Support deprecated in Apache ServiceMix 4
JBI 1.0 support is available in Apache ServiceMix 4 to allow existing users to migrate more easily to this latest version - if you're a new user, you should consider JBI deprecated and not use it for your project. Take a look at our technology selection guidelines for more information.
servicemix-camel
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.
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
<?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>
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 RouteBuilders in the org.apache.servicemix.example.camel package.
<?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>
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 MyService and the endpoint name is MyEndpoint.
from("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")
When a JBI endpoint appears at the end of a route, as in the example below, that will send
to("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")
The messages sent by this producer endpoint are sent to the already deployed JBI endpoint.
URI format
jbi:service:serviceNamespace[sep]serviceName[?options]
jbi:endpoint:serviceNamespace[sep]serviceName[sep]endpointName[?options]
jbi:name:endpointName[?options]
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&ption=value&..
Examples
Using jbi:service
jbi:service:http://foo.bar.org/MyService
jbi:service:urn:foo:bar:MyService
Using jbi:endpoint
jbi:endpoint:urn:foo:bar:MyService:MyEndpoint
jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint
Using jbi:name
When using jbi:name, the component uses http://activemq.apache.org/camel/schema/jbi}endpoint as the default Service QName.
jbi:name:MyEndpoint
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 |
Examples
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)
Example routes
Simple Spring route
This simple Spring route registers a new endpoint on the ESB (service Router, endpoint name orders). The message exchange contents will be logged and then forwarded to another JBI service endpoint (service OrderService)
<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>
The same route using the Java DSL
When we implement the same route in the Java DSL, we first code our RouteBuilder implementation
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");
}
}
In our camel-context.xml file, we just refer to the org.apache.servicemix.example package that contains our JbiRouteBuilder.
<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>
Special considerations
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.
from("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")
.streamCaching()
.to("xslt:transform.xsl", "bean:doSomething");
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.