The Synapse configuration language is designed to support a processing model where messages come into Synapse, are processed via some number of mediators and then delivered to an endpoint somewhere. It is currently direction agnostic, but directionality can easily be added as a selection mechanism for mediators (see below for details).
A Synapse configuration looks like the following at the top level:
<synapse> registrydef+ <definitions> (sequencedef | endpointdef | literalpropertydef)+ <definitions>? <proxies> proxyservice+ </proxies>? <rules [key="string"]> mediator* </rules> </synapse>
A registrydef token represents a <registry> element which is used to define a Registry which is referenced within the configuration.
<registry [name="string"] provider="string"/> <property name="string" value="string"/>* </registry>
The registry definition without a name becomes the 'default' registry for the Synapse instance, and any reference to a registry which does not specify a registry name defaults to this instance. Optionally, a number of configuration properties may be specified to configure an instance of a registry.
The <definitions> section defines reusable elements that can be used from within the rules, and the <rules> section contains the sequence of mediators that every message passes through during mediation.
The token literalpropertydef refers to a <set-property> element as follows:
<set-property name="string" [value="string"] [src="url"] [key="string"]> <inline-xml/>? <set-property/>
These properties are top level properties which are set globally for the entire system. Values of these properties can be retrieved via the extension XPath function called "synapse:get-property(prop-name)".
A property can be static literal text (specified with the value attribute) or static XML specified as an inline XML fragment or specified as a URL (using the src attribute). A property can alternatively be a DynamicProperty which will reference a key on a Registry. If a property is a DynamicProperty, it will be fetched from the Registry and cached locally as per meta information provided by the Registry for caching. DynamicProperties are automatically refreshed when expired, and thus can be used to specify dynamic behaviour in Synapse.
Dynamic properties allows the creation of Dynamic Sequences, Endpoints and Proxies whose definition would change accordingly with any changes on the property.
A sequencedef token represents a <sequence> element which is used to define a named sequence of mediators that can be invoked later by name as a sequence of mediators.
<sequence name="string" [onError="string"] [key="string"]> mediator* </sequence>
If an optional error handler sequence name is specified through the attribute 'onError', an exception on this sequence will invoke the sequence specified by this name.
A Dynamic Sequence may be defined by specifying a Dynamic Property as its definition. As the dynamic property changes, the sequence will dynamically be updated accordingly.
An endpointdef token represents an <endpoint> element which is used to give a logical name to an endpoint address. If the address is not just a simple URL, then extensibility elements may be used to indicate the address (i.e. to compute the address at runtime).
<endpoint name="string" [address="url"] [key="string"] [force="soap|pox"] [optimize="mtom|swa"]> <enableRM/>? <enableSec [policy="key"]/>? <enableAddressing separateListener="true|false"/>? .. extensibility .. </endpoint>
The enableRM/enableSec options turns on WS-Security or WS-RM on outgoing messages to this endpoint and specific policies may be specified for configuration
A Dynamic Endpoint may be defined by specifying a Dynamic Property as its definition. As the dynamic property changes, the endpoint will dynamically be updated accordingly.
NOTE: The Rampart and/or Sandesha configuration options may change with Axis2 changes currently in progress
The <proxies> section defines Synapse Proxy services, which are real Axis2 services hosted on Synapse, which allows WSDL mediation as well as the ability to expose existing services on Synapse, with possibly different semantics, such as WS-Security, WS-RM and Transport switching etc.
A proxyservice token represents a <proxy> element which is used to define a Synapse Proxy service.
<proxy name="string" [description="string"] [transports="(http |https |jms )+|all"]> <target (inSequence="name" outSequence="name") | endpoint="name"/>? // defaults to the synapse main sequence <wsdl key="string">? <enableRM/>? <enableSec/>? <policy key="string">* // optional service level policies // (e.g. WS-Security and/or WS-RM policies) <property name="string" value="string"/>* // optional service parameters // (e.g. transport.jms.ConnectionFactory) </proxy>
A proxy service is created and exposed on the specified transports through the underlying Axis2 instance, exposing service EPR's as per the standard Axis2 conventions - based on the service name. (Note: that currently Axis2 does not allow custom URI's to be set for services on some transports.) The Proxy service could be exposed over all enabled Axis2 transports such as http, https, JMS etc. or on a subset of these. Each service could define the target for received messages as a named sequence or a direct endpoint. If a target is not supplied, the default Synapse rules will apply for incoming message mediation. Any supplied policies would apply as service level policies, and any properties could be passed into the proxy services' AxisService instance (e.g. the JMS destination etc). If the proxy service should enable WS-Reliable Messaging or Security, the appropriate modules could be engaged.
A Dynamic Proxy may be defined by specifying a Dynamic Property as its definition. As the dynamic property changes, the proxy will dynamically be updated accordingly.
A mediator token refers to any of the following tokens:
send | drop | log | makefault | transform | header | filter | switch | class | validate | setproperty | sequenceref | in | out | rm | try
In addition to the above, Synapse will be able to load mediators via the J2SE Service Provider model. Mediator extensions must implement the MediatorFactory interface, similarly to the configuration extensions mentioned previously.
The send token represents a <send> element. The <send> element is used to send messages out of Synapse to some endpoint, and stop further mediation of the message. The send mediator also copies any correlation message context properties from the current message context to the reply message received on the execution of the send operation. This allows the reply messages to be correlated to the original messages in a flexible manner. Messages may be correlated by WS-A MessageID, or even simple custom text labels. Also see the set-property mediator.
In the simplest case, the place to send the message to is implicit in the message (via a property of the message itself)- that is indicated by the following:
<send/>
If the message is to be sent to one or more endpoints, then the following is used:
<send> (endpointref | endpoint)+ </send>
where the endpointref token refers to the following:
<endpoint ref="name"/>
and the endpoint token refers to an anonymous endpoint defined inline:
<endpoint address="url"/>
If the message is to be sent to an endpoint selected by load balancing across a set of endpoints, then it is indicated by the following:
<send> <load-balance algorithm="uri"> (endpointref | endpoint)+ </load-balance> </send>
Similarly, if the message is to be sent to an endpoint with failover semantics, then it is indicated by the following:
<send> <failover> (endpointref | endpoint)+ </failover> </send>
Once the <send> mediator executes, further processing of the current message stops.
Note: Synapse does not yet support the load balancing or failover semantics, and supports only a single endpoint reference.
The drop token refers to a <drop> element which is used to drop a message:
<drop/>
Once the <drop> mediator executes, further processing of the current message stops.
The log token refers to a <log> element which may be used to log messages being mediated:
<log [level="string"] [separator="string"]> <property name="string" (value="literal" | expression="xpath")/>* </log>
The optional level attribute selects a pre-defined subset of properties to be logged.
e.g.
A separator if defined will be used to seperate the attributes being logged. The default separator is the ',' comma.
<makefault [version="soap11|soap12"]> <code (value="literal" | expression="xpath")/> <reason (value="literal" | expression="xpath")> <node>? <role>? <detail>? </makefault>
The <makefault> mediator transforms the current message into a fault message, but does NOT send it. The <send> mediator needs to be invoked to send a fault message created this way. The fault message "to" header is set to the "faultTo" of the original message if such a header existed on the original message, else it is set it to the "replyTo" of the original message.
<xslt key="string" [source="xpath"]> <property name="string" (value="literal" | expression="xpath")/>* </transform>
The <xslt> mediator applies the specified XSLT transformation to the given element. If the source element is not specified, it defaults to the first child of the soap body. Optionally parameters (XSLT) could be passed into the transformations through the <property> elements.
<header name="qname" (value="literal" | expression="xpath") [action="set"]/> <header name="qname" action="remove"/>
The <header> mediator sets or removes a specified header from the current soap message. Currently the set header only supports simple valued headers. In the future we may extend this to have XML structured headers by embedding the XML content within the element itself. The optional action attribute specifies whether the mediator should set or remove the header. If omitted, it defaults to a set-header.
<filter (source="xpath" regex="string") | xpath="xpath"> mediator+ </filter>
The <filter> mediator either test the given xpath expression as a boolean expression, or match the evaluation result of a source xpath expression against the given regular expression. If the test succeeds, the filter mediator will execute the enclosed mediators in sequence.
<switch source="xpath"> <case regex="string"> mediator+ </case>+ <default> mediator+ </default>? </switch>
The <switch> mediator will evaluate the given source xpath expression into its string value, and match it against the given regular expressions. If the specified cases does not match and a default case exists, it will be executed.
<validate [source="xpath"]> <schema key="string"/>+ <on-fail> mediator+ </on-fail> </validate>
The <validate> mediator validates the result of the evaluation of the source xpath expression, against the schema specified. If the source attribute is not specified, the validation is performed against the first child of the SOAP body of the current message. If the validation fails, the on-fail sequence of mediators is executed.
Note: As the validation mediator is strongly dependent on the Xerces2-J 2.8.0 parser, it is bundled with the Synapse extensions, so that the Synapse core will remain simple and lightweight.
<set-property name="string" (value="literal" | expression="xpath") [scope=correlate|axis2]/>
The setproperty token refers to a <set-property> element which is a mediator that has no direct impact on the message but rather on the message context flowing through Synapse. The properties thus set on the message context applies only to the current message and can be later retrieved through the synapse:get-property(prop-name) extension function. If a scope is specified for a property, the property could be set as a correlation property or an (underlying) Axis2 message context property.
<try> <sequence> mediator+ </sequence> <onError> mediator+ </onError> <finally> mediator+ </finally> </try>
The try token refers to a <try> element which is a mediator that has a set of child mediators. If an exception is encountered during the execution of these child mediators, the list of mediators specified as the 'onError' sequence is executed. The 'finally' list of mediators is then executed irrespective of whether an exception was encountered or not.
<class name="class-name"> <property name="string" (value="literal" | expression="xpath")/>* </class>
The class mediator creates an instance of the specified class and sets it as a mediator. The class must implement the org.apache.synapse.api.Mediator interface. If any properties are specified, the corresponding setter methods are invoked on the class. However, Synapse will only support String properties.
<sequence ref="name"/>
A sequenceref token refers to a <sequence> element which is used to invoke a named sequence of mediators.
The Synapse configuration language could be easily extended, with configuration extensions as well as mediation extensions. The Spring mediator is such an example.
A Spring configuration could be created as a property or DynamicProperty providing a URL or a reference to a Registry. The configuration is then created on first use or as necessary (as per DynamicProperty semantics) by the mediators which reference this configuration.
<set-property name="string" key="string"/> <set-property name="string" src="url"/>
The name attribute specifies a unique name for the configuration, and the src, key or inlined XML references to the Spring configuration
<spring:spring bean="exampleBean1" key="string"/>
The <spring> element creates an instance of a mediator, which is managed by Spring. This Spring bean must implement the Mediator interface for it to act as a Mediator. The key will reference the Spring ApplicationContext/Configuration used for the bean
Synapse supports Mediators implemented in a variety of scripting languages such as JavaScript, Python or Ruby.
There are two ways of defining script mediators, either with the script program statements stored in a separate file which is referenced via a Synapse property, or with the script program statements embedded in-line within the Synapse configuration.
A script mediator using a registry property is defined as follows:
<script key="property-key" [function="script-function-name"]/>
The property-key is a Synapse registry property containing a URL to the script source. The function is an optional attribute defining the name of the script function to call, if not specified it defaults to a function named 'mediate'. The function is passed a single parameter which is the Synapse MessageContext. The function may return a boolean, if it does not then true is assumed. The language the script is written in is determined from the file name suffix of the property key value.
An inline script mediator has the script source embedded in the config XML:
<script.LL>...script source code...<script.LL/>
where LL is the script language name extension. For example, script.js indicates a JavaScript program, script.rb a Ruby program, or script.py a Python program. The environment of the script has the Synapse MessageContext predefined in a script variable named 'mc'.
An example of an inline mediator using JavaScript/E4X which returns false if the SOAP message body contains an element named 'symbol' which has a value of 'IBM' would be:
<script.js>mc.getPayloadXML()..symbol != "IBM";<script.js/>
The boolean response from the inlined mediator is either the response from the evaluation of the script statements or if that result is not a boolean then a response of true is assumed.
Synapse uses the Apache Bean Scripting Framework for the script language support, any script language supported by BSF may be used to implement a Synapse Mediator.
Implementing a Mediator with a script language can have advantages over using the built in Synapse Mediator types or implementing a custom Java class Mediator. Script Mediators have all the flexibility of a class Mediator with access to the Synapse MessageContext and SynapseEnvironment APIs, and the ease of use and dynamic nature of scripting languages allows rapid development and prototyping of custom mediators. An additional benefit of some scripting languages is that they have very simple and elegant XML manipulation capabilities, for example JavaScript E4X or Ruby REXML, so this makes them well suited for use in the Synapse mediation environment.
For both types of script mediator definition the MessageContext passed in to the script has additional methods over the standard Synapse MessageContext to enable working with the XML in a way natural to the scripting language. For example when using JavaScript get/setPayloadXML use E4X XML objects, when using Ruby they use REXML documents.