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.