Exploring Java Business Integration with Apache ServiceMix

November 6th, 2009 by Henri Bezemer

Introduction

Apache ServiceMix is an Enterprise Service Bus that is compliant to the Java Business Integration specification (JBI). In a nutshell, the JBI specification defines a robust and managed environment which supports components called Binding Components (BC’s) and Service Engines (SE’s), that exchange XML messages (with optional binary attachments) with each other. The goal of a Binding Component is to convert messages to and from a specific protocol (like SOAP over HTTP) to allow communication with the outside world. The goal of a Service Engine is to provide business logic (like message transformation, message routing, or any other type of business logic).

You typically don’t develop BC and SE’s yourself. Usually an ESB (JBI or non-JBI compliant) comes packed with a rich set of components, ranging from very simple ones (like an email BC) to very complex ones (like a WS-BPEL Service Engine). You have to select the right components for the job at hand and instruct them what to do. Some components may require simple configuration through xml, others may require writing Java (or other programming language) code while other may require you to create even higher level constructs like XSLT style sheets or BPEL modules.

The JBI specification defines how BC’s and SE’s “click” into a JBI environment, but it doesn’t say what functionality components should provide. Creating instructions for a JBI component is component-specific and possibly vendor specific. It is wise to choose components that comply with a standard (like the WS-BPEL SE mentioned earlier). This prevents vendor lock in.

The JBI specification defines a deployment packaging for the instructions that you write for components (called service units). These are not unlike the jar files which are being used in an EJB environment. A collection of service units is called a service assembly, which resembles EJB’s ear file (zip of zips).

A simple test of ServiceMix

In this post we create a simple service assembly containing one simple service unit. We use ServiceMix’s standard file BC which allows simple message exchange with the file system. Besides Apache ServiceMix (version 3.3.1) I’ll use Maven 2 to create the deployment packages. An IDE like Eclipse is useful to create the Maven POMs and some xml files, but if you want you can use any simple file editor. I’ve given a short explanation of Maven and the m2eclipse Eclipse plugin in a previous post (http://www.zienit.nl/blog/2009/11/enterprise-java/web-services-made-easy-with-ejb-jpa-and-jax-ws). Please read this to get a better understanding of the next steps.

In Eclipse we create two projects, one for the service unit and one for the service assembly. Use Eclipse to create a Maven enabled project called simplepoller (skip archetype selection). Edit the POM in the root of the project to look like this:

<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>com.zienit.simplejbi</groupId>
    <artifactId>simplepoller</artifactId>
    <packaging>jbi-service-unit</packaging>
    <name>simplepoller</name>
    <version>0.0.1-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.servicemix</groupId>
            <artifactId>servicemix-file</artifactId>
            <version>2009.01</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.servicemix.tooling</groupId>
                <artifactId>jbi-maven-plugin</artifactId>
                <version>4.1</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>

 Note the following things in this POM:

  • The packaging is jbi-service-unit.
  • There is a dependency on the jbi-maven-plugin, which will take care of the packaging. Note that the version is not 3.3.1 (equal to the ServiceMix version) because that version does not exist in any Maven Repository. So I’m using the latest version I could find (4.1). This works fine.
  • The jbi-maven-plugin will create a file jbi.xml and store it into the META-INF directory of the resulting package. This file is required by the specification. Because the plug-in completely takes care of its creation, I won’t explain this file any further.
  • We have to specific y at which component this service unit is targeted. The jbi-maven-plugin expects this component to be specified in the form of a regular Maven dependency. Therefore a dependency on artifact servicemix-file is defined. Note that the version is 2009.01. This is the actual version of the component as it is bundled with ServiceMix 3.1.1. You can find the correct version of the components by taking a look at the files in the hotdeploy subdirectory of the ServiceMix installation.

The second file that we create in simplepoller contains the actual configuration for the file BC. The file must be called xbean.xml and must be stored in the project’s subdirectory /src/main/resources:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:file="http://servicemix.apache.org/file/1.0"
    xmlns:foo="http://servicemix.org/demo/">
    <file:poller
        service="foo:filePoller"
        endpoint="filePoller"
        targetService="foo:fileSender"
        file="inbox"
        deleteFile="true"
        archive="archive"/>
    <file:sender
        service="foo:fileSender"
        endpoint="sender"
        directory="outbox"
        append="true"/>                           
</beans>

xbean.xml defines two so called endpoints. An endpoint exists within a service. A service name must be a qualified name. In this example there are two services called filePoller and fileSender respectively, both with a namespace URI of http://servicemix.org/demo/). An endpoint’s name (which is not a qualified name) must be unique for its service.

The messages (files) picked up at the filePoller endpoint are forwarded to a target endpoint. Here we provide only the name of the target service. This is specific enough because there exists only one endpoint within this service. The files are picked up from the inbox subdirectory (relative to the installation directory of ServiceMix). After successful processing, this file is deleted and a copy is stored in the archive subdirectory.

The messages arriving at the sender endpoint are stored in the outbox directory. If the file already exists, its content will be append to the existing file (a process resulting in ill-formed XML!).

Package the service unit by running Maven install.

The service assembly

Create another Eclipse project called simpleassembly analogous to the simplepoller. This project will only contain the following POM:

<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>com.zienit.simplejbi</groupId>
    <artifactId>simpleassembly</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jbi-service-assembly</packaging>
    <name>simple</name>
    <dependencies>
        <dependency>
            <groupId>com.zienit.simplejbi</groupId>
            <artifactId>simplepoller</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.servicemix.tooling</groupId>
                <artifactId>jbi-maven-plugin</artifactId>
                <version>4.1</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>

This POM has two notable things:

  • The packaging is jbi-service-assembly.
  • Regular Maven dependencies define which service units to include in the assembly.

Run Maven install to create the assembly.

Deployment and test

The service assembly must be dropped on the subdirectory hotdeploy (relative to ServiceMix’s installation directory). Once started, you can drop xml files in the inbox directory. Watch them disappear and pop up in the outbox directory. If you drop an ill-formed xml file in the inbox, you’ll see parse exceptions in the ServiceMix console.

A good way to get some insight into ServiceMix’ operation is through JMX. Start jconsole that comes with the JDK.  Select the advanced tab, enter JMX URL service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi , user smx and password smx. You can now explore ServiceMix’ static and runtime data.

In this post we’ve established a simple environment to develop JBI service units and service assemblies for Apache ServiceMix. In a future post I’ll be looking at more complex use cases of ServiceMix.

One Comment

November 21, 2009 at 12:35 pm Paweł Ryznar

1

hi :)
Link to post “web services made easy with ejb jpa and jax ws” is wrong. This post don’t exist.