Creating a protocol bridge has been edited by Bruce Snyder (Jan 22, 2008).

(View changes)

Content:

ServiceMix can be used as a protocol bridge. The following tutorial will explain how to create a JBI Service Assembly (aka a JBI application) to bridge two different protocols. In this example, we will bridge the HTTP/SOAP with the JMS protocol using an InOnly MEP. We will also put between the two protocols an XSLT transformation.
We will leverage ServiceMix archetypes and maven plugin (see Maven JBI plugin).

This tutorial has been written for ServiceMix 3.1. For ServiceMix 3.0, see this page.

Identifying the service units

Our JBI SA (Service Assembly) will be composed of the following SUs (Service Units):

  • an HTTP+SOAP consumer
  • a pipeline to call the XSLT transformer and the JMS provider
  • an XSLT transformer
  • a JMS provider

Directory layout

We aim to have the following project structure:

bridge\
  pom.xml
  bridge-http-su\
    ...
  bridge-eip-su\
    ...
  bridge-xslt-su\
    ...
  bridge-jms-su\
    ...
  bridge-sa\
    ...

Creating the Service Units

In the bridge directory, run the following commands (remove tailing backslashes and make each command on one line) to create the JBI service units (SUs):

mvn archetype:create \
        -DarchetypeGroupId=org.apache.servicemix.tooling \
        -DarchetypeArtifactId=servicemix-http-consumer-service-unit \
        -DarchetypeVersion=3.1-incubating \
        -DgroupId=org.apache.servicemix.samples.bridge \
        -DartifactId=bridge-http-su \
        -DremoteRepositories=http://people.apache.org/repo/m2-incubating-repository

mvn archetype:create \
        -DarchetypeGroupId=org.apache.servicemix.tooling \
        -DarchetypeArtifactId=servicemix-jms-provider-service-unit \
        -DarchetypeVersion=3.1-incubating \
        -DgroupId=org.apache.servicemix.samples.bridge \
        -DartifactId=bridge-jms-su \
        -DremoteRepositories=http://people.apache.org/repo/m2-incubating-repository

mvn archetype:create \
        -DarchetypeGroupId=org.apache.servicemix.tooling \
        -DarchetypeArtifactId=servicemix-eip-service-unit \
        -DarchetypeVersion=3.1-incubating \
        -DgroupId=org.apache.servicemix.samples.bridge \
        -DartifactId=bridge-eip-su \
        -DremoteRepositories=http://people.apache.org/repo/m2-incubating-repository

mvn archetype:create \
        -DarchetypeGroupId=org.apache.servicemix.tooling \
        -DarchetypeArtifactId=servicemix-saxon-xslt-service-unit \
        -DarchetypeVersion=3.1-incubating \
        -DgroupId=org.apache.servicemix.samples.bridge \
        -DartifactId=bridge-xslt-su \
        -DremoteRepositories=http://people.apache.org/repo/m2-incubating-repository

mvn archetype:create \
        -DarchetypeGroupId=org.apache.servicemix.tooling \
        -DarchetypeArtifactId=servicemix-service-assembly \
        -DarchetypeVersion=3.1-incubating \
        -DgroupId=org.apache.servicemix.samples.bridge \
        -DartifactId=bridge-sa \
        -DremoteRepositories=http://people.apache.org/repo/m2-incubating-repository

Main pom

Now that we have created the SUs and SA structure, let's write the main pom.xml (in the bridge directory):

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.apache.servicemix.samples</groupId>
  <artifactId>bridge</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <modules>
    <module>bridge-http-su</module>
    <module>bridge-eip-su</module>
    <module>bridge-xslt-su</module>
    <module>bridge-jms-su</module>
    <module>bridge-sa</module>
  </modules>
</project>

The content of <version> describes not the version of ServiceMix but the SA we create, thus you may change it to your desired version (e.g. 3.0-final). Then you have to change it below as well.

Configure the Service Assembly

We want the JBI Service Assembly to include the 4 SUs that we just created.
So let's edit the bridge-sa pom we created and add the <dependencies> which is a child of <project>:

