Index Changes
Fuji Home

Enterprise Integration Pattern Extensibility

Overview

The EIP implementation we have today, have static types. For example aggregate only has a "set" type, message filters only have "xpath" and "regex" types. The platform can be extended by adding addition "types" to the EIP's, these types though should be pluggable dynamically. A proposal for how we can achieve this follows.

Design

In general, each EIP processes an exchange, based on the type of the EIP the message contents are processed and a result is produced. The result could be a list of split messages (split), a route name (cbr), a boolean (filter), which feeds into the overall implementation of the pattern. The parameters which affect the processing are:
  • The EIP itself ( Split: splits the exchange, CBR: selects a route for the exchange by reading it's contents)
  • The EIP type ( "xpath", "regex" )
  • The configuration ( xpath expression, aggregate conditions )

Additional types can be added to EIPs dynamically if, we define an interface/SPI for processing the exchange as follows :

public interface PatternType<T> {

    /** 
     *  Process the message and return the result.
     */
     T processMessage(MessageExchange exchange);

    /** Set the type configuration, this will be called once and 
     *  always before processMessage is invoked 
     */
    void setConfiguration(HashMap typeConfig);

    /** 
     * Callback for stateful EIPs such as Aggregate, which do not return the 
     * processed exchange immediately. For EIP types that do not need the callback, this is a nop
     */
    void setListener(PatternListener listener);
}
public interface PatternListener {

    /** Notification to send an exchange.
     */
    void sendExchange(MessageExchange exchange);
}

Specific type interfaces for each EIP, defined as such:

    public interface SplitType<T> extends PatternType<T>{
    }


    public interface AggregateType<T> extends PatternType<T>{
    }


    public interface ContentRouteType<T> extends PatternType<T>{
    }


    public interface MessageFilterType<T> extends PatternType<T>{
    }

we could add eip specific spi to these interfaces, if needed, right now the basic interface seems to be sufficient.

Java Type Implementation

An OSGi bundle can register a services which implements a specific type interface with the service property
  • org.glassfish.openesb.eip.typeName

which identifies the name of the type. When an EIP is being executed, it will look for the type implementation service in the OSGi service registry.

Example

Split could be defined in the IFL as :
ftp "in"
file "out"

route do 
  from "in"
  split custom "custom-split-config"
  to "out"
end

The following OSGi Bundle adds the type implementation:

public class CustomSplitType implements BundleActivator, SplitType {
    
    HashMap config_;
    ServiceRegistration type_;

    public void start(BundleContext ctx) throws Exception {
        type_ = ctx.registerService(
                SplitType.class.getName(), this, getTypeProperties());
    }

    public void stop(BundleContext ctx) throws Exception {
        type_.unregister();
    }

    public ArrayList processMessage(MessageExchange exchange) throws Exception {
        // Process the message based on eip/type
        
        // One way exchange, so there's no need to return anything
        return exchange;
    }
        
    void setConfiguration(HashMap typeConfig){
       
        // This has all the contents of [custom-split-config/service.properties]
        config_ = typeConfig;
    }


    void setListener(IntegrationPatternListener listener){
      //no-op;
    }

    private Properties getTypeProperties() {

        Properties props = new Properties();
        props.put("org.glassfish.openesb.typeName", "custom");
        return props;
    }

}

The runtime split execution will look up the type implementation i.e. an OSGi service registration of "SplitType" with org.glassfish.openesb.eip.typeName= "custom" and then first invoke the setConfiguration() operation followed by the processMessage(), the resulting list of documents will then be enveloped in the right exchange and will continue on the route path.

Thoughts

  • Right now there is a generic interface PatternType, we can add specifics to the EIP interfaces if needed.
  • The runtime has the context for the EIP, for instance the runtime execution of aggregate would know that aggregate is statful and handle the type execution in the context of the EIP.

JSPWiki v2.4.100
[RSS]
« Home Index Changes Prefs
This page (revision-9) was last changed on 20-Mar-09 14:58 PM, -0700 by Nikita