maandag 29 oktober 2007

Using Petals JBI components in ServiceMix

In the previous post I wrote the steps you need to take to get a component from openESB to run inside ServiceMix. That wasn't too complex, the main part there was to fix some jar conflicts, and write the wsdl configuration without the Netbeans openESB plugin.

OpenESB and ServiceMix aren't the only two JBI based ESBs. From ObjectWeb we've also got Petals, and they've recently released Petals 2.0.

About a month ago I tried getting Petals' components to work with ServiceMix, but ran into some strange problems where it was missing some property in it's configuration. I didn't look into that at that time, and moved on to playing around some more with openESB.

So now with a new version of Petals out I decided to try it's components again. I downloaded the latest release, dropped the pojo service engine inside the deploy directory and everything seemed to be working. So I made a simple SU deployed it, and ran into a problem where it couldn't find the method to send the message exchange to. I couldn't find the sources of the service engine, so I got the latest SVN versions and tried from there.

Although there are some bugs in the latest version from SVN, they changed some package and namespaces, after some trivial fixes everything was working nicely.

To get the POJO service engine working in ServiceMix from the petals SVN you roughly have to follow the following steps:

1. Fix the JBI descriptor for the pojo-se component
Change the bootstrap class name from:

org.objectweb.petals.component.framework.DefaultBootstrap
to:
org.ow2.petals.component.framework.DefaultBootstrap

And also change the petal namespace definition to:
xmlns:petals="http://petals.ow2.org/extensions"

2. Deploy the JBI component
Just drop this altered pojo-se component in the servicemix deploy directory and you'll see some log messages coming by showing you that the component is successfully installed.

3. Create the pojo to deploy to this component

I think there is a bug here, the component now forces you to use the org.ow2.petals.component.framework.util.Exchange in your pojo instead of a normal jbi messageexchange. In previous versions the onMessageExchange message needed to accept the interface class, not the petals specific implementation. But that's what you get for using code fresh from SVN.


package opensource.esb.servicemix.chapter6.petals;

import javax.jbi.component.ComponentContext;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.MessageExchange;

import org.ow2.petals.component.framework.util.Exchange;

public class PetalsPojo {

private DeliveryChannel channel;
private ComponentContext ctx;

public void setChannel(DeliveryChannel channel) {
System.out.println("Channel set:" + channel);
this.channel = channel;
}

public void setCtx(ComponentContext ctx) {
System.out.println("ComponentContext set:" + ctx);
this.ctx = ctx;
}


public boolean onExchange(Exchange exchange) throws Exception {
System.out.println("MessageExchange received:" + exchange);
return false;
}

public void init() {
System.out.println("Initializing: " + this);
}

public void start() {
System.out.println("Starting:" + this );
}

public void stop() {
System.out.println("Stopping:" + this);
}
}


4. Create a configuration file
This part isn't that well documented on the site, perhaps again because they seem to are in the process of switching namespaces, packaging and the manner of configuration. However looking through the code, and the schemas, I came to the following jbi.xml which works.


<jbi version="1.0" xmlns='http://java.sun.com/xml/ns/jbi'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:petals="http://petals.ow2.org/extensions">
<services binding-component="false">
<provides interface-name= "petals:SamplePojoInterface"
service-name = "petals:SamplePojoService"
endpoint-name = "SamplePojoEndpoint">
<petals:wsdl/>
<petals:su-interceptors/>
<petals:params>
<petals:param name="class-name">opensource.esb.servicemix.chapter6.petals.PetalsPojo</petals:param>
</petals:params>
</provides>
</services>
</jbi>


This registers an endpoint and service. Once an exchange is received on this component, the onMessageExchange method of the previous mentioned pojo is invoked.

5. pack everything up and deploy
The last step is to archive and deploy everything. Create the following SU:

-META-INF/jbi.xml (the previous example)
-classes.jar (the jar file which contains the pojo and related classes)

Now create a Service Assembly that can deploy this to the petals-pojo component and you're done.


