This section of the guide covers aspects of SPI.
There are two types of Processors in Synapse:
These can contain sub-processors in its processor map. Ex: RegexProcessor, XpathProcessor etc.
This does not contain any sub-processors. Their soul purpose is to contain configuration infromation. Ex: AddressinInProcessor Core of Synapse contain Group and Referencing Processors, Rule Processors, Built-in Processors and User Mediator Type Processors.
Apart from the above, Synapse considers all other processors as extensions. Ex: SpringMediator etc. As mentioned in the Userguide every element in synapse.xml maps to a Processor. Every Processor has its ProcessorConfigurator. ProcessorConfigurator is the one which decides whether the corresponding Processor is a Node or Leaf Processor. So any Processor that has been written to Synapse should come as a extension and should go under the SVN folder "extensions".
Following XML shows the semantics of a Node Processor.
<foo attr="value"> <bar/> <car/> </foo>
<foo/> should map to FooProcessor which is a Node and there should be corresponding FooProcessorConfiguratator. So FooProcessor should contain a map to hold down the other Processors coming under it (BarProcessor and CarProcessor, these will be explained later on). To be a Node, FooProcessorConfigurator should extend from abstract AbstractListProcessorConfigurator. FooProcessorConfigurator contains all the configuration information of the Processor. It will hold the QName of element. All elements comes under the namespace of http://ws.apache.org/ns/synapse. If there are other attributes pertaining to the elements they should also come under the prior namespace and it should be defined in the ProcesssorConfigurator. Ultimately you will have following code.
Now you have to implement the following methods,
public Processor createProcessor(SynapseEnvironment se, OMElement el);public QName getTagQName();
public Processor createProcessor(SynapseEnvironment se, OMElement el),
This will deal with the FooProcessor creation. The following is a specific way to write this method
Now lets look at the FooProcessor implementation. Remember it's a Node, and it should contain a place to hold the value of "attr". As this is a Node, it should extend from ListProcessor.
public boolean process(SynapseEnvironment se, SynapseMessage smc)
handle the processing logic. So there be any condition, and if the logic is "true" call "super.process(se, smc)" . If the processing logic is fault through make sure that you will call "return true". So writing a extension is as easy as prior.
<bar/> is leaf element and it will map to a Leaf Node. So let the mapping be BarProcessor and there should be the corresponding BarProcessorConfigurator. So the symantics of BarProcessorConfigurator is as follows,
If there are attributes, let them be handle as shown in "Writing a Node Processor" . Leaf ProcessorConfigurators should extend from AbstractProcessorConfigurator. Now lets see the semantics of BarProcessor.
Leaf Processors should extend from AbstractProcessor. So "Let there be Processors". But we are not quite there. We need to do one more configuration, Plunging the extension to the core.
First Method:
This is based on Service Provider funtionality that comes with JDK1.3 above. For more information click here
JAR structure is as follows
META-INF +-services +-a.b.c.d.ProcessorConfigurator {this is a text file, which has a QName entry a.b.c.d.BarProcessorConfigurator } a +-b +-c +-d +-BarProcessorConfigurator
Second Method
Go to the class
org.apache.synapse.xml.ProcessorConfiguratorFinder
there one will find the following static variable.
private static Class[] processorConfigurators = {...}
You have to fill it with your extensions as follows,
private static Class[] processorConfigurators = {..., FooProcessorConfigurator.class,BarProcessorConfigurator.class}
Now you have successfully plugged your processor into Synapse. Finally "Let there be Processors".