Enterprise Integration Zone is brought to you in partnership with:

Tijs has posted 3 posts at DZone. View Full User Profile

A Look Inside FUSE ESB 4: An OSGi-Based Integration Platform

03.10.2009
| 97126 views |
  • submit to reddit

In the first two examples we focused on the Camel functionality available in FUSE ESB. But FUSE ESB also provides an easy to use definition for web services with Apache CXF. But to communicate between Camel routes and these web services we need an interaction layer. So we need a bus inside the ESB, which is named the NMR in FUSE ESB 4.

Introducing the NMR

The NMR project enables the interaction between different components in the OSGi container. This is quite similar to the normalized message router which is defined in the JBI specification, but it’s more flexible and not only dedicated to JBI. The main purpose of the NMR is to mediate between service consumers and service providers. In the example shown in figure 5, you can see that the NMR can be used to communicate between a Camel route definition and a JAX-WS endpoint. This example is provided with FUSE ESB 4 with the name cxf-camel-nmr.

Figure 5 An overview of the cxf-camel-nmr example provided with FUSE ESB 4. This example shows the use of a NMR to mediate between a Camel route and a JAX-WS endpoint.

For a change we don’t trigger the integration logic with a file or a JMS message in the cxf-camel-nmr example, but with a timer. The timer is defined as part of the Camel route definition. Then a Spring bean, MyTransform, is invoked with its transform method, which basically returns the message that can be sent as a request to the web service. Then the web service is invoked via the NMR and the result is passed on, again to the MyTransform Spring bean, which logs the web service response with the display method. Now let’s take a look at the XML configuration in listing 5.

Listing 5 The XML configuration for the Camel route and JAX-WS endpoint definition.

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xmlns:camel-osgi="http://activemq.apache.org/camel/schema/osgi"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://activemq.apache.org/camel/schema/spring
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd
http://activemq.apache.org/camel/schema/osgi
http://activemq.apache.org/camel/schema/osgi/camel-osgi.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/transport/nmr/cxf-transport-nmr.xml" />
<import resource="classpath:org/apache/servicemix/camel/nmr/camel-nmr.xml" />
<camel-osgi:camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
<!-- Route periodically sent events into the NMR -->
<route>
<from
uri="timer://myTimer?fixedRate=true&period=5000&exchangePattern=InOut" />
<bean ref="myTransform" method="transform"/>
<to uri="nmr:{http://cxfcamel.examples.servicemix.apache.org/}HelloWorldImplPort"/>
<bean ref="myTransform" method="display" />
</route>
</camel-osgi:camelContext>
<bean id="myTransform" class="org.apache.servicemix.examples.cxfcamel.MyTransform">
<property name="value">
<value><![CDATA[
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:sayHi xmlns:ns1="http://cxf.examples.servicemix.apache.org/">
<arg0>Guillaume</arg0>
</ns1:sayHi>
</soap:Body>
</soap:Envelope>]
]></value></property>
</bean>
<jaxws:endpoint id="helloWorld"
implementor="org.apache.servicemix.examples.cxfcamel.HelloWorldImpl"
address="nmr:HelloWorld" />
</beans>

We’ll start with the timer definition in the Camel route. The timer triggers the Camel route at a fixed rate of 5 seconds and produces an InOut exchange pattern. We need this InOut exchange pattern to communicate with the web service, because we need to send a request (In) and receive a response (Out). In the next step the transform method of the MyTransform Spring bean is invoked. In listing 6 we’ll look at the implementation of the MyTransform class in detail, but this method returns the SOAP envelope as configured with the value property of the myTransform Spring bean definition. So this produces a message with an element of sayHi and a value of Guillaume.

Then the hello world web service is invoked which is configured with the jaxws:endpoint. We’ll look at the implementation of the HelloWorldImpl in listing 7, but this method returns the obvious “hello” message. Then the MyTransform bean is called again, but now with the display method, which logs the web service response. Notice that we need to import several XML files at the top of the XML configuration file, to initialize Apache CXF and the NMR.The implementation of the MyTransform class is shown in listing 6, but this will not be too complex.

Listing 6 The MyTransform implementation which produces the web service request and logs the response.


package org.apache.servicemix.examples.cxfcamel;
import java.util.logging.Logger;
import javax.xml.transform.Source;
import org.apache.camel.converter.jaxp.StringSource;
import org.apache.camel.converter.jaxp.XmlConverter;
public class MyTransform {
private static final transient Logger LOG = Logger.getLogger(MyTransform.class);
private String value;
public Object transform(Object body) {
LOG.info(">>>> " + value);
return new StringSource(value);
}
public void display(Source body) throws Exception {
String str = new XmlConverter().toString(body);
LOG.info("<<<< " + str);
}
// omitted the getter and setter for the value property
}

The HelloWorldImpl class is very simple and is annotated with the @WebService annotation which sets the web service interface class, which just defines the sayHi method in this example.

Published at DZone with permission of its author, Tijs Rademakers.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Claus Ibsen replied on Wed, 2009/03/11 - 12:57am

Very nice article.

