incubator-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Incubator Wiki] Update of "Synapse/InProgress/SynapseConfigurationLanguage" by Asankha Perera
Date Wed, 07 Jun 2006 06:03:56 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Incubator Wiki" for change notification.

The following page has been changed by Asankha Perera:
http://wiki.apache.org/incubator/Synapse/InProgress/SynapseConfigurationLanguage

New page:
= Synapse Configuration Language =

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. This design currently does not support the concept of "service mediation." It is
also currently direction agnostic, but directionality can easily be added as a selection mechanism
for mediators (see below for details). 

== Overall Structure ==

A Synapse configuration looks like the following at the top level:
{{{
  <synapse>
    <definitions>
      (sequencedef | endpointdef | literalpropertydef | extensiondef)+
    <definitions>?
    <rules>
      mediator+
    </rules>
  </synapse>
}}}

=== Definitions ===

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.

==== Sequences ====

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">
    mediator+
  </sequence>
}}}

==== Endpoints ====

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"]>
    .. extensibility ..
  </endpoint>
}}}

==== Extensions ====

An extensiondef token represents an extension element that extends the core Synapse configuration.
An extension provider must create an ExtensionFactory implementation that defines the type
of element that the factory handles. At runtime the configuration builder loads any extensions
through the Java service provider model, and then passes any unknown elements to the extension
factory finder which will return the registered factory, if any. Then the factory is requested
to process the extension element and create the extension, and this could be set as a 'property'
into the SynapseConfiguration object. The Spring configuration extension operates in this
manner and creates the Spring application contexts and sets it to the configuration as a property.

See 'Extensibility of Synapse' below for more details.

Note: The supported extensions are loaded through the J2SE Service Provider model. (http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider)

==== Properties ====

The token literalpropertydef refers to a <set-property> element as follows:
{{{
  <set-property name="string" value="string"/>
}}}
which is used to set a global property with a constant value.

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)".

=== Mediators ===

A mediator token refers to any of the following tokens:
{{{
send | drop | log | makefault | transform | header | filter | switch | class | validate |
setproperty | sequenceref | in | out 
}}}

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.

==== Send ====

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 message context properties named "correlate/*" 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. See example 1 for
more details.

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.

==== Drop ====

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.


==== Log ====