<dependencies>
  <dependency>
    <groupId>org.apache.servicemix.samples.bridge</groupId>
    <artifactId>bridge-http-su</artifactId>
    <version>1.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>org.apache.servicemix.samples.bridge</groupId>
    <artifactId>bridge-eip-su</artifactId>
    <version>1.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>org.apache.servicemix.samples.bridge</groupId>
    <artifactId>bridge-xslt-su</artifactId>
    <version>1.0-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>org.apache.servicemix.samples.bridge</groupId>
    <artifactId>bridge-jms-su</artifactId>
    <version>1.0-SNAPSHOT</version>
  </dependency>
</dependencies>

Now, we should be able to launch maven and have the SA generated in the bridge-sa/target/ directory. You can check that by running the following command from the bridge/ directory:

mvn install

Of course, it won't work if you deploy it and we now need to fill the holes.

HTTP SU

We need to define a simple HTTP consumer endpoint in the http SU. As we do not use the request / response pattern, we will use an InOnly mep.

<?xml version="1.0"?>
<beans xmlns:http="http://servicemix.apache.org/http/1.0"
       xmlns:b="http://servicemix.apache.org/samples/bridge">

  <http:endpoint service="b:http"
                 endpoint="endpoint"
                 targetService="b:pipeline"
                 role="consumer"
                 locationURI="http://localhost:8192/bridge/"
                 defaultMep="http://www.w3.org/2004/08/wsdl/in-only" />

</beans>

EIP SU

The EIP SU contains the definition of the pipeline pattern, which can be used as a bridge between two InOnly MEPs and an InOut MEP. The XSLT transformer primary MEP is an InOut, as it will receive an incoming message, transform it, and send the answer back to the consumer. But in our case, the HTTP component and JMS component should send and receive an InOnly MEP, hence the need for the Pipeline.

<?xml version="1.0"?>
<beans xmlns:eip="http://servicemix.apache.org/eip/1.0"
       xmlns:b="http://servicemix.apache.org/samples/bridge">

  <eip:pipeline service="b:pipeline" endpoint="endpoint">
    <eip:transformer>
      <eip:exchange-target service="b:xslt" />
    </eip:transformer>
    <eip:target>
      <eip:exchange-target service="b:jms" />
    </eip:target>
  </eip:pipeline>

</beans>

XSLT SU

The XSLT transformation will be deployed on the servicemix-saxon SE using the following xbean.xml configuration file.

<?xml version="1.0"?>
<beans xmlns:saxon="http://servicemix.apache.org/saxon/1.0"
       xmlns:b="http://servicemix.apache.org/samples/bridge">

  <saxon:xslt service="b:xslt" endpoint="endpoint"
              result="string"
              resource="classpath:bridge.xslt" />

</beans>

Note the classpath:bridge.xsdl uri used to point to the XSLT. The classpath is automatically defined by the component and includes the root directory of the SU (see Classloaders).

We need to create the bridge.xslt stylesheet and put in in the src/main/resources directory of this SU, along the xbean.xml configuration file.
Let's use an identity stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

JMS SU

For the JMS provider, we will reuse the embedded ActiveMQ broker which is started with ServiceMix, and output the request in the bridge.output JMS queue.

<?xml version="1.0"?>
<beans xmlns:jms="http://servicemix.apache.org/jms/1.0"
       xmlns:b="http://servicemix.apache.org/samples/bridge">

  <jms:endpoint service="b:jms"
                endpoint="endpoint"
                role="provider"
                destinationStyle="queue"
                jmsProviderDestinationName="bridge.output"
                connectionFactory="#connectionFactory" />

  <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616" />
  </bean>

</beans>

Building, Deploying and Testing

To build the SUs and SA, run the following command in the bridge root directory:

mvn install

Then, deploy the SA and needed components to a started ServiceMix container:

cd bridge-sa
mvn jbi:projectDeploy

Then you can send an HTML POST request to http://localhost:8192/bridge/ and use a jmx console to check that the bridge.output queue contains a jms message.

What's next

Of course, this example is not very useful as is, especially with an identity XSLT sheet. However, adding an xpath router as the target of the pipeline, could be useful to normalize different requests to the same format, because the XSD changed between versions of the service, or because different clients use different XSDs which can be services by the same service.

Powered by Atlassian Confluence (Version: 2.2.9 Build:#527 Sep 07, 2006) - Bug/feature request

Unsubscribe or edit your notifications preferences