IBM WebSphere Application ServerTM
Release 7

Package com.ibm.wsspi.sibx.mediation

These interfaces provide full support for the mediation primitive programming model.

See:
          Description

Interface Summary
InputTerminal The input terminal of a mediation primitive.
Mediation Defines the contract between mediation primitives and the mediation flow engine.
MediationServices Provides services to a mediation primitive.
OutputTerminal The output terminal of a mediation primitive.
Terminal Defines a set of common methods for all terminal types.
TerminalType This is a marker interface which allows typing of terminals.
 

Class Summary
AbstractMediation Convenient abstract class for mediation primitive implementors.
 

Exception Summary
MediationBusinessException Thrown if a mediation primitive encounters a business logic error.
MediationConfigurationException Thrown if a mediation primitive encounters a configuration error.
MediationException Base exception for all mediation primitive exceptions.
TerminalNotFoundException Thrown if a mediation primitive attempts to obtain an undefined input or output terminal.
 

Package com.ibm.wsspi.sibx.mediation Description

These interfaces provide full support for the mediation primitive programming model.

Mediation primitives

These interfaces provide full support for the mediation primitive programming model. The mediation primitive programming model allows the development of mediation primitives which can then be composed into mediation flows.

Table of contents

  1. Overview
  2. Anatomy of a mediation primitive
  3. Mediation primitive lifecycle
  4. Programming a mediation primitive

Overview

Mediation primitives are the building blocks of mediation flows. A mediation primitive may be thought of as a piece of logic which acts on a message as it passed along a mediation flow. It may modify the contents of the message, and may also route the message by firing its output terminals.

Anatomy of a mediation primitive

A mediation primitive may have one or more input terminals, and zero or more output terminals. In addition, they also have zero or one failure terminals which are not exposed to the primitive programmer.

Mediation primitives are realized as Java beans which implement the SPI described by the Javadoc. The basic interface of a mediation primitive is described by the Mediation interface. This defines the methods which must be implemented by mediation primitive programmers.

Messages arrive at input terminals, and are processed by the primitive logic. As a result of the logic, the primitive may fire zero or more of its output terminals. The terminals of primitives are wired together to produce mediation flows.

If a mediation primitive encounters any problems during the mediation of a message, it may throw either a MediationConfigurationException or a MediationBusinessException to indicate the fact. This will result in the invocation of the primitive's failure terminal.

A default implementation of Mediation is provided in the AbstractMediation class. This implements the setMediationServices method, a useful getMediationServices method and also provides a default implementation of the init method.

Mediation services

A mediation primitive can access meta-data about itself via a MediationServices interface. This provides access to the input and output terminals, as well as the name of the primitive (as it is known within the flow) and its display name (which is normally more meaningful to an end user.)

Terminals

The input and output terminals retrieved from the MediationServices are derived from the Terminal interface. This interface provides access to the name of the terminals, as well as the TerminalType.

Input terminals are described by the InputTerminal interface, whilst output terminals are described by the OutputTerminal interface. The OutputTerminal interface provides an additional fire method which allows a mediation primitive to fire an output terminal.

Properties

Mediation primitives can define various properties which the mediation flow engine will populate from configuration information during the creation of the mediation primitive. These properties are defined by using the standard Javabean mechanisms. Namely, each property must have a public getter and setter method. Indexed properties are permitted.

6.0.2 onwards
From WebSphere ESB 6.0.2, it is possible for the properties of mediation primitives to be externally modified by administrators. There are scenarios where the internal value of a mediation primitive property is different to the value seen by, and expected to be set by the administrator. A typical example is where where the value of the property is presented as a choice from a restricted set of values. These may be presented to the administrator as string literal values such as "All" or "First" but may internally be recognised as integers such as 0 or 1. In this case, the mediation primitive must provide an additional method to perform any conversion from the string literal form to the form expected by the primitive. The signature of this method must be:

public  Convert(String stringForm);

For example, you may implement a mediation primitive with an integer property whose string literal values may be "First" and "All" in such a way:

        public static class FooMediation implements Mediation {
        
            private int distributionMode;
            private static final String MODE_FIRST = "first";
            private static final String MODE_ALL = "all;
            
            public int getDistributionMode() { return distributionMode;}
            
            public void setDistributionMode(int distributionMode) {
                this.distributionMode = distributionMode;
            }
            
            public int distributionModeConvert(String modeString) {
                int result = -1;
                
                try {
                        result =  Integer.parseInt(modeString);
                } catch (NumberFormatException nfe){
                    if(modeString.equalsIgnoreCase(MODE_FIRST)) {
                    result = 0;
                } else if (modeString.equalsIgnoreCase(MODE_ALL)) {
                    result = 1;
                }       
            }
            
            return result;
            }
            
            ...
        }
        

