Working with Mule
09/11/08 11:53 Filed in: Java
In the project I'm in we are going to use Mule to
implement asynchronous services in an SOA way. After
a lot of banging our heads into a wall I finally
managed to get up Mule with ActiveMQ as the message
broaker. This should be easy, but it turned out not
to be so.
The documentation is poor, the examples has broken tests and all examples on the net has a lot of different syntax in them and people are not really that great and telling which version of the software they are using when they are discussing stuff... So therefore I decided to describe how I did it as people might find it useful.
The setup is using mule 2.1.1 and Active MQ 5.1.1. It is built using maven 2.0.6. The example I have is a webservice that is forwarded to a message queue. I have used ActiveMQ without any setup, just starting the downloaded binary, accessed the web console and creating a new queue. The code follows now (I must apologize for my blog software that does not let me manipulate the HTML in a very good way, so it looks not that good, but hopefully readable):
The web service is defined as follows:
This file will not compile unless you do "maven eclipse:eclipse" and import the project as it depends on javax.jws found in the one of the mule support jar files.
The config file for mule looks like this (have defined it in conf/ytelse-mule.xml):
The queue it sends to is TestQ. The config file takes in a spring config file where activeMqConnectionFactory is defined. The applicationContext.xml file is defined like this (put in conf/ dir):
As there is no configuration it will not try to embed a broker. I would have preferred to have an embedded broker, but I haven't figured out the configuration for that yet. Finally the hole shabang is built using maven and the pom.xml file looks like this:
The trick in this file is that it adds conf/ and src/main/resources (commented out, but nice if you want to add property files at root into the built jars) into the classpath. To run it you do:
mvn install
This will now copy the needed jar files to $MULE_HOME/lib/user which is the place where mule looks for files when running code. This is described by the build step in the pom.xml. In addition to the ytelse.jar file the activemq files needed for connecting is found.
Starting mule using "mule -config conf/ytelse-mule.xml" will start up mule and make everything ready. Make sure that you have started activeMQ before trying to start mule as it will try to connect to the message broker upon startup.
After this is done, you can test the code using this simple webcall: http://localhost:65082/services/WebCall/sendMessage/message/Hi there.
This will put a message with the body "Hi there" on the queue TestQ, which you should be able to track using the admin console for ActiveMQ. (http://localhost:8161/admin/queues.jsp)
That's all there is to it
Enjoy!
The documentation is poor, the examples has broken tests and all examples on the net has a lot of different syntax in them and people are not really that great and telling which version of the software they are using when they are discussing stuff... So therefore I decided to describe how I did it as people might find it useful.
The setup is using mule 2.1.1 and Active MQ 5.1.1. It is built using maven 2.0.6. The example I have is a webservice that is forwarded to a message queue. I have used ActiveMQ without any setup, just starting the downloaded binary, accessed the web console and creating a new queue. The code follows now (I must apologize for my blog software that does not let me manipulate the HTML in a very good way, so it looks not that good, but hopefully readable):
The web service is defined as follows:
package hello;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface WebCall {
public void sendMessage(@WebParam(name="message") String messge);
}
This file will not compile unless you do "maven eclipse:eclipse" and import the project as it depends on javax.jws found in the one of the mule support jar files.
The config file for mule looks like this (have defined it in conf/ytelse-mule.xml):
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.1"
xmlns:ejb="http://www.mulesource.org/schema/mule/ejb/2.1" xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.1"
xmlns:cxf="http://www.mulesource.org/schema/mule/cxf/2.1"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.mulesource.org/schema/mule/core/2.1 http://www.mulesource.org/schema/mule/core/2.1/mule.xsd
http://www.mulesource.org/schema/mule/vm/2.1 http://www.mulesource.org/schema/mule/vm/2.1/mule-vm.xsd
http://www.mulesource.org/schema/mule/ejb/2.1 http://www.mulesource.org/schema/mule/ejb/2.1/mule-ejb.xsd
http://www.mulesource.org/schema/mule/cxf/2.1 http://www.mulesource.org/schema/mule/cxf/2.1/mule-cxf.xsd
http://www.mulesource.org/schema/mule/jms/2.1 http://www.mulesource.org/schema/mule/jms/2.1/mule-jms.xsd">
<description>Test ytelse</description>
<spring:beans>
<spring:import resource="classpath:applicationContext.xml" />
</spring:beans>
<jms:activemq-connector name="jmsConnector"
specification="1.1" brokerURL="vm://localhost" connectionFactory-ref="activeMqConnectionFactory" />
<jms:activemq-xa-connector name="xaConnector"
maxRedelivery="1">
<dispatcher-threading-profile
doThreading="false" />
</jms:activemq-xa-connector>
<model name="ytelseModel">
<service name="WebCall">
<inbound>
<cxf:inbound-endpoint address="http://localhost:65082/services/WebCall"
serviceClass="hello.WebCall" />
</inbound>
<outbound>
<pass-through-router>
<jms: outbound-endpoint queue="TestQ" connector-ref="jmsConnector"/>
</pass-through-router>
</outbound>
</service>
</model>
</mule>
The queue it sends to is TestQ. The config file takes in a spring config file where activeMqConnectionFactory is defined. The applicationContext.xml file is defined like this (put in conf/ dir):
<?xml version="1.0" encoding="UTF-8"?>
<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.5.xsd">
<bean id="activeMqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
</bean>
</beans>
As there is no configuration it will not try to embed a broker. I would have preferred to have an embedded broker, but I haven't figured out the configuration for that yet. Finally the hole shabang is built using maven and the pom.xml file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>no.rcn.orgreg</groupId>
<artifactId>ytelse</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>Ytelse v2.</name>
<description> The Loan Broker example application is based on the example presented in the Enterprise Integration Patterns book. This chapter of the book is available online so you can see a detailed description of the application here (http://www.eaipatterns.com/ComposedMessagingWS.html).</description>
<properties>
<muleVersion>2.1.1</muleVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.mule</groupId>
<artifactId>mule-core</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.modules</groupId>
<artifactId>mule-module-spring-config</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.transports</groupId>
<artifactId>mule-transport-ejb</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.transports</groupId>
<artifactId>mule-transport-jms</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.transports</groupId>
<artifactId>mule-transport-jetty</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.transports</groupId>
<artifactId>mule-transport-vm</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.transports</groupId>
<artifactId>mule-transport-cxf</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.transports</groupId>
<artifactId>mule-transport-http</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.modules</groupId>
<artifactId>mule-module-spring-extras</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>org.mule.modules</groupId>
<artifactId>mule-module-client</artifactId>
<version>${muleVersion}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>codehaus</id>
<name>Codehaus Maven 2.x Release Repository</name>
<url>http://repository.codehaus.org</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>codehaus-snapshots</id>
<name>Codehaus Maven 2.x Snapshots Repository</name>
<url>http://snapshots.repository.codehaus.org</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>apache-incubating</id>
<name>Apache incubating repository</name>
<url>http://people.apache.org/repo/m2-incubating-repository</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!--
This is actually from cxf's pom an shouldn't be necessary here.
-->
<repository>
<id>java.net</id>
<name>Java.net Repository</name>
<url>http://download.java.net/maven/1/</url>
<layout>legacy</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>apache-plugin-snapshots</id>
<name>Apache Maven Plugins Snapshot Repository</name>
<url>http://people.apache.org/maven-snapshot-repository</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
<build>
<resources>
<resource>
<directory>conf</directory>
</resource>
<!--
<resource>
<directory>src/main/resources</directory>
</resource>
-->
</resources>
<plugins>
<!-- "mvn install" will copy the target jar to the $MULE_HOME/lib/user directory,
overwriting the previous one. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-artifact</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${MULE_HOME}/lib/user</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<artifactItems>
<artifactItem>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<destFileName>${artifactId}.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.1.0</version>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
The trick in this file is that it adds conf/ and src/main/resources (commented out, but nice if you want to add property files at root into the built jars) into the classpath. To run it you do:
mvn install
This will now copy the needed jar files to $MULE_HOME/lib/user which is the place where mule looks for files when running code. This is described by the build step in the pom.xml. In addition to the ytelse.jar file the activemq files needed for connecting is found.
Starting mule using "mule -config conf/ytelse-mule.xml" will start up mule and make everything ready. Make sure that you have started activeMQ before trying to start mule as it will try to connect to the message broker upon startup.
After this is done, you can test the code using this simple webcall: http://localhost:65082/services/WebCall/sendMessage/message/Hi there.
This will put a message with the body "Hi there" on the queue TestQ, which you should be able to track using the admin console for ActiveMQ. (http://localhost:8161/admin/queues.jsp)
That's all there is to it
|