Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3
Warning
titleWarning

This component has been deprecated in favor to servicemix-lwcontainer component.
See also POJO Support.

Introduction

Developing services and component for use in a JBI (Java Business Integration) environment can seem a little complex at first and, since the JBI (JSR-208) specification is very open-ended, it can be difficult to get started sometimes. The purpose of the ServiceMix Spring Client Toolkit (SSCT) is to allow you to quickly get started get up and running quickly with either with new components or services, or maybe simply by JBI-enabling your existing Java code, so that you can use it in a JBI environment.

This Quick Start guide will let help you quickly get moving building build a couple of simple components that we can hook be hooked together to show that we are able to use , in order to illustrate how you can use JBI. All these of the examples detailed below are built to work on the ServiceMix 1.0 release (see ServiceMix for more information).

...

It's All about Tooling

Preparing to build code for a JBI environment usually typically means getting prepared so that you are need to be able to efficiently build code and get deployable code out of the door then, make that code deployable (since this is what everyone is really waiting forthe point of building for JBI). In order to help us get there build code for a JBI environment, ServiceMix provides some tooling projects that will allow us you to quickly build produce JBI-compliant JAR's JARs and descriptors, without needing requiring you to get up to our your knees in XML and ant Ant scripts.

The starting place is a copy of Maven 1.0.1 (this is available from Apache Maven), once . Once you have Maven installed, you will need to get a copy of the Maven JBI Plugin, which is available here. You simply need to Simply download the maven-jbi-plugin-1.0.jar and then drop it in into your $MAVEN_HOME/plugins directory to make it available for your build process.

My First Component Project

The best place to start is, of course, to create a new project to work with, since we are all about making it easy with which to work. Since this Quick Start guide is intended to make it building and deploying easy, you can use the Maven JBI plugin to help you out heresimplify your work. First, create a work directory (iei.e., '/work'), which is empty, and then go to that directory in from a shell or command line prompt and enter the following:

No Format
maven jbi:createArchetype

You should see the Maven start-up, and then it will ask be prompted for you the name of your new component, we can use myFirstComponent as a good starting place. It . As a good starting point, please use 'myFirstComponent'. Maven will then create the required directory structure underneath the /work directory.

No Format
 __  __
|  \/  |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\__,_|\_/\___|_||_|  v. 1.0.2

Enter the name for your new JBI project:
myFirstComponent
build:start:

jbi:createArchetype:
    [mkdir] Created dir: C:\work\myFirstComponent\src\main\java
    [mkdir] Created dir: C:\work\myFirstComponent\src\main\test
    [mkdir] Created dir: C:\work\myFirstComponent\src\main\merge
    [mkdir] Created dir: C:\work\myFirstComponent\src\main\jbi\META-INF
    [copy] Copying 1 file to C:\work\myFirstComponent
    [copy] Copying 1 file to C:\work\myFirstComponent\src\main\jbi\META-INF
    [copy] Copying 1 file to C:\work\myFirstComponent\src\main\merge
BUILD SUCCESSFUL
Total time: 53 seconds
Finished at: Thu Aug 18 16:05:01 EDT 2005

Now we , you will need to make this project available in our your favourite IDE, so . So if you are using Eclipse then you can , change to the myFirstComponent directory and use Maven to create the relevant Eclipse files by running the following:

No Format
maven eclipse

See the Apache Maven website for more information on creating the configuration files for other IDE'sIDEs.

You should now be able to open the JBI project in your IDE, and where you can see the basic structure of the project, as shown below:

Image Modified

At this point we , you are ready to start working with JBI.

Understanding

...

How JBI

...

Works

While the JBI specification is no light document we , this Quick Start guide will try and to distill some of the basic ideas down , so that we can get you have the information you need to write a basic component written. Basically, JBI is a way of exposing Services and Binding Components, a . A Service is usually something that is functions as an Engine of some type, and instances of that an engine each run with a configuration, this e.g., a service might be a BPEL engine, or it might be a transformation engine. While a A Binding Component is a particular type of service that , which allows you to take calls or messages from a non-JBI transport, such as JMS, or to a non-JBI transport/protocol.

The JSR is purposefully vague on some of this simply to allow the greatest range to the component developers, however in order for us to be able . In this case however, you will be using the SSCT to write a simple component we will be using our Spring Client Toolkit to help use integratefor integration use. To that end, there are a few basic things you need to focus onconcepts to understand:

  • Services/Components have life-cycles, these are basically most commonly initialization, start and stop. There is a bit more to it that that life-cycles, but in order to get you going we started on building code for a JBI environment, you can start here.
  • Services/Components communicate to other Services/Components via EndPoints, this means that if you want . Therefore, in order to talk to another service, you need to refer specifically to its Service Name.
  • Services/Components can have interfaces, this which means that a service can route a message to a different peice piece of code, and you might want to can have a service that exposes more than one interface.
  • All Service Names and Interface names are Qualified Names, so we you should declare namespaces for they are correct.

How

...

Does this

...

Map to the ServiceMix Spring Client Toolkit?

The Toolkit SSCT is there provided to try and simplify the appraoch to building for JBI and make writing to make it easier for you to write these components a bit easier, though as with all things it hides that hide some of the complexity but technology's complexity – the SSCT also hides some of the more advanced functionality.

To start with the Spring Client Toolkit The SSCT itself is based on Spring and therefore, it is probably worth first looking at what Spring is, since we will assume a little knowledge. The second thing is the the SSCT working along side recommended that you first take a look at Spring if you are not already familiar, since this Quick Start guide assumes at least preliminary Spring knowledge. In addition, the SSCT works in conjunction with the Maven JBI plugin to help you build you your component. And finally in these examples we Finally, in using the SSCT examples, you will be producing hard-routed components, in other words i.e., components that will build with their destinations inincluded, though you the guide will see that changing the destinations also show you that it isn't too complexoverly complex to change your components' desitnations.

If you are familiar with the JSR-208 specification you have probably heard , you should be aware of interfaces like Component/LifeCycle/Service Unit Manager etc, while . While you can certainly use these interfaces, the Spring Client Toolkit provides a simplified SSCT provides the following set of three, simplified interfaces to the JBI infrastructure, these are:

ServiceLifeCycleImplementation

Which can be implemented by your code and then rely on the SSCT container will to invoke the start/stop method in-line with the JBI lifecycle methods.

ServiceInterfaceImplementation

Which can be used to receieve exchanges on a given interface, ; your code will implement this interface and return the QName of the interface on which it wishes to receive the exchanges.

ServiceEndPointImplementation

Which can be used to recieve receive exchanges on a given Service Name and End Point, EndPoint; your code will implement this interface and return the QName of the service and the name of the endpoint EndPoint to receive the exchanges.

...

Your First Component

In order to start we begin, you will create a very simple component that is able to can start a Timer, and then simply create and then send a message to another component. Admittedly note , not the most earth-shattering of components though – but it is simple enough to get done that you can get it built over a cup of coffee and its going to require two pages explaining the code., and it requires only two pages of explanation.

Create We will create a new package org.servicemix.tutorial under src/main/java and then in there , create a new class called 'TimerComponent and ' in order to implement the ServiceLifeCycleImplementation interface.

You should end up with a class looking much like thisthe following:

Code Block
java
java


package org.servicemix.tutorial;

import javax.jbi.JBIException;

import org.servicemix.client.ServiceContext;

import org.servicemix.client.ServiceLifeCycleImplementation;

/**
 * A simple Timer based component
 * 
 * @author <a hrefxhref="mailto:pdodds@unity-systems.com">Philip Dodds </a>
 */
public class TimerComponent implements ServiceLifeCycleImplementation {