I think this is one of the big advantages of JBI; interoperability of the components. When I started with JBI I didn't really have much hope that components where truly interchangeable between JBI containers. But, even though there are some small issues, getting a component from one implementation to work on the other is very easy.
The main difference is the way you need to configure the components. ServiceMix choose an XBean approach, openESB a WSDL approach and petals extends the jbi.xml file. Personally I like the ServiceMix and Petals approach the most. They make it very easy to configure components without having to depend on an editor/support like openESB.

zondag 21 oktober 2007

Using openESB SMTP components inside ServiceMix

Using openESB SMTP components inside ServiceMix

One of the advantages of using a JBI compliant container is that it should be easy to use components from other containers. So in theory using a component from the openESB JBI container in ServiceMix would be as simple as dropping in the component in the deploy directory and create a serviceunit that can be deployed to it.

In practice however, for a change, it isn't that much more difficult. I was playing around with the SMTP component of openESB and wanted to check whether it worked in ServiceMix, since ServiceMix itself didn't provide this connectivity yet. So for those of you who want to play around with the components of openESB inside ServiceMix, here are the steps to follow:

1. Download the latest SMTP components:

You can find the daily builds at:

http://download.java.net/jbi/binaries/open-jbi-components/main/nightly/latest/ojc/

Here download the smtpbc.jar file and also the encoderlib.jar file. The first one is the binding component that will be using from ServiceMix and the second one is the shared library the smtpbc.jar file needs.

2. Fix a classcast problem:

The first problem we'll encounter when we start using this component is because most of the components from openESB use a different version of wsdl4j. If we don't fix this we'll get a strange classcast exception when we start deploying the serviceunits to this component.
So the first thing we need to do is replace the wsdl4j from the ServiceMix, from the newer version from this archive. Just copy the wsd4j.jar file from this component to the lib directory of ServiceMix replacing the version there. And then while you're at it, remove the wsd4j.jar file from the component.

3. Install the component in ServiceMix:

To now install the component in ServiceMix, you only need to drop the archive in the 'HotDeploy' directory and you'll see some output in the console. Before we do this though, first drop the encorderlib.jar file in this directory, so that we're sure it can find it's needed shared libraries.
Now we're ready to start using the component.

4. Create a new serviceassembly for deployment:
For those of you who haven't worked with openESB yet, probably aren't familiar with the way you need to deploy to these JBI components. In ServiceMix you just create a simple XBean configuration and be done with it. For openESB it's a bit different. You first create a WSDL describing the messages, operations and services. And by using WSDL extensions you configure how you want to connect to an external system.

Let's first look at how the WSDL file looks:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:osesb="http://opensourceesb/mailBC/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemaswri.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="mailBC"
xmlns:smtp="http://schemas.sun.com/jbi/wsdl-extensions/smtp/"
targetNamespace="http://opensourceesb/mailBC/">

<!-- define the message we need to sent -->
<wsdl:message name="emailReceiverOperationRequest">
<wsdl:part name="bodypart" type="xsd:string"/>
<wsdl:part name="subjectpart" type="xsd:string"/>
<wsdl:part name="frompart" type="xsd:string"/>
</wsdl:message>

<!-- define the operation on this port -->
<wsdl:portType name="emailReceiverPortType">
<wsdl:operation name="EmailReceiverOperation">
<wsdl:input message="osesb:emailReceiverOperationRequest" name="input1"/>
</wsdl:operation>
</wsdl:portType>

<!-- define a concrete implementation -->
<wsdl:binding name="emailReceiverBinding" type="osesb:emailReceiverPortType">
<smtp:binding/>
<wsdl:operation name="EmailReceiverOperation" >
<smtp:operation/>
<wsdl:input name="input1">
<smtp:input message="bodypart" subject="subjectpart" from="frompart"/>
</wsdl:input>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="mailBCService">
<wsdl:port binding="osesb:emailReceiverBinding" name="emailReceiverPort">
<smtp:address location="mailto:jos.dirksen@gmail.com" smtpport="10025" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

