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
| 96552 views |
  • submit to reddit

Note that ActiveMQ is included in FUSE ESB 4 by default and the ActiveMQ broker is started automatically when you start the FUSE ESB container. The ActiveMQ configuration that’s used by FUSE can be found in the deploy directory in the activemq-broker.xml file. So in this example we’ll make use of this default ActiveMQ broker. In listing 2, the implementation of the ValidationRouter is shown.

Listing 2 Implementation of the ValidationRouter class.

package com.fusesource.camel;


import org.apache.camel.ValidationException;
import org.apache.camel.builder.RouteBuilder;
public class ValidationRouter extends RouteBuilder {
public void configure() throws Exception {
from("jms:camel.jms.in")
.to("log:showAll?level=info")
.tryBlock()
.to("validator:hello.xsd")
.to("jms:camel.jms.out")
.handle(ValidationException.class)
.to("jms:camel.jms.error");
}
}

Listing 2 shows the really powerful configuration language of the Camel Java DSL. With only a few lines of code you can define quite a bit of logic. With the from method the source JMS queue is configured, where a listener will consume newly arrived messages. Then, with the Camel log component, the message exchange is logged to the container log file. In this case the showAll configuration is used, which means the whole message exchange is logged. There are other logging configurations available which log for example the message headers or the message payload. You can also configure a log level, such as the info level which is used in this example.

Then a tryBlock method is used to be able to catch possible validation errors that may occur in the validator component. With the handle method exceptions can be caught and handled with a piece of integration logic. When a ValidationException occurs the message is forwarded to the camel.jms.error queue. To make the ValidationRouter class available within the Camel context and to start the JMS polling, we need to define a Camel XML configuration file similar to the first example shown in listing 1. But, in this second example we implemented the routing logic in a Java class, so let’s look at how to configure a Java DSL example in listing 3.

Listing 3 Camel XML configuration file, beans.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel-osgi="http://activemq.apache.org/camel/schema/osgi"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.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">
<camel-osgi:camelContext xmlns="http://activemq.apache.org/camel/schema/spring">
<package>com.fusesource.camel</package>
</camel-osgi:camelContext>
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory">
<osgi:reference id="connectionFactory" interface="javax.jms.ConnectionFactory" />
</property>
</bean>
</beans>
Instead of the route element definition we saw in the camelContext definition in the first example, we now define a package element, which contains the ValidationRouter class. When we deploy this second example to the FUSE ESB container, the com.fusesource.camel package will be scanned for Camel classes like the RouteBuilder class we defined with the ValidationRouter. Because we use the Camel JMS component, we have to define a Spring bean with a connection factory. We can define an ActiveMQConnectionFactory with a brokerURL property with a value of tcp://localhost:61616. But the connection factory is already defined in the activemq-broker.xml file that can be found in the deploy directory.
<osgi:service ref="pooledConnectionFactory">
<osgi:interfaces>
<value>javax.jms.ConnectionFactory</value>
</osgi:interfaces>
<osgi:service-properties>
<entry key="name" value="default"/>
</osgi:service-properties>
</osgi:service>

 So we can also define an OSGi reference to this connection factory with the osgi:reference element. To be complete, listing 4 shows the XML Schema definition that will be used to validate the incoming message.

 Listing 4 The XML Schema definition file, hello.xsd.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://fusesource.com/examples"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
targetNamespace="http://fusesource.com/examples">
<xsd:element name="hello-request">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>

This concludes the implementation of the Camel JMS example. The source code can of course be downloaded at the link shown at the end of this article, but let’s have a quick look at the project structure in figure 4.

Figure 4 Project structure of the Camel JMS example.

The camel-jms-example project is Maven based and therefore a pom.xml file is defined at the root of the project directory. The ValidationRouter is defined where you would expect a Java file in a Maven project, the src/main/java directory. The Camel XML configuration file beans.xml is defined in the src/main/resources directory under META-INF/spring. The XML Schema definition hello.xsd is defined at the root of the src/main/resources directory.

Now let’s get this example running on the FUSE ESB container. First we’ve to build the camel-jms-example project with the mvn clean install Maven command. A camel-jms-example-1.0.jar OSGi bundle file will be created in the target directory of the project. This jar file can be deployed to the FUSE ESB container by copying it to the deploy directory, just like we did in the first example. Remember that we’ve already installed the camel-jms feature, because we’ll need this feature to be installed before this example is deployed. When you now run the ‘osgi list’ command in the FUSE ESB console, you can see that the example OSGi bundle is deployed and active under the name ‘Fuse example : : Camel JMS’. In the source code of the camel-jms-example project you can find the hello-test.xml and hello-test2.xml test files. With the HermesJMS tool (http://www.hermesjms.com) you can use these files to add a message to the camel.jms.in queue to trigger the example. When you have produced a message to the queue you can see the log file of the FUSE ESB container by executing the ‘log d’ or ‘log display’ command in the console. You can see that the incoming message content is logged here.

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.