You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 8 Next »

ServiceMix Script

The ServiceMix Script component provides JBI integration with scripting engines.

Note that this component is only available in releases >= 3.1 and older scripting component will be deprecated in future releases.

Deployment

Here is an example of a SU deploymennt. The SU is only a zip of these two files:

xbean.xml
<beans xmlns:script="http://org.apache.servicemix/script/1.0"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:test="urn:test">
  <script:exchangeProcessor service="test:groovy" endpoint="endpoint">
    <property name="helpers">
      <list>
        <ref bean="groovyExchangeHelper" />
      </list>
    </property>
    <property name="implementation" ref="groovyExchangeProcessor" />
  </script:exchangeProcessor>
  <script:exchangeHelper id="groovyExchangeHelper" singleton="true" />
  <lang:groovy id="groovyExchangeProcessor"
               script-source="classpath:GroovyExchangeProcessor.groovy">
    <lang:property name="exchangeHelper" ref="groovyExchangeHelper" />
  </lang:groovy>
</beans>
GroovyExchangeProcessor.groovy
import org.apache.servicemix.common.ExchangeProcessor;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.NormalizedMessage;
import org.apache.servicemix.jbi.jaxp.StringSource;
import org.apache.servicemix.script.ScriptExchangeHelper;
import org.apache.servicemix.jbi.jaxp.SourceTransformer;

class GroovyExchangeProcessor implements ExchangeProcessor {

    @Property ScriptExchangeHelper exchangeHelper;

	def void start() {
	    println "Starting";
	}

    def void process(MessageExchange exchange) {
    	def inputMessage = new SourceTransformer().toString(exchange.getInMessage().getContent());
    	println "Hello, I got an input message "+inputMessage;
    	NormalizedMessage out = exchange.createMessage();
        out.setContent(new StringSource("<world>hello</world>"));
        exchange.setMessage(out, "out");
        exchangeHelper.sendExchange(exchange);    	
    }
    
    def void stop() {
    	println "Stopping";
    }
}

Accessing the Delivery Channel

ATTENTION: This idea was develop during debugging another problem and so I forgot that I actually added the method getChannel() to the ScriptExchangeProcessorEndpoint which without this idea is not going to fly. So, until this method is added there is no way to make this fly. Also this Endpoint is fixed to be a Provider and so it could never send anything else than an InOnly method anyhow, sorry.
Please check out this JIRA issue: https://issues.apache.org/activemq/browse/SM-1112 for more info.

In order to create Message Exchanges one needs the Delivery Channel to obtain the Message Exchange Factory to create them. This is not possible by default but can be easily added using a customer Script Helper class. The only thing to do is to create a class that implements the Script Helper interface and use the Script Exchange Processor Endpoint instance to obtain the Delivery Channel from. Now you can either provide the Delivery Channel as is or you can create convenience method to create Message Exchanges for example. This is how a customer Script Helper class would look like:

foo.MyScriptHelper.java
package foo;

import javax.jbi.messaging.DeliveryChannel;

import org.apache.servicemix.script.ScriptExchangeProcessorEndpoint;
import org.apache.servicemix.script.ScriptHelper;

public class MyScriptExchangeHelper
   implements ScriptHelper
{
    protected ScriptExchangeProcessorEndpoint mEndpoint;

    public void setScriptExchangeProcessorEndpoint(
        ScriptExchangeProcessorEndpoint pEndpoint
    ) {
        mEndpoint = pEndpoint;
    }

    public DeliveryChannel getChannel() {
        return mEndpoint.getChannel();
    }
}

After that you only need to use a Spring Bean to create an instance and the use the same references in the rest of the Script settings. This is what needs to be changed from the xbean.xml mentioned above:

xbean.xml changes
<bean
    id="groovyExchangeHelper"
    class="foo.MyScriptExchangeHelper"
/>

<!--<script:exchangeHelper id="groovyExchangeHelper" singleton="true" />-->

The Groovy code could then look like this:

GroovyExchangeProcessor.groovy
import org.apache.servicemix.common.ExchangeProcessor;
import javax.jbi.messaging.MessageExchange;
import org.apache.servicemix.jbi.jaxp.StringSource;
import org.apache.servicemix.script.ScriptHelper;
import org.apache.commons.logging.LogFactory;

class GroovyExchangeProcessor
    implements ExchangeProcessor
{
    @Property ScriptHelper exchangeHelper;

    def mLog = LogFactory.getLog( getClass() );

    def void start() {
        mLog.info( "Starting" );
    }

    def void process(MessageExchange pExchange) {
        def lChannel = exchangeHelper.getChannel();
        def lRequest = lChannel.createExchangeFactory().createInOutExchange();
        lRequest.setService( new QName( "urn:test", "target-service" ) );
        lRequest.setOperation( new QName( "MyOpertation" ) );
        def lNM = lRequest.createMessage();
        lNM.setContent( new StringSource( "<receiver><title>Zero</title><index>0</index></receiver>" ) );
        lRequest.setInMessage( lNM );
        mLog.info( "process() send new ME: " + lRequest );
        lChannel.send( lRequest );
    }

    def void stop() {
        mLog.info( "Stopping" );
    }
}

Attention:

  • if you do not extend the ScriptExchangeHelper then you need to change the type in the Groovy script to ScriptHelper for the exchangeHelper propery
  • if you extend the ScriptExchangeHelper then you have to call the super.setScriptExchangeProcessorEndpoint() method in order to set the private member there too, otherwise you will experience Null Pointer Exceptions
  • you have to use the Spring Bean in the xbean.xml because the script:exchangeHelper is fixed to use the super class
  • no need to upcast the exchange helper property in the Groovy script; even though the type is specified there Groovy still is able to find the method in the sub class
  • No labels