	/* (non-Javadoc)
	 * @see org.servicemix.client.ServiceLifeCycleImplementation#init(org.servicemix.client.ServiceContext)
	 */
	public void init(ServiceContext serviceContext) throws JBIException {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.servicemix.client.ServiceLifeCycleImplementation#start()
	 */
	public void start() throws JBIException {
		// TODO Auto-generated method stub

	}

	/* (non-Javadoc)
	 * @see org.servicemix.client.ServiceLifeCycleImplementation#stop()
	 */
	public void stop() throws JBIException {
		// TODO Auto-generated method stub

	}

}

Now we , you are going to create a simple Timer, this is actually made a little easier by the fact that the Spring Client Toolkit doesn't ask you to extend anything so you are extend TimerTask and create basic Timer. The SSCT actually simplifies this for you as you are only extending the TimerTask and creating a Timer, in the init method. In the start and stop we , you will basically perform set the timer operations to schedule it the timer to run every 5000ms and to cancel it if we stopstopped.

Code Block
java
java
package org.servicemix.tutorial;

import java.util.Timer;
import java.util.TimerTask;

import javax.jbi.JBIException;

import org.servicemix.client.ServiceContext;
import org.servicemix.client.ServiceLifeCycleImplementation;

/**
 * A simple Timer -based component
 * 
 * @author <a hrefxhref="mailto:pdodds@unity-systems.com">Philip Dodds </a>
 */
public class TimerComponent extends TimerTask implements
		ServiceLifeCycleImplementation {

	private Timer timer;
	private ServiceContext serviceContext;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.servicemix.client.ServiceLifeCycleImplementation#init(org.servicemix.client.ServiceContext)
	 */
	public void init(ServiceContext serviceContext) throws JBIException {
		this.serviceContext = serviceContext;
		timer = new Timer();
		timer.schedule(this, 5000);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.servicemix.client.ServiceLifeCycleImplementation#start()
	 */
	public void start() throws JBIException {
		timer.schedule(this, 5000);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.servicemix.client.ServiceLifeCycleImplementation#stop()
	 */
	public void stop() throws JBIException {
		timer.cancel();

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.util.TimerTask#run()
	 */
	public void run() {

	}

}

Note that since we NOTE: Since you extended TimerTask we , you now have a run method, so we you can use this run method to create a simple InOnly exchange. In order to help us To do this we , you can use the serviceContext helper methods.

Below we , you can see how easy it is to create an InOnly exchange and how to populate the message.

NOTE: With , note that with the ServiceContext helper method we , you must also refer to the name of the interface that we will to send to, we to which the message will be sent. You will see this interface mapping to a service name later in the services.xml.

Code Block
java
java
/*
 * (non-Javadoc)
 * 
 * @see java.util.TimerTask#run()
 */
public void run() {
	try {
        InOnly inOnly = serviceContext.createInOnly(new QName(
				"http://tempuri.org/logger", "log"));
		NormalizedMessage message = inOnly.createMessage();
		message.setContent(new StreamSource(new StringReader(
				"<hello>world</hello>")));
		serviceContext.done(inOnly);
	} catch (MessagingException e) {
		e.printStackTrace();
	}
}

Thats That's it for our building your first component's code. Now, now we you need to do the wiring for the JBI. This basically means we , i.e., you will need to make sure that when we you publish to the interface, that it maps to a specific service name. Since we you are still writing the first component we , you will have to make up the name of the second component as a placeholder. However, but keep it this name in mind since we you will write be writing a second component to recieve these in a minutereceive these messages shortly. To do the JBI wiring we , look to the /src/main/merge/services.xml file. You should be able to prepare the file as shown below:

Code Block
xml
xml
<services binding-component="false"	
	xmlns:logger="http://tempuri.org/logger">
	<consumes interface-name="logger:log"
		service-name="logger:myLogger" />
</services>

Note that we have our NOTE: The interface name is described as a consumes, which is in JBI-speak means that this component will be sending its exchange to the service-name servicename 'logger:myLogger'. We You haven't written this service yet, but as you can see, it won't take us you long to create this service and then we so that you can use its services.xml to expose that the service-name and interface name. The Spring Client Toolkit SSCT lets us you work through the interface name, though you still have access to be able the ability to publish to any of your the available end points EndPoints that you are defined in the services.xml.

Next we , you need to tell our the Spring Component that we need an instance of the TimerComponent , this is required. This is done in the spring Spring configuration file found in /src/main/jbi/META-INF/jbi-spring.xml, as can be see seen below:

Code Block
xml
xml
<beans>
	<!--  This is going to be where we declare the beans that we want the
		   SpringComponent container to build -->

	<bean id="myTimer"
		class="org.servicemix.tutorial.TimerComponent">	
	</bean> 
</beans>

The final step for our in building the JBI component is actually creating the component, this can be done using the Maven JBI plugin , using by running the following command in from your myFirstComponent directory:

No Format
maven jbi:generateInstaller

Which This command will create a ZIP file in the target directory below called myFirstComponent-1.0-jbi-installer.zip.

Congratulations you ! You have just created your first JBI component!

Creating a

...

Component to

...

Receive the

...

Exchange

Of course, creating single JBI The one problem with JBI is that a single component is pretty useless, much like being the only person at the party there is very little to do. So we can , the next step is for you to return to the parent directory and repeat the process above, using our Maven JBI plugin and the maven jbi:createArchetype, to create a second component called aptely , which you will call mySecondComponent.

Once you have created the project, and also the eclipse Eclipse files, you can create a new class in the package org.servicemix.tutorial called LoggerComponent, this . This time we you will implement be implementing the ServiceInterfaceImplementation interface, and we you will fill in the getInterface method with the name of the interface we you used in building the first component., as shown below:

Code Block
java
java
package org.servicemix;

import javax.jbi.messaging.MessageExchange;
import javax.xml.namespace.QName;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.servicemix.client.ServiceContext;
import org.servicemix.client.ServiceInterfaceImplementation;

/**
 * A simple Logger based component
 * 
 * @author <a hrefxhref="mailto:pdodds@unity-systems.com">Philip Dodds </a>
 */
public class LoggerComponent implements ServiceInterfaceImplementation {
	
	private static final Log log = LogFactory.getLog(LoggerComponent.class
			.getName());

	/* (non-Javadoc)
	 * @see org.servicemix.client.ServiceInterfaceImplementation#getInterfaceName()
	 */
	public QName getInterfaceName() {
		return new QName(
				"http://tempuri.org/timer", "notification");
	}

	/* (non-Javadoc)
	 * @see org.servicemix.client.ServiceImplementation#setServiceContext(org.servicemix.client.ServiceContext)
	 */
	public void setServiceContext(ServiceContext arg0) {
		
	}

	/* (non-Javadoc)
	 * @see org.servicemix.client.ServiceImplementation#onMessage(javax.jbi.messaging.MessageExchange)
	 */
	public void onMessage(MessageExchange exchange) {
		log.info("I got my exchange "+exchange);
	}

}

The Spring Client Toolkit will make sure SSCT will ensure that exchanges for this service and that interface its interfaces will be passed to this the ServiceInterfaceImplementation.

Next we , you will need to set up the services.xml for this component. ...Since this is such a simple example, you can simply reverse the logic from the first component, so that this this component provides the interface for itself.

Code Block
xml
xml

<!-- This is where we are able to declare the ins and outs of the Service
 	  as it consumes and provides elements, the service-names and EndPoints
 	  will be used to activate the JBI EndPoints,  and you can use the
 	  interface-name to determine which one you want to call and which
 	  bean is going to receive the actual JBI exchange -->
<services binding-component="false"
	xmlns:timer="http://tempuri.org/timer"
	xmlns:logger="http://tempuri.org/logger">
	<provides interface-name="timer:notification"
		service-name="logger:write" />
</services>

Once again you need to configure the Spring container to create an instance of your bean in the src/main/jbi/META-INF/jbi-spring.xml file, shown below:

Code Block
xml
xml

<beans>
	<!--  This is going to be where we declare the beans that we want the
		   SpringComponent container to build -->
	<bean id="myLogger"
		class="org.servicemix.tutorial.LoggerComponent">
	</bean>
</beans>

This now completes the writing of the receiving component's code. As with the first component, you need to build the receiving component so that it is ready for deployment using the maven jbi:generateInstaller goal onto a JBI server (in our case the wonderful ServiceMix).

Deploying Your Components onto ServiceMix

One of the key differences between the ServiceMix Spring Client Toolkit and the standard ServiceMix client libraries is that the SSCT is designed to generate standard JBI components and service units that can run in any JBI-compliant container. This means that you are able to build installable ZIP files that can be deployed onto the server itself. In this example, you are going to deploy to a stand-alone ServiceMix server, however you could deploy to a Geronimo and JBoss instance running ServiceMix embedded, as well.

To deploy your JBI components, you must first download and un-ZIP ServiceMix to your your machine.

Next, under $SERVICEMIX_HOME (the location you unzipped it), you should find an install directory. You need to copy both of the JBI installers that you created for your components into this directory. If you have been working in '/work' then these files should appear as follows:

/work/myFirstComponent/target/myFirstComponent-1.0-jbi-installer.zip and /work/mySecondComponent/target/mySecondComponent-1.0-jbi-installer.zip.

Once you have installed the new components, you can just start ServiceMix - to do so goto $SERVICE_HOME/bin and run servicemix

You should see your components deploy and then, every 5 secs you should see the logger receive the exchange from the timer component.

No Format

ServiceMix ESB: null

Loading ServiceMix from servicemix.xml on the CLASSPATH
Aug 19, 2005 11:13:13 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader
loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [servicemix.xml]
Aug 19, 2005 11:13:13 AM org.springframework.context.support.AbstractRefreshableApplicationContext
refreshBeanFactory
INFO: Bean factory for application context [org.springframework.context.support.
ClassPathXmlApplicationContext;hashCode=14737862]: org.springframework.beans.factory.support.
DefaultListableBeanFactory defining beans [transactionManager,jmsFactory,jbi]; root of BeanFactory hierarchy
Aug 19, 2005 11:13:14 AM org.springframework.context.support.AbstractApplicationContext
refresh
..........
Aug 19, 2005 11:13:15 AM org.springframework.beans.factory.support.DefaultListableBeanFactory
preInstantiateSingletons
INFO: Pre-instantiating singletons in factory [org.springframework.beans.factory.support.
DefaultListableBeanFactory defining beans [myLogger]; root of BeanFactory hierarchy]
Aug 19, 2005 11:13:15 AM org.springframework.beans.factory.support.AbstractBeanFactory getBean
INFO: Creating shared instance of singleton bean 'myLogger'
Aug 19, 2005 11:13:15 AM org.servicemix.jbi.framework.ComponentContextImpl activateEndpoint
INFO: Component: mySecondComponent activated endpoint: {http://tempuri.org/logger}write : default
Aug 19, 2005 11:13:15 AM org.servicemix.jbi.framework.AutoDeploymentService$1 run
INFO: Directory: install: Finished installation of archive:  mySecondComponent-1.0-jbi-installer.zip
Aug 19, 2005 11:13:20 AM org.servicemix.tutorial.LoggerComponent onMessage
INFO: I got my exchange org.servicemix.jbi.messaging.InOnlyImpl@15ad5c6

*Aug 19, 2005 11:13:20 AM org.servicemix.tutorial.LoggerComponent onMessage
INFO: I got my exchange org.servicemix.jbi.messaging.InOnlyImpl@15ad5c6*

There you go! You have just written your first JBI components, hooked them up, and deployed them successfully!TO BE COMPLETED