We won't go into too much detail here. The most important part for us here, is the wsdl:binding and the wsdl:port where we extend the normal wsdl with smtp specific settings. For more info on what you can configure here look at the smtp bc documentation on the jbi-components site (http://wiki.open-esb.java.net/Wiki.jsp?page=SMTPBC). In our case we just want to be able to send a mail to the ESB and then send the content to a file. With the above configuration we've specified that we'll start listening on 10025 and look for an email to jos.dirksen@gmail.com.
Now we have to create a jbi.xml file for the serviceunit that tells the container what to do with this interface. Do we implement it (provide a service) or are we going to use it (consume it).

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jbi xmlns="http://java.sun.com/xml/ns/jbi"
xmlns:ns1="http://opensourceesb/mailBC/"
version="1.0">
<services binding-component="true">
<!-- receive messages from external -->
<consumes endpoint-name="emailReceiverPort"
interface-name="ns1:emailReceiverPortType"
service-name="ns1:mailBCService"/>
</services>
</jbi>

What this jbi.xml file tells us is that if we receive a message on the specified address, we send the content of this message to the service as specified in this jbi.xml file. So this ServiceUnit serves as a proxy from an email client to a service inside the jbi container.

We can now deploy this serviceunit in the standard way. Just create an archive (SU-example-mail.zip) that contains the following:

+ META-INF/jbi.xml
+ mailBC.wsdl

Since we also want to do something with the message we've received we'll also quickly define an endpoint in an xbean for the file component.

<beans xmlns:f="http://servicemix.apache.org/file/1.0"
xmlns:proj="http://opensourceesb/mailBC/"
xmlns:sm="http://servicemix.apache.org/config/1.0">
<f:sender service="proj:mailBCService"
endpoint="emailReceiverPort"
directory="servicemix_work/myOutbox/">
</f:sender>
</beans>

