To make it simpler to use we've created a JBI Client API which makes it easy to work with any JBI container and other JBI components.
The JavaDoc is probably self evident for many things, especially if you are aware of the JBI APIs. There is an example test case which shows many of these APIs in action.
Using the JBI interfaces
The following helper methods just provide some helper methods for easier use of the JBI APIs
Sending messages
This example uses a specific service to invoke
InOnly exchange = client.createInOnlyExchange();
NormalizedMessage message = exchange.getInMessage();
message.setProperty("name", "James");
message.setContent(new StreamSource(new StringReader("<hello>world</hello>")));
QName service = new QName("http:, "receiver");
exchange.setService(service);
client.send(exchange);
In this example, we assume that the JBI container will have setup a default routing connection for our client, so we don't have to worry about specifying the endpoint.
InOnly exchange = client.createInOnlyExchange();
NormalizedMessage message = exchange.getInMessage();
message.setProperty("name", "James");
message.setContent(new StreamSource(new StringReader("<hello>world</hello>")));
client.send(exchange);
Invoking services
InOut exchange = client.createInOutExchange();
NormalizedMessage inMessage = exchange.getInMessage();
inMessage.setProperty("name", "James");
inMessage.setContent(new StreamSource(new StringReader("<hello>world</hello>")));
exchange.setService(service);
client.sendSync(exchange);
NormalizedMessage outMessage = exchange.getOutMessage();
Working with URIs and Destinations
ServiceMix has integrated support for URIs to simplify the accessing of endpoints within the NMR. The ServiceMixClient (from 3.0-M3 or later) allows you to work with URIs easily via a Destination interface. This interface acts as a factory of MessageExchange objects which are pre-wired to specific endpoints specified via a URI.
The following shows how to work with InOnly for one way messaging
Destination destination = client.createDestination("service:http:);
InOnly exchange = destination.createInOnlyExchange();
NormalizedMessage message = exchange.getInMessage();
message.setProperty("name", "James");
message.setContent(new StreamSource(new StringReader("<hello>world</hello>")));
client.send(exchange);
Or using InOut for request-response
Destination destination = client.createDestination("service:http:);
InOut exchange = destination.createInOutExchange();
NormalizedMessage request = exchange.getInMessage();
request.setProperty("name", "James");
request.setContent(new StreamSource(new StringReader("<hello>world</hello>")));
client.sendSync(exchange);
NormalizedMessage response = exchange.getOutMessage();
Simpler one-way messaging with Destinations
For one-way messaging its sometimes simpler to just work with a Message instance (you can always refer to the MessageExchange via the getExchange() method if need be). For example
Destination destination = client.createDestination("service:http:);
Message message = destination.createInOnlyMessage();
message.setProperty("name", "James");
message.setBody("<hello>world</hello>");
client.send(message);
For more detail see the unit test case
Using the POJO methods
We provide a few helper POJO based methods to allow you to use JBI using regular POJOs to hide some of the XML marshaling detail. Then you can use a plugable Marshaler to map your POJOs to JAXP Sources.
Sending messages
This example uses a specific service to invoke
Map properties = new HashMap();
properties.put("name", "James");
QName service = new QName("http:, "receiver");
EndpointResolver resolver = client.createResolverForService(service);
client.send(resolver, null, properties, "<hello>world</hello>");
In this example, we assume that the JBI container will have setup a default routing connection for our client, so we don't have to worry about specifying the endpoint.
Map properties = new HashMap();
properties.put("name", "James");
client.send(null, null, properties, "<hello>world</hello>");
Invoking services
EndpointResolver resolver = client.createResolverForService(service);
Map properties = new HashMap();
properties.put("name", "James");
Object response = client.request(resolver, null, properties, "<hello>world</hello>");
Configuring the ServiceMixClient
We use the Spring XML configuration files to configure the client. You can then use dependency injection to inject the client into your POJOs.
Here's an example of using a basic client...
<bean id="client" class="org.apache.servicemix.client.DefaultServiceMixClient">
<constructor-arg ref="jbi" />
</bean>
Note that the jbi bean reference is the ServiceMix JBI container.
This example creates a client which is hard-wired to default to a specific service when an invocation is performed.
<bean id="clientWithRouting" class="org.apache.servicemix.client.DefaultServiceMixClient">
<constructor-arg ref="jbi" />
<constructor-arg>
<sm:activationSpec destinationService="foo:receiver"/>
</constructor-arg>
</bean>
If you have access to a ComponentContext
If you are inside a JBI component you can create a ServiceMixClient as follows
ServiceMixClient client = new ServiceMixClientFacade(context);
If you want to access a remote ServiceMix instance
If you want to create a ServiceMixClient to access services on a remote ServiceMix instance, you can use the RemoteServiceMixClient. The constructor arguments shown below is the URI for connecting to ServiceMix's embedded ActiveMQ instance. This only works if the remote instance has the JMS Flow enabled.
ServiceMixClient client = new RemoteServiceMixClient("tcp:);
If you are using Spring, this becomes
<bean id="client" class="org.apache.servicemix.client.RemoteServiceMixClient" init-method="start" destroy-method="shutDown">
<constructor-arg value="tcp://localhost:61616" />
</bean>
Using ClientFactory
Starting from 3.0-M3, you can retrieve a ClientFactory from JNDI.
ClientFactory factory = new InitialContext().lookup(ClientFactory.DEFAULT_JNDI_NAME);
ServiceMixClient client = factory.createClient();
...
client.close();
Note that creating client is somewhat expensive, so it's best to create a client once and reuse it.