Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Switched from mvn:create goal to mvn:generate due to deprecation

...

Info

For the purposes of the tutorial a single Maven project will be used for both the client and server. Ideally you would break your application down into the appropriate components.

Code Block
mvn archetype:creategenerate -DgroupId=org.example -DartifactId=CamelWithJmsAndSpring

...

First we need to have dependencies for the core Camel jars, its spring, jms components and finally ActiveMQ as the message broker.

Wiki Markup
{snippet:id=e1|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/pom.xml}
As we use spring xml configuration for the ActiveMQ JMS broker we need this dependency:
Wiki Markup
{snippet:id=e2|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/pom.xml}

Writing the Server

Create the Spring Service

For this example the Spring service (= our business service) on the server will be a simple multiplier which trebles in the received value.

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/examples/camel-example-spring-jms/src/main/java/org/apache/camel/example/server/Multiplier.java}
And the implementation of this service is:
Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/examples/camel-example-spring-jms/src/main/java/org/apache/camel/example/server/Treble.java}
Notice that this class has been annotated with the @Service spring annotation. This ensures that this class is registered as a bean in the registry with the given name multiplier.

Define the Camel Routes

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/examples/camel-example-spring-jms/src/main/java/org/apache/camel/example/server/ServerRoutes.java}
This defines a Camel route from the JMS queue named numbers to the Spring bean named multiplier. Camel will create a consumer to the JMS queue which forwards all received messages onto the the Spring bean, using the method named multiply.

...

The Spring config file is placed under META-INF/spring as this is the default location used by the Camel Maven Plugin, which we will later use to run our server.
First we need to do the standard scheme declarations in the top. In the camel-server.xml we are using spring beans as the default bean: namespace and springs context:. For configuring ActiveMQ we use broker: and for Camel we of course have camel:. Notice that we don't use version numbers for the camel-spring schema. At runtime the schema is resolved in the Camel bundle. If we use a specific version number such as 1.4 then its IDE friendly as it would be able to import it and provide smart completion etc. See Xml Reference for further details.

Wiki Markup
{snippet:id=e1|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/META-INF/spring/camel-server.xml}
We use Spring annotations for doing IoC dependencies and its component-scan features comes to the rescue as it scans for spring annotations in the given package name:
Wiki Markup
{snippet:id=e2|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/META-INF/spring/camel-server.xml}
Camel will of course not be less than Spring in this regard so it supports a similar feature for scanning of Routes. This is configured as shown below.
Notice that we also have enabled the JMXAgent so we will be able to introspect the Camel Server with a JMX Console.
Wiki Markup
{snippet:id=e3|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/META-INF/spring/camel-server.xml}
The ActiveMQ JMS broker is also configured in this xml file. We set it up to listen on TCP port 61610.
Wiki Markup
{snippet:id=e4|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/META-INF/spring/camel-server.xml}
As this examples uses JMS then Camel needs a JMS component that is connected with the ActiveMQ broker. This is configured as shown below:
Wiki Markup
{snippet:id=e5|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/META-INF/spring/camel-server.xml}
Notice: The JMS component is configured in standard Spring beans, but the gem is that the bean id can be referenced from Camel routes - meaning we can do routing using the JMS Component by just using jms: prefix in the route URI. What happens is that Camel will find in the Spring Registry for a bean with the id="jms". Since the bean id can have arbitrary name you could have named it id="jmsbroker" and then referenced to it in the routing as from="jmsbroker:queue:numbers).to("multiplier");
We use the vm protocol to connect to the ActiveMQ server as its embedded in this application.

...

We will initially create a client by directly using ProducerTemplate. We will later create a client which uses Spring remoting to hide the fact that messaging is being used.

Wiki Markup
{snippet:id=e1|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/camel-client.xml}
Wiki Markup
{snippet:id=e2|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/camel-client.xml}
Wiki Markup
{snippet:id=e3|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/camel-client.xml}
The client will not use the Camel Maven Plugin so the Spring XML has been placed in src/main/resources to not conflict with the server configs.

...

And the CamelClient source code:

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/examples/camel-example-spring-jms/src/main/java/org/apache/camel/example/client/CamelClient.java}
The ProducerTemplate is retrieved from a Spring ApplicationContext and used to manually place a message on the "numbers" JMS queue. The requestBody method will use the exchange pattern InOut, which states that the call should be synchronous, and that the caller expects a response.

...

Spring Remoting "eases the development of remote-enabled services". It does this by allowing you to invoke remote services through your regular Java interface, masking that a remote service is being called.

Wiki Markup
{snippet:id=e1|lang=xml|url=camel/trunk/examples/camel-example-spring-jms/src/main/resources/camel-client-remoting.xml}
The snippet above only illustrates the different and how Camel easily can setup and use Spring Remoting in one line configurations.

...

And the Java client source code:

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/examples/camel-example-spring-jms/src/main/java/org/apache/camel/example/client/CamelClientRemoting.java}
Again, the client is similar to the original client, but with some important differences.

...

Okay enough talk, show me the code!

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/examples/camel-example-spring-jms/src/main/java/org/apache/camel/example/client/CamelClientEndpoint.java}
Switching to a different component is just a matter of using the correct endpoint. So if we had defined a TCP endpoint as: "mina:tcp://localhost:61610" then its just a matter of getting hold of this endpoint instead of the JMS and all the rest of the java code is exactly the same.

...