IPF Scripting Layer

Scripting layer

The IPF scripting layer not only brings the Groovy programming language to your route definitions it also allows you to define your own DSL extensions. It consists of the DSL extension mechanism and the predefined DSL extensions. All predefined DSL extensions provided by IPF have been built using the DSL extension mechanism. You can get an overview of these extensions in the IPF extensions index. For a guide how to write you own DSL extensions refer to the DSL extensions guide or continue reading this section to see a very simple example. In IPF, all platform-camel-* components contribute their extensions to the scripting layer i.e. the DSL extension mechanism supports modularization (DSL extensions provided by individual components are pluggable).

In addition to predefined DSL extensions applications can easily define their own DSL extensions, for example, to give a project-specific message processor or a message processing pattern a custom name. This is explained in detail in the DSL extensions guide. It makes message processing routes more readable and allows other projects to reuse these extensions. DSL extensions may also be based on other DSL extensions i.e. composition of DSL extensions is supported as well. There is also extensive support for Groovy closures in combination with existing Camel DSL elements and IPF DSL extensions.

DSL extension mechanism

The DSL extension mechanism allows for extending the Apache Camel DSL and the IPF DSL with custom language elements. The definition of extensions is done with Groovy meta-programming. Route definitions that use DSL extensions must therefore be written in Groovy. A Groovy meta-programming-based mechanism was chosen because Camel itself doesn't support DSL extensions on Java-level (at least at the time of writing where Camel 1.6 was out).

Example

DSL extensions guide and tutorials

The example presented here is explained in much more detail in the DSL extensions guide. Furthermore, all tutorials make use of the DSL extension mechanism and the predefined DSL extensions.

The easiest way to learn the DSL extension mechanism is to start with a simple example. Let's say we want to introduce a new translate DSL element that translates a message from one language into another. To keep the examle simple we assume that the translating magic is done inside a single Translator processor.

Translator.java
package example;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class Translator implements Processor {

    public void process(Exchange exchange) throws Exception {
        // do language translation here ...
    }

}

Without using DSL extensions such a processor can be included into route definitions like in the following example.

MyRouteBuilder.groovy
package example

import org.apache.camel.spring.SpringRouteBuilder

class MyRouteBuilder extends SpringRouteBuilder {

    void configure() {
        from('direct:input')
        .process(new Translator())
        .to('direct:output')

    }

}

Our goal however is to introduce a translate DSL extension that makes use of this processor. The result should look like.

MyRouteBuilder.groovy
package example

import org.apache.camel.spring.SpringRouteBuilder

class MyRouteBuilder extends SpringRouteBuilder {

    void configure() {
        from('direct:input')
        .translate()
        .to('direct:output')

    }

}

To be able to use the translate() method in our route definitions we need to add that method into the corresponding DSL model class which is org.apache.camel.model.ProcessorType in our example. Adding the method is done via Groovy meta-programming inside an extensions block.

MyExtension.groovy
package example

import org.apache.camel.model.ProcessorType

class MyExtension {

    static extensions = {

        ProcessorType.metaClass.translate = {->
            delegate.process(new Translator())
        }

    }

}

You can add an extensions block to any class you like. To make the example work we have to wire the DSL extension, the route builder and the infrastructure components of the DSL extension mechanism together within a Spring application context.

context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://activemq.apache.org/camel/schema/spring"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://activemq.apache.org/camel/schema/spring 
http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">

    <camel:camelContext id="camelContext" />
    
    <bean id="routeBuilder" depends-on="routeModelExtender"
        class="example.MyRouteBuilder">
    </bean>
    
    <bean id="exampleModelExtension"
        class="example.MyExtension">
    </bean>
    
    <bean id="coreModelExtension"
        class="org.openehealth.ipf.platform.camel.core.extend.CoreModelExtension">
    </bean>
    
    <bean id="routeModelExtender"
        class="org.openehealth.ipf.platform.camel.core.extend.DefaultModelExtender">
        <property name="routeModelExtensions">
            <list>
                <ref bean="coreModelExtension" />
                <ref bean="exampleModelExtension" />
            </list>
        </property>
    </bean>

</beans>

The above example also shows how to include the predefined DSL extensions provided by platform-camel-core. Please note that this is not required to make our example work. It's only for demonstration purposes how to combine predefined DSL extensions with custom DSL extensions.

Limitations

DSL extensions defined in Groovy are not available for Camel's Java DSL or for the Spring-based XML configuration. Defining extensions for multiple languages is currently under discussion for Camel 2.x. Also, Java IDE's cannot detect extensions introduced via Groovy meta-programming i.e. code completion for these extensions isn't supported at the moment. We currently investigate whether this is possible with IntelliJ IDEA.

Predefined DSL extensions

Predefined DSL extensions are provided by the following IPF components.

Component Extension class Documentation
platform-camel-core org.openehealth.ipf.platform.camel.core.extend.CoreModelExtension Core features DSL
platform-camel-flow org.openehealth.ipf.platform.camel.flow.extend.FlowModelExtension Flow management DSL
platform-camel-hl7 org.openehealth.ipf.platform.camel.hl7.extend.Hl7ModelExtension HL7 processing DSL
platform-camel-lbs org.openehealth.ipf.platform.camel.lbs.core.extend.LbsModelExtension LBS processing DSL
platform-camel-event org.openehealth.ipf.platform.camel.event.extend.EventModelExtension Event processing DSL

A description of these components is given on the IPF architecture page. For a detailed description of the extensions follow the links in the extension documentation column. The extension classes can be combined as shown in the application configuration section.

Summary of all predefined DSL extensions

A summary of all predefined DSL extensions provided by IPF is given in the DSL extensions index appendix.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.