The log token refers to a <log> element which may be used to log messages being mediated:
{{{
  <log [level="string"] [seperator="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. simple  = To, From, WSAction, SOAPAction, ReplyTo, MessageID and any properties
		 headers = All SOAP header blocks and any properties
		 full		 = all attributes included in log level 'simple' and the SOAP envelope and any properties
		 custom  = Only properties specified to the Log mediator

A seperator if defined will be used to seperate the attributes being logged. The default seperator
is the ',' comma.


==== Transforms ====

===== Faults =====
{{{
  <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/XQuery =====
{{{
  <transform xslt|xquery="url" [source="xpath"]>
    <property name="string" (value="literal" | expression="xpath")/>*
  </transform>
}}}
The <transform> mediator applies the specified XSLT or XQuery transformation to the
given element. If the source element is not specified, it defaults to the soap body content.
Optionally parameters (XSLT) or variables (XQuery) could be passed into the transformations
through the <property> elements.

Note: Synapse does not currently support XQuery transformations

===== Headers =====
{{{
  <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.

==== Selection ====

===== Filters =====
{{{
  <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 =====
{{{
  <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.

==== Validation ====
{{{
  <validate schema="url" [source="xpath"]>
    <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 soap body content 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 Xerces 2.8.0 parser, it is bundled
with the Synapse extensions, so that the Synapse core will remain simple and lightweight.

==== Properties ====
{{{
  <set-property name="string" (value="literal" | expression="xpath")/>
}}}
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.

==== Class Mediators ====
{{{
  <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.

==== Reusing Sequences ====
{{{
  <sequence ref="name"/>
}}}
A sequenceref token refers to a <sequence> element which is used to invoke a named sequence
of mediators.

=== Extensibility of Synapse ===
The Synapse configuration language could be easily extended, with configuration extensions
as well as mediation extensions. The Spring mediator and Spring Configuration are such examples.

==== Spring Configuration ====
The <spring:config> element could be used to define a reusable Spring ApplicationContext
(BeanFactory). This could be referred subsequently by Spring mediator instances which will
use this context.
{{{
  <spring:config name="string" src="file"/>
}}}
The name attribute specifies a unique name for the configuration, and the src attribute specifies
the Spring configuration file.

Note: the <spring:config> element belongs to the http://ws.apache.org/ns/synapse/spring
namespace.

==== Spring mediator ====
{{{
   <spring bean="exampleBean1" (config="spring1" | src="spring.xml)"/>
}}}
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. If a config
attribute is specified, the bean will refer to the Spring configuration with the given name
as its bean factory. If a src attribute specifies the Spring configuration file, the required
application context is created inline and will be used by the mediator instance.

== Examples ==
The following illustrates the hypothetical example used to illustrate the new Synapse configuration
language syntax. However, features such as load balancing and failover etc are still not available
with Synapse.

The sample configuration presented below applies in the following hypothetical scenario. Assume
that two web service endpoints exists, where registration requests could be processed. Requests
may fall into Gold and Silver categories, and a specialized endpoint exists to process the
Gold requests. If the Gold endpoint cannot be reached for whatever reason, requests should
be processed via the Silver endpoint (i.e. failover).

Once message arrive at Synapse, the 'to' address is looked up and different mediation rules
applied depending on it. For registration messages, first we need to validate the incoming
message against a schema, and if the validation fails, a log entry should be made and a fault
reply should be sent back. For valid messages, we determine its category and attempt to use
the Gold endpoint, failing which the Silver endpoint is tried. For requests that does not
fall into the Gold category the default silver endpoint is used always.

{{{
  <synapse>
    <definitions>
      <sequence name="registration_flow">
        <validate schema="http://registry/xsd/registration.xsd" source="//regRequest">
          <on-fail>
            <set-property name="error-code" value="100"/>
            <set-property name="error-reason" value="validation failed"/>
            <sequence ref="fault_flow"/>
          </on-fail>
        </validate>          
        <filter xpath="/regRequest[@Category='GOLD']">
           <send>
             <failover>
               <endpoint ref="gold_registration"/>
               <endpoint ref="silver_registration"/>
             </failover>
           </send>
        <filter>  
        <send>
          <endpoint ref="silver_registration"/>
        </send>
      <sequence>
  
      <sequence name="fault_flow">
        <log level="simple">
          <property name="application" value="synapse:get-property('reg-app')"/>
        </log>
        <makefault version="soap11">
          <code value="synapse:get-property('error-code')"/>
          <reason expression="synapse:get-property('error-reason')">
        <makefault>
        <send/>
      <sequence>
  
      <endpoint name="gold_registration" address="http://gold/registration"/>
      <endpoint name="silver_registration" address="http://silver/registration"/>
  
      <set-property name="reg_app" value="Registration Application"/>    
    </definitions>
  
    <rules>
      <switch source="synapse:get-property('to')">
        <case regex="/registration">
          <sequence ref="registration_flow"/>
        </case>
        <case regex="someother">
          ...
        </case>
        <default>
          <drop/>
        </default>
    </rules>
  
  </synapse>  
}}}

Example 0.
{{{
<synapse xmlns="http://ws.apache.org/ns/synapse">
  
  <definitions>
    
    <sequence name="stockquote">
    	<!-- set the To address to the real endpoint -->
    	<header name="To" value="http://www.webservicex.net/stockquote.asmx"/>
    
    	<!-- check if the symbol is MSFT -->
      <filter xpath="//*[wsx:symbol='MSFT']" xmlns:wsx="http://www.webserviceX.NET/">
      	<!-- if it is throw a fault -->
      	<makefault>
      		<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
      		<reason value="Isn't there a Windows API for that?"/>
      	</makefault>
      </filter>
    </sequence>

  </definitions>

  <rules>
  	<!-- now log the message using log4j -->
  	<log level="full"/>
  	
  	<!-- Check if the URL matches the stockquote gateway/dumb case -->
  	<filter source="get-property('To')" regex=".*/StockQuote.*">
  		<sequence ref="stockquote"/>
  	</filter>
  	
  	<!-- check if the URL matches the virtual url - either the proxy or ws-add case -->
		<filter source="get-property('To')" regex="http://stockquote.*">
  		<sequence ref="stockquote"/>
  	</filter>
  	
  	<!-- send the message on -->
  	<send/>
  </rules>

</synapse> 
}}}
The above configuration is available with the Synapse distribution and illustrates the usual
Stock quote examples. The client code for these are available with the Synapse samples, and
the README.txt of the samples defines these in detail.

Example 1.
{{{
<synapse xmlns="http://ws.apache.org/ns/synapse">
  
  <definitions>

    <sequence name="customrequest">
    	<!-- set the To address to the real endpoint -->
    	<header name="To" value="http://ws.invesbot.com/stockquotes.asmx"/>
    	
    	<!-- set correlation field to custom label -->
    	<set-property name="correlate/label" value="customquote"/>
    	
    	<!-- transform the custom quote into a standard quote requst -->
    	<transform xslt="file:../synapse_repository/conf/sample/transform.xslt"/>
    	
    	<!-- send message to real endpoint and stop -->
    	<send/>
    	<drop/>
    </sequence>

		<sequence name="customresponse">
    	<!-- transform the custom quote into a standard quote requst -->
    	<transform xslt="file:../synapse_repository/conf/sample/transform_back.xslt"/>
    	
    	<!-- now send the custom response back to the client and stop -->
    	<send/>    	
    	<drop/>
    </sequence>
    
    <sequence name="stockquote">
    	<!-- set the To address to the real endpoint -->
    	<header name="To" value="http://ws.invesbot.com/stockquotes.asmx"/>
    
    	<!-- check if the symbol is MSFT -->
      <filter xpath="//*[wsx:symbol='MSFT']" xmlns:wsx="http://www.webserviceX.NET/">
      	<!-- if it is throw a fault -->
      	<makefault>
      		<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
      		<reason value="Isn't there a Windows API for that?"/>
      	</makefault>
      </filter>
      
      <send/>
    </sequence>
    
    <sequence name="standardrequest">
	  	<!-- now log the message using log4j -->
	  	<log level="full"/>
	  	
	  	<!-- Check if the URL matches the stockquote gateway/dumb case -->
	  	<filter source="get-property('To')" regex=".*/StockQuote.*">
	  		<sequence ref="stockquote"/>
	  	</filter>
	  	
	  	<!-- check if the URL matches the virtual url - either the proxy or ws-add case -->
			<filter source="get-property('To')" regex="http://stockquote.*">
	  		<sequence ref="stockquote"/>
	  	</filter>
	  		  	
	  	<!-- send the message on -->
	  	<send/>
    </sequence>

  </definitions>

  <rules>
  	<in>
	  	<!-- is this a custom stock quote message? -->
	  	<filter xpath="//m0:CheckPriceRequest" xmlns:m0="http://www.apache-synapse.org/test">
	  		<sequence ref="customrequest"/>
	  	</filter>
	  	
	  	<!-- else, proceed as usual with the standard processing rules -->
	  	<sequence ref="standardrequest"/>
		</in>
		
		<out>
  		<!-- is this a custom stock quote reply? -->
	  	<filter source="synapse:get-property('correlate/label')" regex="customquote">
	  		<sequence ref="customresponse"/>
	  	</filter>

			<!-- just let the message flow through -->
		  <send/>
		</out>		
  </rules>

</synapse> 
}}}
This example illustrates the correlation of incoming and outgoing messages and the use of
the <in> and <out> mediators that simplify the mediation configuration. This example
also shows how an XSLT transformation of a message may be performed on receipt or reply, and
also how a SOAP fault message may be created when required.

Example 2.
{{{
<synapse xmlns="http://ws.apache.org/ns/synapse">
  
  <definitions>
  
  	<!-- define global properties -->
  	<set-property name="version" value="0.1"/>
  
  	<!-- define a reuseable endpoint definition and use it within config -->
  	<endpoint name="invesbot" address="http://ws.invesbot.com/stockquotes.asmx"/>

    <sequence name="customrequest">
    	<!-- is this a valid custom request ? -->
    	<validate schema="file:../synapse_repository/conf/sample/validate.xsd">
		    <on-fail>
		    	<!-- if the request does not validate againt schema throw a fault -->
	      	<makefault>
	      		<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
	      		<reason value="Invalid custom quote request"/>
	      	</makefault>
	      	
	      	<!-- send the fault and stop processing -->
	      	<send/>
		      <drop/>
		    </on-fail>
		  </validate>

  		<switch source="//m0:CheckPriceRequest/m0:Code" xmlns:m0="http://www.apache-synapse.org/test">
		    <case regex="IBM">
		    	<set-property name="symbol" value="Great stock - IBM"/>
		    </case>
		    <case regex="MSFT">
		      <set-property name="symbol" value="Are you sure? - MSFT"/>
		    </case>
		    <default>
		      <set-property name="symbol" expression="fn:concat('Normal Stock - ', //m0:CheckPriceRequest/m0:Code)"
xmlns:m0="http://www.apache-synapse.org/test"/>
		    </default>
		  </switch>
		  
		  <!-- set a dynamic (local) message property -->
		  
    
    	<!-- set correlation field to custom label -->
    	<set-property name="correlate/label" value="customquote"/>
    	
    	<!-- transform the custom quote into a standard quote requst -->
    	<transform xslt="file:../synapse_repository/conf/sample/transform.xslt"/>
    	
    	<log level="custom">
    		<property name="Text" value="Sending quote request"/>
    		<property name="version" expression="synapse:get-property('version')"/>
    		<property name="symbol" expression="synapse:get-property('symbol')"/>
    	</log>
    	
    	<!-- send message to real endpoint referenced by name "invesbot" and stop -->
    	<send>
    		<endpoint ref="invesbot"/>
    	</send>
    	<drop/>
    </sequence>

		<sequence name="customresponse">
    	<!-- transform the custom quote into a standard quote requst -->
    	<transform xslt="file:../synapse_repository/conf/sample/transform_back.xslt"/>
    	
    	<!-- now send the custom response back to the client and stop -->
    	<send/>    	
    	<drop/>
    </sequence>
    
    <sequence name="stockquote">
    	<!-- set the To address to the real endpoint -->
    	<header name="To" value="http://ws.invesbot.com/stockquotes.asmx"/>
    
    	<!-- check if the symbol is MSFT -->
      <filter xpath="//*[wsx:symbol='MSFT']" xmlns:wsx="http://www.webserviceX.NET/">
      	<!-- if it is throw a fault -->
      	<makefault>
      		<code value="tns:Receiver" xmlns:tns="http://www.w3.org/2003/05/soap-envelope"/>
      		<reason value="Isn't there a Windows API for that?"/>
      	</makefault>
      </filter>
      
      <send/>
    </sequence>
    
    <sequence name="standardrequest">
	  	<!-- now log the message using log4j -->
	  	<log level="full"/>
	  	
	  	<!-- Check if the URL matches the stockquote gateway/dumb case -->
	  	<filter source="get-property('To')" regex=".*/StockQuote.*">
	  		<sequence ref="stockquote"/>
	  	</filter>
	  	
	  	<!-- check if the URL matches the virtual url - either the proxy or ws-add case -->
			<filter source="get-property('To')" regex="http://stockquote.*">
	  		<sequence ref="stockquote"/>
	  	</filter>
	  		  	
	  	<!-- send the message on -->
	  	<send/>
    </sequence>

  </definitions>

  <rules>
  	<in>
	  	<!-- is this a custom stock quote message? -->
	  	<filter xpath="//m0:CheckPriceRequest" xmlns:m0="http://www.apache-synapse.org/test">
	  		<sequence ref="customrequest"/>
	  	</filter>
	  	
	  	<!-- else, proceed as usual with the standard processing rules -->
	  	<sequence ref="standardrequest"/>
		</in>
		
		<out>
  		<!-- is this a custom stock quote reply? -->
	  	<filter source="synapse:get-property('correlate/label')" regex="customquote">
	  		<sequence ref="customresponse"/>
	  	</filter>

			<!-- just let the message flow through -->
		  <send/>
		</out>		
  </rules>

</synapse> 
}}}
This example adds onto the example 2 shown above and shows how the validate mediator could
be used to perform message validation. This also illustrates the use of custom properties
with the log mediator, global properties and message context properties and how they may be
queried via the synapse:get-property(name) XPath extension function. See the Synapse samples
for more information on this example and to try it out for real with the given test client.
You will need to place the Xerces 2.8.0 jars into your <JAVA_HOME>/lib/endorsed directory,
and the synapse-extensions.jar into the <SYNAPSE>/lib folder for this excersice as the
validation mediator extension is dependent on the Xerces parser.

Example 3.
{{{
<synapse xmlns="http://ws.apache.org/ns/synapse" xmlns:spring="http://ws.apache.org/ns/synapse/spring">
  
  <definitions>
		<spring:config name="springconfig" src="./../../repository/conf/sample/springsample.xml"/>
  </definitions>

  <rules>
  	<spring bean="springtest" config="springconfig"/>
  	<spring bean="springtest" src="./../../repository/conf/sample/springsample.xml"/>
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@incubator.apache.org
For additional commands, e-mail: cvs-help@incubator.apache.org


Mime
View raw message