| <?xml version="1.0" encoding="ISO-8859-1"?> |
| |
| <document> |
| <properties> |
| <title>Apache Synapse - Extending...</title> |
| </properties> |
| <head> |
| <style type="text/css" xml:space="preserve"> |
| .command { |
| border: 1px dashed #3c78b5; |
| text-align: left; |
| background-color: #f0f0f0; |
| padding: 3px; |
| font-size: 11px; |
| font-family: Courier; |
| margin: 10px; |
| line-height: 13px; |
| } |
| .consoleOutput { |
| border: 1px dashed #3c78b5; |
| font-size: 11px; |
| font-family: Courier; |
| margin: 10px; |
| line-height: 13px; |
| background-color: #f0f0f0; |
| border-bottom: 1px dashed #3c78b5; |
| padding: 3px; |
| border-style: solid; |
| } |
| .info { |
| border-style: solid; |
| border-width: 1px; |
| border-color: #090; |
| background-color: #dfd; |
| text-align:left; |
| margin-top: 5px; |
| margin-bottom: 5px; |
| } |
| li { |
| font-family: Verdana, arial, sans-serif; |
| font-size: 11px; |
| line-height: 16px; |
| color: #000000; |
| font-weight: normal; |
| } |
| p { |
| font-family: Verdana, arial, sans-serif; |
| font-size: 11px; |
| line-height: 16px; |
| color: #000000; |
| font-weight: normal; |
| } |
| pre { |
| padding: 0px; |
| margin-top: 5px; |
| margin-left: 15px; |
| margin-bottom: 5px; |
| margin-right: 5px; |
| text-align: left; |
| background-color: #f0f0f0; |
| padding: 3px; |
| border: 1px dashed #3c78b5; |
| font-size: 11px; |
| font-family: Courier; |
| margin: 10px; |
| line-height: 13px; |
| } |
| h1 { |
| font-size: 24px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| color: #003366; |
| border-bottom: 1px solid #3c78b5; |
| padding: 2px; |
| margin: 36px 0px 4px 0px; |
| } |
| h2 { |
| font-size: 18px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| border-bottom: 1px solid #3c78b5; |
| padding: 2px; |
| margin: 27px 0px 4px 0px; |
| } |
| h3 { |
| font-size: 14px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| padding: 2px; |
| margin: 21px 0px 4px 0px; |
| } |
| h4 { |
| font-size: 12px; |
| line-height: normal; |
| font-weight: bold; |
| background-color: #f0f0f0; |
| padding: 2px; |
| margin: 18px 0px 4px 0px; |
| }</style> |
| </head> |
| <body> |
| <div style="margin-top:-40px; float:right; _margin-top:0px;"> |
| <img alt="Synapse logo" |
| src="images/synapse-logo-web2.png" width="197" |
| height="82"/> |
| </div> |
| <div> |
| <h1> |
| Apache Synapse ESB - Extending... |
| </h1> |
| </div> |
| <h2> |
| Writing custom Mediator implementations |
| </h2> |
| <p> |
| The primary interface of the Synapse API is the MessageContext interface |
| defined below. This essentially defines the per-message context passed |
| through the chain of mediators, for each and every message received and |
| processed by Synapse. Each message instance is wrapped within a |
| MessageContext instance, and the message context is set with the |
| references to the SynapseConfiguration and SynapseEnvironments. The |
| SynapseConfiguration holds the global configuration model that defines |
| mediation rules, local registry entries and other and configuration, while |
| the environment gives access to the underlying SOAP implementation used - |
| Axis2. A typical mediator would need to manipulate the MessageContext by |
| referring to the SynapseConfiguration. However it is strongly recommended |
| that the SynapseConfiguration is not updated by mediator instances as it |
| is shared by all messages, and may be updated by Synapse administration or |
| configuration modules. Mediator instances may store local message |
| properties into the MessageContext for later retrieval by successive |
| mediators.<br/> |
| </p> |
| <h4> |
| <a |
| href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/MessageContext.java?view=markup">MessageContext |
| Interface</a> |
| </h4> |
| <p/> |
| <pre xml:space="preserve">package org.apache.synapse; |
| |
| import ... |
| |
| public interface MessageContext { |
| |
| /** |
| * Get a reference to the current SynapseConfiguration |
| * |
| * @return the current synapse configuration |
| */ |
| public SynapseConfiguration getConfiguration(); |
| |
| /** |
| * Set or replace the Synapse Configuration instance to be used. May be used to |
| * programatically change the configuration at runtime etc. |
| * |
| * @param cfg The new synapse configuration instance |
| */ |
| public void setConfiguration(SynapseConfiguration cfg); |
| |
| /** |
| * Returns a reference to the host Synapse Environment |
| * @return the Synapse Environment |
| */ |
| public SynapseEnvironment getEnvironment(); |
| |
| /** |
| * Sets the SynapseEnvironment reference to this context |
| * @param se the reference to the Synapse Environment |
| */ |
| public void setEnvironment(SynapseEnvironment se); |
| |
| /** |
| * Get the value of a custom (local) property set on the message instance |
| * @param key key to look up property |
| * @return value for the given key |
| */ |
| public Object getProperty(String key); |
| |
| /** |
| * Set a custom (local) property with the given name on the message instance |
| * @param key key to be used |
| * @param value value to be saved |
| */ |
| public void setProperty(String key, Object value); |
| |
| /** |
| * Returns the Set of keys over the properties on this message context |
| * @return a Set of keys over message properties |
| */ |
| public Set getPropertyKeySet(); |
| |
| /** |
| * Get the SOAP envelope of this message |
| * @return the SOAP envelope of the message |
| */ |
| public SOAPEnvelope getEnvelope(); |
| |
| /** |
| * Sets the given envelope as the current SOAPEnvelope for this message |
| * @param envelope the envelope to be set |
| * @throws org.apache.axis2.AxisFault on exception |
| */ |
| public void setEnvelope(SOAPEnvelope envelope) throws AxisFault; |
| |
| /** |
| * SOAP message related getters and setters |
| */ |
| public ....get/set()... |
| |
| }</pre> |
| <p> |
| The MessageContext interface is based on the Axis2 <a>MessageContext</a> |
| interface, and uses the Axis2 <a>EndpointReference</a> and |
| SOAPEnvelope classes/interfaces. The purpose of this interface is to |
| capture a message as it flows through the system. As you will see the |
| message payload is represented using the SOAP infoset. Binary messages can |
| be embedded in the Envelope using MTOM or SwA attachments using the AXIOM |
| object model. |
| </p> |
| <h4> |
| <a |
| href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/Mediator.java?view=markup">Mediator |
| interface</a> |
| </h4> |
| <p> |
| The second key interface for mediator writers is the Mediator interface: |
| </p> |
| <pre xml:space="preserve">package org.apache.synapse; |
| |
| import org.apache.synapse.MessageContext; |
| |
| /** |
| * All Synapse mediators must implement this Mediator interface. As a message passes |
| * through the synapse system, each mediator's mediate() method is invoked in the |
| * sequence/order defined in the SynapseConfiguration. |
| */ |
| public interface <span style="font-weight: bold;">Mediator </span>{ |
| |
| /** |
| * Invokes the mediator passing the current message for mediation. Each |
| * mediator performs its mediation action, and returns true if mediation |
| * should continue, or false if further mediation should be aborted. |
| * |
| * @param synCtx the current message for mediation |
| * @return true if further mediation should continue |
| */ |
| public boolean mediate(MessageContext synCtx); |
| |
| /** |
| * This is used for debugging purposes and exposes the type of the current |
| * mediator for logging and debugging purposes |
| * @return a String representation of the mediator type |
| */ |
| public String getType(); |
| }</pre> |
| <p> |
| A mediator can read and/or modify the <a>SynapseMessage</a> in |
| any suitable manner - adjusting the routing headers or changing the |
| message body. If the mediate() method returns false, it signals to the |
| Synapse processing model to stop further processing of the message. For |
| example, if the mediator is a security agent it may decide that this |
| message is dangerous and should not be processed further. This is |
| generally the exception as mediators are usually designed to co-operate to |
| process the message onwards. |
| </p> |
| <h3> |
| Leaf and Node Mediators, List mediators and Filter mediators |
| </h3> |
| <p> |
| Mediators may be Node mediators (i.e. these that can contain child |
| mediators) or Leaf mediators (mediators that does not hold any other child |
| mediators). A Node mediator must implement the |
| org.apache.synapse.api.ListMediator interface listed below, or extend from |
| the org.apache.synapse.mediators.AbstractListMediator. |
| </p> |
| <h4> |
| <a |
| href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/ListMediator.java?view=markup">The |
| ListMediator interface</a> |
| </h4> |
| <pre xml:space="preserve">package org.apache.synapse.mediators; |
| |
| import java.util.List; |
| |
| /** |
| * The List mediator executes a given sequence/list of child mediators |
| */ |
| public interface ListMediator extends Mediator { |
| /** |
| * Appends the specified mediator to the end of this mediator's (children) list |
| * @param m the mediator to be added |
| * @return true (as per the general contract of the Collection.add method) |
| */ |
| public boolean addChild(Mediator m); |
| |
| /** |
| * Appends all of the mediators in the specified collection to the end of this mediator's (children) |
| * list, in the order that they are returned by the specified collection's iterator |
| * @param c the list of mediators to be added |
| * @return true if this list changed as a result of the call |
| */ |
| public boolean addAll(List c); |
| |
| /** |
| * Returns the mediator at the specified position |
| * @param pos index of mediator to return |
| * @return the mediator at the specified position in this list |
| */ |
| public Mediator getChild(int pos); |
| |
| /** |
| * Removes the first occurrence in this list of the specified mediator |
| * @param m mediator to be removed from this list, if present |
| * @return true if this list contained the specified mediator |
| */ |
| public boolean removeChild(Mediator m); |
| |
| /** |
| * Removes the mediator at the specified position in this list |
| * @param pos the index of the mediator to remove |
| * @return the mediator previously at the specified position |
| */ |
| public Mediator removeChild(int pos); |
| |
| /** |
| * Return the list of mediators of this List mediator instance |
| * @return the child/sub mediator list |
| */ |
| public List getList(); |
| }</pre> |
| <p> |
| A ListMediator implementation should call super.mediate(synCtx) to process |
| its sub mediator sequence. A FilterMediator is a ListMediator which |
| executes its sequence of sub mediators on successful outcome of a test |
| condition. The Mediator instance which performs filtering should implement |
| the FilterMediator interface. |
| </p> |
| <h4> |
| <a |
| href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/FilterMediator.java?view=markup">FilterMediator |
| interface</a> |
| </h4> |
| <pre xml:space="preserve">package org.apache.synapse.mediators; |
| |
| import org.apache.synapse.MessageContext; |
| |
| /** |
| * The filter mediator is a list mediator, which executes the given (sub) list of mediators |
| * if the specified condition is satisfied |
| * |
| * @see FilterMediator#test(org.apache.synapse.MessageContext) |
| */ |
| public interface <span style="font-weight: bold;">FilterMediator </span>extends ListMediator { |
| |
| /** |
| * Should return true if the sub/child mediators should execute. i.e. if the filter |
| * condition is satisfied |
| * @param synCtx |
| * @return true if the configured filter condition evaluates to true |
| */ |
| public boolean test(MessageContext synCtx); |
| }</pre> |
| <h2> |
| Writing custom Configuration implementations for mediators |
| </h2> |
| <p> |
| You may write your own custom configurator for the Mediator implementation |
| you write without relying on the Class mediator or Spring extension for |
| its initialization. You could thus write a MediatorFactory implementation |
| which defines how to digest a custom XML configuration element to be used |
| to create and configure the custom mediator instance. A MediatorSerializer |
| implementation defines how a configuration should be serialized back into |
| an XML configuration. The custom MediatorFactory & MediatorSerializer |
| implementations and the mediator class/es must be bundled in a JAR file |
| conforming to the J2SE Service Provider model (See the description for |
| Extensions below for more details and examples) and placed into the |
| SYNAPSE_HOME/lib folder, so that the Synapse runtime could find and load |
| the definition. Essentially this means that a custom JAR file must bundle |
| your class implementing the Mediator interface, and the MediatorFactory |
| implementation class and contain two text files named |
| "org.apache.synapse.config.xml.MediatorFactory" and |
| "org.apache.synapse.config.xml.MediatorSerializer" which will contain the |
| fully qualified name(s) of your MediatorFactory and MediatorSerializer |
| implementation classes. You should also place any dependency JARs into the |
| same lib folder so that the correct classpath references could be made. |
| The MediatorFactory interface listing is given below, which you should |
| implement, and its getTagQName() method must define the fully qualified |
| element of interest for custom configuration. The Synapse initialization |
| will call back to this MediatorFactory instance through the |
| createMediator(OMElement elem) method passing in this XML element, so that |
| an instance of the mediator could be created utilizing the custom XML |
| specification and returned. See the ValidateMediator and the |
| ValidateMediatorFactory classes under modules/extensions in the Synapse |
| source distribution for examples. |
| </p> |
| <h4> |
| <a |
| href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactory.java?view=markup">The |
| MediatorFactory interface</a> |
| </h4> |
| <pre xml:space="preserve">package org.apache.synapse.config.xml; |
| |
| import ... |
| |
| /** |
| * A mediator factory capable of creating an instance of a mediator through a given |
| * XML should implement this interface |
| */ |
| public interface MediatorFactory { |
| /** |
| * Creates an instance of the mediator using the OMElement |
| * @param elem |
| * @return the created mediator |
| */ |
| public Mediator createMediator(OMElement elem); |
| |
| /** |
| * The QName of this mediator element in the XML config |
| * @return QName of the mediator element |
| */ |
| public QName getTagQName(); |
| }</pre> |
| <p/> |
| <h4> |
| <a |
| href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializer.java?view=markup">The |
| MediatorSerializer interface</a> |
| </h4> |
| <pre xml:space="preserve">package org.apache.synapse.config.xml; |
| |
| import ... |
| |
| /** |
| * Interface which should be implemented by mediator serializers. Does the |
| * reverse of the MediatorFactory |
| */ |
| public interface MediatorSerializer { |
| |
| /** |
| * Return the XML representation of this mediator |
| * @param m mediator to be serialized |
| * @param parent the OMElement to which the serialization should be attached |
| * @return the serialized mediator XML |
| */ |
| public OMElement serializeMediator(OMElement parent, Mediator m); |
| |
| /** |
| * Return the class name of the mediator which can be serialized |
| * @return the class name |
| */ |
| public String getMediatorClassName(); |
| }</pre> |
| <h2> |
| Configuring mediators |
| </h2> |
| <p> |
| Mediators could access the Synapse registry to load resources and |
| configure the local behaviour. Refer to the Spring mediator and Script |
| mediator implementations for examples on how this could be achieved. |
| </p> |
| <h4> |
| Loading of Extensions by the Synapse runtime |
| </h4> |
| <p> |
| Synapse loads available extensions from the runtime classpath using the <a |
| href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider">J2SE |
| Service Provider model</a>. This essentially iterates over the |
| available JAR files, for a META-INF/services directory within each file, |
| and looks for a text file with the name |
| org.apache.synapse.config.xml.MediatorFactory which contains a list of |
| fully qualified classname that implement the above interface, listing each |
| class in a separate line. e.g. The built-in synapse-extensions.jar |
| contains the following structure |
| </p> |
| <pre xml:space="preserve">synapse-extensions.jar |
| /META-INF/services |
| org.apache.synapse.config.xml.MediatorFactory |
| org.apache.synapse.config.xml.MediatorSerializer |
| /... the implementation classes as usual...</pre> |
| </body> |
| </document> |