As you can see we create a component that provides the service/endpoint that the mailBC wants to consume (so in hindsight, I'd might have chosen some better names). For this one also create a simple serviceunit (again an archive) with the name (SU-example-file.zip):

+ xbean.xml

Add both of these together in an service assembly with the following descriptor:

<?xml version="1.0" encoding="UTF-8"?>
<jbi xmlns="http://java.sun.com/xml/ns/jbi" version="1.0">
<service-assembly>
<identification>
<name>MailServiceAssembly</name>
<description>Assembly showing usage of openesb mail component</description>
</identification>
<service-unit>
<identification>
<name>Mail-SU</name>
<description>test</description>
</identification>
<target>
<artifacts-zip>SU-example-mail.zip</artifacts-zip>
<component-name>sun-smtp-binding</component-name>
</target>
</service-unit>
<service-unit>
<identification>
<name>Simple file flow</name>
<description>Simple sender</description>
</identification>
<target>
<artifacts-zip>SU-example-file.zip</artifacts-zip>
<component-name>servicemix-file</component-name>
</target>
</service-unit>
</service-assembly>
</jbi>


5. Deploy the serviceassembly:

Just copy the create archive into the hotdeploy directory from servicemix and that's it. Now we only need to test it.

6. Testing the deployment:

For this open a mail client, add a new SMTP server (localhost:10025) and use that SMTP server to send an email to the specified address from the WSDL. If all goes correctly you'll see the content of the message being sent to the file directory specified.

The resulting file will look something like this (which is customizable):

<?xml version="1.0" encoding="UTF-8"?><jbi:message xmlns:jbi="http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper" xmlns:msgns="http://opensourceesb/mailBC/" type="msgns:emailReceiverOperationRequest" version="1.0"><jbi:part>This is the content
</jbi:part><jbi:part>This is a mail to test sun smtp</jbi:part><jbi:part>Jos Dirksen <jos@test></jbi:part></jbi:message>

Pretty much the same scenario can be used for the other sun-jbi components.

On a side note, I'm also trying to get the jbi components from the Petals project to run on ServiceMix, but no luck so far.

vrijdag 12 oktober 2007

Using Apache Camel with ServiceMix


In the last days I have been looking at Apache Camel (http://activemq.apache.org/camel). Within ServiceMix there is a Enterprise Integration Patterns (EIP) JBI component that is very useful to implement patterns like for example content-based router, message filter, recipient list and content enricher patterns. These are of course a number of the patterns that are listed in the famous Enterprise Integration Patterns book by Hohpe and Woolf (http://www.enterpriseintegrationpatterns.com/). But this servicemix-eip module is limited in the support for these patterns and on the ServiceMix site, Apache Camel is referenced as an important alternative. In August Apache Camel 1.1 was released and with this release there is quite a lot of attention about this framework. ServiceMix also has a JBI component so that Camel can easily be integrated within ServiceMix. So I thought it would be a good time to develop some hello world type of implementation of ServiceMix with Camel.

The hello world type example that I implemented is a file poller that sends the file contents via Camel to a file sender. So the example just picks up a file from the inbox directory and sent it to the outbox directory. For people who know the ServiceMix service assembly configuration this maybe a bit simple, but the layout of the service assembly that I've implemented looks like this:

----pom.xml
----hello-sa
------------pom.xml
----hello-file-su
------------src/main/resources/xbean.xml
------------pom.xml
----hello-camel-su
------------src/main/resources/xbean.xml
------------pom.xml

The hello assembly (hello-sa) is eventually deployed to the ServiceMix container. But what is important is the xbean.xml configuration for the file and the camel service units. Let's start with the file service unit xbean.xml.

<beans xmlns:sm="http://servicemix.apache.org/config/1.0"
xmlns:file="http://servicemix.apache.org/file/1.0"
xmlns:esb="http://esbinaction.com/helloworld">

<file:poller service="esb:poller" endpoint="endpoint"
targetService="esb:camelReceiver" targetEndpoint="endpoint" file="file:inbox" />

<file:sender service="esb:sender" endpoint="endpoint" directory="file:outbox"/>

</beans>

So we have a simple file poller on the inbox directory and a file sender to the outbox directory. The target service for the incoming file contents, configured with the file poller, is the camelReceiver. This service is configured in the xbean configuration of the camel service unit.


<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://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/camel-spring.xsd
">

<camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
<route>
<from uri="jbi:service:http://esbinaction.com/helloworld/camelReceiver"/>
<to uri="jbi:service:http://esbinaction.com/helloworld/sender"/>
</route>
</camelContext>

</beans>

So this is a very simple Camel XML configuration that just forwards the file contents from the camelReceiver service to the sender service. This same kind of Camel routing could also have been implemented in Java and then it looks like this.

RouteBuilder routeBuilder = new RouteBuilder {

   public void configure() {

      from(jbi:service:http://esbinaction.com/helloworld/camelReceiver").to("jbi:service:http://esbinaction.com/helloworld/sender");

   }

}

<camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring">
<package>com.esbinaction.hello<package/>
</camelContext>

So this a very simple example on how to use Camel within ServiceMix.

zondag 7 oktober 2007

Back from vacation, back to writing

I'm now a couple of days back from my much needed holiday to Gran Canaria (+30 degrees celsius, finally some sunshing), and today started doing some cleanup work on the second chapter. I must say that it was very hard to get started again, but since I also have to start work again tomorrow it's an easy way to slide into thinking about software again, instead of deciding where to go out for lunch.

In the second chapter we mainly look at the architecture of Mule and ServiceMix (and thus also JBI). I've especially been working on the JBI part. Although I like it as a specification, it isn't the easiest one to understand.

I'm giving a presentation on using JBI this week at the NL-Jug J-Fall conference. So we'll see then whether I can get people to understand JBI better. Tijs wil also be presenting at the same conference, his session deals with SCA and Tuscany.