Maybe the description for the Camel SEDA and VM components, could be changed to:
- asynchronous call to another endpoint in the same Camel Context
- asynchronous call to another endpoint in the same JVM

The List component is renamed to Browse in Camel 2.0 as a better name what it does, eg being able to browse Messages that have passed it.


--
Claus Ibsen
Apache Camel Committer

Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/

Claus Ibsen replied on Wed, 2009/03/11 - 1:03am

I am wondering if in listening 3 the reference for the connectionFactory should be pooledConnectionFactory instead? Well at least you would assume this when reading the AMQ configuration below.

Claus Ibsen replied on Wed, 2009/03/11 - 1:06am

ActiveMQ comes with a web console, I was wondering if that is can be used for sending new messages to a JMS queue instead of having to install Hermes and find out how to get it connected with AMQ.

AMQ web console:
http://activemq.apache.org/web-console.html

Tijs Rademakers replied on Wed, 2009/03/11 - 2:24am

Hi Claus, Thanks, I changed the VM and SEDA description to your descriptions. About listing 3, the pooledConnectionFactory ref attribute value is pointing to the Spring bean definition in the activemq-broker.xml file. So the name I gave the JMS ConnectionFactory in listing 3 is just a name that's used within this FUSE JMS configuration. And yes, the web console can of course also be used to send a message to a JMS queue. Hermes is a nice alternative with some more features. Best regards, Tijs

Tang Yong replied on Sat, 2009/03/14 - 9:21am

Hi trademak,

The same greate and wonderful article as "Open-Source ESB In Action"!

I wish that you can contribute more excellent article about enterprise integration.

Especially about the key technoledge points of open source integration(such as spring with mule,spring with servicemix,...).



--- Mike Tang

Sun Glassfish FishCat Contributor

Open Source Integration Fans



Blog: http://mikertang.blogspot.com/

Tijs Rademakers replied on Sat, 2009/03/14 - 11:51am in response to: Tang Yong

Hi Mike, Thanks! I have plans to write some more articles about open source integration (as time permits). Best regards, Tijs

Robert Williams replied on Wed, 2009/03/18 - 7:42am

Could not  download the article source code at  the URL listed.

Could you please make the article source code available

BTW Nice article! 

Erwin Teseling replied on Wed, 2009/03/18 - 8:12am in response to: Robert Williams

I would also like to download the source, could you provide an updated link?

Tijs Rademakers replied on Wed, 2009/03/18 - 2:52pm in response to: Erwin Teseling

Hi, I've added the source code to my own web page at esbinaction.com. I changed the download link in the article. Let me know if you still run into problems. Best regards, Tijs

Erwin Teseling replied on Wed, 2009/03/18 - 5:39pm in response to: Tijs Rademakers

Thanks a lot. I still had some problems with the correct pom.xml settings in order to gets things working, but with the source I managed to get it working!

Ali Yang replied on Wed, 2010/07/14 - 10:59am

Hi Tijs, I have talked with a guy from FUSE. He said OSGi Service function just like a registry in OSGi container. It is very simple. So what about your opinion? What is the benefit to use OSGi Service to expose functions in one Bundle to other Bundles in OSGi container? Thanks

Mohit Dklkjhsds replied on Mon, 2010/08/16 - 10:20am

Hi Tijs, I am fairly new to java,i have just worked on a very modest core java project.I have little idea of web services but i am a complete stranger to the terminologies like FUSE ESB,JBI,OSGI,CAMEL,SERVICEMIX. Can you please suggest what i must first get acquainted with before jumping into this ,if it requires any prior knowledge(which, i am almost certain it does).Or if possible can you please dumb it down a little for people like me who have very little idea what FUSE ESB is all about and also a little about it's other components. Thanks & Regards Mohit

Larry Xu replied on Mon, 2010/11/15 - 3:27am

where is the source code ?

Dead Devil replied on Tue, 2011/03/15 - 4:17pm

Greetings!! Many thanks for the examples but i have some issues with this. When i deploy camel-jms-example-1.0.jar, by copying it to the deploy directory, i get this error Exception in thread "SpringOsgiExtenderThread-6" java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext at org.springframework.context.support.AbstractRefreshableApplicationContext.getBeanFactory(AbstractRefreshableApplicationContext.java:171) at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.close(DependencyWaiterApplicationContextExecutor.java:345) at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.fail(DependencyWaiterApplicationContextExecutor.java:401) at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.stageOne(DependencyWaiterApplicationContextExecutor.java:287) at org.springframework.osgi.extender.internal.dependencies.startup.DependencyWaiterApplicationContextExecutor.refresh(DependencyWaiterApplicationContextExecutor.java:175) at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:175) at org.springframework.osgi.extender.internal.activator.ContextLoaderListener$2.run(ContextLoaderListener.java:718) at java.lang.Thread.run(Thread.java:636)

Carla Brian replied on Sat, 2012/06/30 - 11:12am

 Fuse ESB has a pluggable architecture that allows organizations to use their preferred service solutions in their SOA. - Mercy Ministries

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.