Thursday, 22 September 2011

jruby processor with activemq-5.5.0

Activemq is already in bundle with camel. The camel config file is in $ACTIVEMQ_HOME/conf/camel.xml.

But you need something more to use a jruby processor with activemq:
- add lang namespace to camel.xml;
- add a aopalliance.jar and jruby.jar to classpath (and more, if you need logback);
- write and register jruby bean.

Add namespace to camel.xml: just replace header with:
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="
                           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                           http://www.springframework.org/schema/lang
                           http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
                           http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

Add a aopalliance.jar to classpath: download springsource-2.5 with all dependencies. Unzip it and get aopalliance.jar from the lib/aopalliance directory.

Activemq $CLASSPATH is defined as $ACTIVEMQ_HOME/conf, so create a ruby folder in conf and add a jruby bean named ruby_processor.rb:
java_import "org.apache.camel.Exchange"
java_import "org.apache.camel.Processor"
java_import "org.slf4j.Logger"
java_import "org.slf4j.LoggerFactory"
java_import "ch.qos.logback.classic.LoggerContext"

java_package "com.test.camel"

class RubyProcessor
  include Processor

  def initialize
    @logger = LoggerFactory.getLogger("com.test.camel.#{File.basename(__FILE__, ".rb")}");
  end  

  java_signature "void process(Exchange exchange)"
  def process(exchange)
    test = exchange.in.headers['test']
    @logger.info("RubyProcessor: header test is: #{test}")
    exchange.in.set_header("Issuer", "rubyProcessor")
  end
end
Please note this bean does very few: just dump the value of a header to a log file, then sets a new header. It is just e proof-of-concept bean.

In camel.xml add a test route like:
<from uri="activemq:example.A"/>
     <bean ref="rubyProcessor" />
            <to uri="activemq:example.B" />

 <lang:jruby id="rubyProcessor"
              script-interfaces="org.apache.camel.Processor"
              script-source="classpath:ruby/ruby_processor.rb">
  </lang:jruby>

The ticky part.


To have logback work first you need to include in lib folder logback-classic and logback-core then I had to upgrade slf4j to 1.6.2 which means copying a couple of jars both in lib and in lib/optional.

The logback.xml can be created in conf, logfile from logback are written in $ACTIVEMQ_HOME.

Than I noticed the ruby scripting fails to work in the routes. I had to replace the <ruby> tags with <simple>.

No comments: