# JBI

## JBI Component

The jbi component is implemented by the ServiceMix Camel module and provides integration with a JBI Normalized Message Router, such as the one provided by Apache ServiceMix.

| Important
See below for information about how to use `StreamSource` types from ServiceMix in Apache Camel.

The following code:

    from("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")

Automatically exposes a new endpoint to the bus, where the service QName is `{http://foo.bar.org}MyService` and the endpoint name is `MyEndpoint` (see URI format).

When a JBI endpoint appears at the end of a route, for example:

    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://`, or

- `:` (colon), if `serviceNamespace` starts with `urn:foo:bar`.

For more details of valid JBI URIs see the ServiceMix URI Guide.

Using the `jbi:service:` or `jbi:endpoint:` URI formats sets the service QName on the JBI endpoint to the one specified. Otherwise, the default Apache Camel JBI Service QName is used, which is:

    {http://activemq.apache.org/camel/schema/jbi}endpoint

You can append query options to the URI in the following format, `?option=value&option=value&...`

## Examples

    jbi:service:http://foo.bar.org/MyService
    jbi:endpoint:urn:foo:bar:MyService:MyEndpoint
    jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint
    jbi:name:cheese

## 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)

## Using Stream bodies

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, Apache 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");

From Apache Camel 1.5 onwards, the stream caching is default enabled, so it is not necessary to set the `streamCaching()` option.

In Apache Camel 2.0 we store big input streams (by default, over 64K) in a `temp` file using `CachedOutputStream`. When you close the input stream, the temp file will be deleted.

## Creating a JBI Service Unit

If you have some Apache Camel routes that you want to deploy inside JBI as a Service Unit, you can use the JBI Service Unit Archetype to create a new Maven project for the Service Unit.

If you have an existing Maven project that you need to convert into a JBI Service Unit, you may want to consult ServiceMix Maven JBI Plugins for further help. The key steps are as follows:

- Create a Spring XML file at `src/main/resources/camel-context.xml` to bootstrap your routes inside the JBI Service Unit.

- Change the POM file's packaging to `jbi-service-unit`.

Your `pom.xml` should look something like this to enable the `jbi-service-unit` packaging:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

      <modelVersion>4.0.0</modelVersion>

      <groupId>myGroupId</groupId>
      <artifactId>myArtifactId</artifactId>
      <packaging>jbi-service-unit</packaging>
      <version>1.0-SNAPSHOT</version>

      <name>A Apache Camel based JBI Service Unit</name>

      <url>http://www.myorganization.org</url>

      <properties>
        <camel-version>1.0.0</camel-version>
        <servicemix-version>3.3</servicemix-version>
      </properties>

      <dependencies>
        <dependency>
          <groupId>org.apache.servicemix</groupId>
          <artifactId>servicemix-camel</artifactId>
          <version>${servicemix-version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.servicemix</groupId>
          <artifactId>servicemix-core</artifactId>
          <version>${servicemix-version}</version>
          <scope>provided</scope>
        </dependency>
      </dependencies>

      <build>
        <defaultGoal>install</defaultGoal>

        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.5</source>
              <target>1.5</target>
            </configuration>
          </plugin>

          <!-- creates the JBI deployment unit -->
          <plugin>
            <groupId>org.apache.servicemix.tooling</groupId>
            <artifactId>jbi-maven-plugin</artifactId>
            <version>${servicemix-version}</version>
            <extensions>true</extensions>
          </plugin>
        </plugins>
      </build>
    </project>

For more information, see the following references:

- ServiceMix Camel module

- Using Camel with ServiceMix

- Cookbook on using Camel with ServiceMix

## JBI Service Unit Archetype

If you want to spin up your own project to use Apache Camel to perform some smart routing inside your JBI based ESB you can use the Maven archtetype to get up to speed quickly.

Just type the following into a console...

    mvn archetype:create                           \
      -DarchetypeGroupId=org.apache.camel          \
      -DarchetypeArtifactId=camel-jbi-service-unit \
      -DarchetypeVersion=1.0-SNAPSHOT              \
      -DgroupId=myGroupId                          \
      -DartifactId=myArtifactId

This will create a maven project which can be run immediately via the Camel Maven Plugin as follows

    cd myArtifactId
    mvn install

The configuration file is in `src/main/resources/camel-context.xml`.

The routing rules lives at `src/main/java/myGroupId/MyRouteBuilder.java`.