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.
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.
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 {@link com.ibm.wsspi.sibx.mediation.Mediation 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 {@link com.ibm.wsspi.sibx.mediation.MediationConfigurationException MediationConfigurationException} or a {@link com.ibm.wsspi.sibx.mediation.MediationBusinessException 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 {@link com.ibm.wsspi.sibx.mediation.AbstractMediation AbstractMediation} class. This implements the {@link com.ibm.wsspi.sibx.mediation.Mediation#setMediationServices(com.ibm.wsspi.sibx.mediation.MediationServices) setMediationServices} method, a useful {@link com.ibm.wsspi.sibx.mediation.AbstractMediation#getMediationServices() getMediationServices} method and also provides a default implementation of the {@link com.ibm.wsspi.sibx.mediation.Mediation#init() init} method.
A mediation primitive can access meta-data about itself via a {@link com.ibm.wsspi.sibx.mediation.MediationServices 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.)
The input and output terminals retrieved from the MediationServices are derived from the {@link com.ibm.wsspi.sibx.mediation.Terminal Terminal} interface. This interface provides access to the name of the terminals, as well as the {@link com.ibm.wsspi.sibx.mediation.TerminalType TerminalType.}
Input terminals are described by the {@link com.ibm.wsspi.sibx.mediation.InputTerminal InputTerminal} interface, whilst output terminals are described by the {@link com.ibm.wsspi.sibx.mediation.OutputTerminal OutputTerminal} interface. The OutputTerminal interface provides an additional {@link com.ibm.wsspi.sibx.mediation.OutputTerminal#fire(DataObject) fire} method which allows a mediation primitive to fire an output terminal.
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.
A mediation primitive has the following lifecycle:
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); } } }