The mediation engine will always look for a conversion method before calling the setter for a mediation primitive property. If no conversion method is specified then the engine will attempt to convert the String directly to the expected type of the property.

The mediation primitive lifecycle

A mediation primitive has the following lifecycle:

  1. The mediation engine will call the default constructor.
  2. The mediation engine will set all properties on the mediation primitive.
  3. The mediation engine will create the MediationServices (including creating the input and output terminals) and set it using the setMediationServices method.
  4. The mediation engine will call the init method upon which the mediation primitive can perform any necessary initialization. The engine will only call init() once.
  5. At this point, the mediation is deemed to be ready, and the runtime will begin to invoke flows resulting in the mediate method being called.

Programming a mediation primitive

The simplest way to program a mediation primitive is to extend the AbstractMediation class, and implement the mediate method:

        public class FooMediation extends AbstractMediation {
        
            public void mediate(InputTerminal inputTerminal, DataObject message} 
                throws MediationConfigurationException, MediationBusinessException {
        
                // Do something with the message
            }
        }     
        

However, we will want to obtain the terminals for the mediation primitive, both to validate they are what we expect, and to fire output terminals later on. The best way to do this is to override the init method:

        public class FooMediation extends AbstractMediation {
        
                private InputTerminal in;
                private OutputTerminal out;
                
                public void init() throws MediationConfigurationException {
                        in = getMediationServices().getInputTerminal("in");
                        if(in == null) {
                            throw new MediationConfigurationException("No input terminal named in");
                        }
                        
                        out = getMediationServices().getOutputTerminal("out");
                        if(out == null) {
                            throw new MediationConfigurationException("No output terminal named out");
                        }
                }
                        
            public void mediate(InputTerminal inputTerminal, DataObject message} 
                throws MediationConfigurationException, MediationBusinessException {
        
                // Do something with the message
            }
        }     
        

In addition, we may want to provide some configuration to our mediation primitive by implementing some properties. For instance, we may want to define a string property named bar. We can also check that the value of that property is correct in the init method:

        public class FooMediation extends AbstractMediation {
        
                private String bar;
        
                private InputTerminal in;
                private OutputTerminal out;
                
                public void setBar(String bar) {
                    this.bar = bar;
                }
                
                public String getBar() {
                    return bar;
                }
                
                public void init() throws MediationConfigurationException {
                        in = getMediationServices().getInputTerminal("in");
                        if(in == null) {
                            throw new MediationConfigurationException("No input terminal named in");
                        }
                        
                        out = getMediationServices().getOutputTerminal("out");
                        if(out == null) {
                            throw new MediationConfigurationException("No output terminal named out");
                        }
                        
                        // If we require bar to have a value, we can validate this in the 
                        // init method:
                        if(bar == null) {
                            throw new MediationConfigurationException("bar property not set");
                        }
                }
                        
            public void mediate(InputTerminal inputTerminal, DataObject message} 
                throws MediationConfigurationException, MediationBusinessException {
        
                // Do something with the message
            }
        }     
        

The main work of the mediation primitive happens in the mediation method. We can implement the body of the method to work on the message and fire an output terminal accordingly:

        public class FooMediation extends AbstractMediation {
        
                private String bar;
        
                private InputTerminal in;
                private OutputTerminal out;
                
                public void setBar(String bar) {
                    this.bar = bar;
                }
                
                public String getBar() {
                    return bar;
                }
                
                public void init() throws MediationConfigurationException {
                        in = getMediationServices().getInputTerminal("in");
                        if(in == null) {
                            throw new MediationConfigurationException("No input terminal named in");
                        }
                        
                        out = getMediationServices().getOutputTerminal("out");
                        if(out == null) {
                            throw new MediationConfigurationException("No output terminal named out");
                        }
                        
                        // If we require bar to have a value, we can validate this in the 
                        // init method:
                        if(bar == null) {
                            throw new MediationConfigurationException("bar property not set");
                        }
                }
                        
            public void mediate(InputTerminal inputTerminal, DataObject message} 
                throws MediationConfigurationException, MediationBusinessException {
        
                        try{
                        // Do something with the message
                        message.setString("bar", bar);
                
                        // fire the output terminal
                        out.fire(message);
                } catch (Exception e){
                        throw new MediationBusinessException(e);
                }
            }
        }     
        


IBM WebSphere Application ServerTM
Release 7