Sample 650: File hierarchy based configuration builder

 

      synapse_sample_650.xml
         |-- endpoints
         |   `-- foo.xml
         |-- events
         |   `-- event1.xml
         |-- local-entries
         |   `-- bar.xml
         |-- proxy-services
         |   |-- proxy1.xml
         |   |-- proxy2.xml
         |   `-- proxy3.xml
         |-- registry.xml
         |-- sequences
         |   |-- custom-logger.xml
         |   |-- fault.xml
         |   `-- main.xml
         |-- synapse.xml
         `-- tasks
             `-- task1.xml

    

Objective: Demonstrate the ability to construct the Synapse configuration from a file hierarchy

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000.

Start ESB with the sample configuration 650 (i.e. wso2esb-samples.sh -sn 650).

Go to the repository/samples directory and locate the subdirectory named synapse_sample_650.xml within it. When ESB is started with the sample configuration 650, ESB will load the configuration from this directory. You will find a number of subdirectories and a set of XML files in each of those directories. Synapse will parse all the XML files in this file hierarchy and construct the full Synapse configuration at startup. As a result when this sample is executed Synapse will start with four proxy services, several sequences, a task, an event source and some endpoint and local entry definitions.

The names of the subdirectories (eg: proxy-services, sequences, endpoints) are fixed and hence cannot be changed. Also the registry definition should go into a file named registry.xml which resides at the top level of the file hierarchy. It can also be specified in the synapse.xml file at top level. This synapse.xml file can include any item that can be normally defined in a synapse.xml file. The files which define proxy services, sequences, endpoints etc can have any name. These configuration files must have the .xml extension at the end of the name. Synapse will ignore any files which do not have the .xml extension.

None of the directories and files in the sample file hierachy are mandatory. You can leave entire directories out if you do not need them. For example if your configuration does not contain any proxy services you can leave the subdirectory named proxy-services out.

To use this feature you should simply pass a path to an existing directory when starting the Synapse server. The SynapseServer class which is responsible for starting the server accepts a file path as an argument from where to load the configuration. Generally we pass the path to the synapse.xml file as the value of this argument. If you pass a directory path instead, Synapse configuration will be loaded from the specified directory. Note the following line on the console when Synapse is loading the configuration from a file hierarchy.

2009-08-04 14:14:42,489 [-] [main]  INFO SynapseConfigurationBuilder Loaded Synapse configuration from the directory hierarchy at : /home/synapse/repository/conf/sample/synapse_sample_650.xml

This feature comes in handy when managing large Synapse configurations. It is easier to maintain a well structured file hierarchy than managing one large flat XML file.

Sample 651: Using Synapse observers

Objective: Demonstrate the ability to monitor the Synapse configuration at runtime using the SynapseObserver interface

Open the synapse.properties file in the ESB_HOME/webapps/ROOT/WEB-INF/classes directory using a text editor and add the following line to the synapse.properties file. This entry defines the simple logging Synapse observer.

synapse.observers=samples.userguide.SimpleLoggingObserver

Open the log4j.properties file in the ESB_HOME/lib directory and add the followin line which sets the INFO log level to the samples.userguide package.

log4j.category.samples.userguide=INFO

Start Synapse using any of the sample configurations. The SimpleLoggingObserver will capture events that occur while constructing the Synapse configuration and log them on the console as follows.

  2009-08-06 14:30:24,578 [-] [main]  INFO SimpleLoggingObserver Simple logging observer initialized...Capturing Synapse events...
  2009-08-06 14:30:24,604 [-] [main]  INFO SimpleLoggingObserver Endpoint : a3 was added to the Synapse configuration successfully
  2009-08-06 14:30:24,605 [-] [main]  INFO SimpleLoggingObserver Endpoint : a2 was added to the Synapse configuration successfully
  2009-08-06 14:30:24,606 [-] [main]  INFO SimpleLoggingObserver Endpoint : null was added to the Synapse configuration successfully
  2009-08-06 14:30:24,611 [-] [main]  INFO SimpleLoggingObserver Local entry : a1 was added to the Synapse configuration successfully
  2009-08-06 14:30:24,649 [-] [main]  INFO SimpleLoggingObserver Proxy service : StockQuoteProxy2 was added to the Synapse configuration successfully
  2009-08-06 14:30:24,661 [-] [main]  INFO SimpleLoggingObserver Proxy service : StockQuoteProxy1 was added to the Synapse configuration successfully
  2009-08-06 14:30:24,664 [-] [main]  INFO SimpleLoggingObserver Sequence : main was added to the Synapse configuration successfully
  2009-08-06 14:30:24,701 [-] [main]  INFO SimpleLoggingObserver Sequence : fault was added to the Synapse configuration successfully

The SimpleLoggingObserver is implemented as follows. It does not override any of the event handler implementations in the AbstractSynapseObserver class. The AbstractSynapseObserver logs all the received events by default.

 package samples.userguide;

 import org.apache.synapse.config.AbstractSynapseObserver;

 public class SimpleLoggingObserver extends AbstractSynapseObserver {

     public SimpleLoggingObserver() {
         super();
         log.info("Simple logging observer initialized...Capturing Synapse events...");
     }
 }

Sample 652: Priority Based Message Mediation

 

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <priority-executor name="exec">
        <queues>
            <queue size="100" priority="1"/>
            <queue size="100" priority="10"/>
        </queues>
    </priority-executor>
    <proxy name="StockQuoteProxy">
        <target>
            <inSequence>
                <filter source="$trp:priority" regex="1">
                    <then>
                        <enqueue priority="1" sequence="priority_sequence" executor="exec"/>
                    </then>
                    <else>
                        <enqueue priority="10" sequence="priority_sequence" executor="exec"/>
                    </else>
                </filter>
            </inSequence>
            <outSequence>
                <send/>
            </outSequence>
        </target>
        <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
    </proxy>
    <sequence name="priority_sequence">
        <log level="full"/>
        <send>
            <endpoint>
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>
        </send>
    </sequence>
</definitions>

Objective: Demonstrate the priority based mediation capability of ESB.

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000. Priority is applied only when ESB is loaded with enough messages to consume its core number of threads. So to observe the priority based mediation, it is required to use a load testing tool like JMeter, SOAP UI or Apache bench.

Start ESB with the sample configuration 652 (i.e. wso2esb-samples.sh -sn 652).

In this sample, client should send a HTTP header that specifies the priority of the message.This header name is priority. This header is retrieved in the ESB configuration using the $trp:priority XPath expression. Then it is matched against the value 1. If it has the value 1, message is executed with priority 1. Otherwise the message is executed with priority 10.

Here are two sample XML files that can be used to invoke the service using a tool like JMeter, or Ab. For SOAP UI, user can use the WSDL repository/samples/resources/proxy/sample_proxy_1.wsdl to create the request. The only difference between the two demonstrated requests here is the symbol. One has the symbol as IBM and other has MSFT. For one type of request set the priority header to 1 and for the next set the priority header to 10. Then load ESB with high volume of traffic from both types of requests using the load testing tool. In the back end server it prints the symbol of the incoming requests. User should be able to see more of high priority symbol.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:To>http://localhost:8281/services/SimpleStockQuoteService</wsa:To>
        <wsa:MessageID>urn:uuid:1B57D0B0BF770678DE1261165228620</wsa:MessageID>
        <wsa:Action>urn:getQuote</wsa:Action>
     </soapenv:Header>
     <soapenv:Body>
        <m0:getQuote xmlns:m0="http://services.samples">
           <m0:request>
              <m0:symbol>IBM</m0:symbol>
           </m0:request>
        </m0:getQuote>
     </soapenv:Body>
</soapenv:Envelope>
           
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:To>http://localhost:8281/services/SimpleStockQuoteService</wsa:To>
        <wsa:MessageID>urn:uuid:1B57D0B0BF770678DE1261165228620</wsa:MessageID>
        <wsa:Action>urn:getQuote</wsa:Action>
     </soapenv:Header>
     <soapenv:Body>
        <m0:getQuote xmlns:m0="http://services.samples">
           <m0:request>
              <m0:symbol>MSFT</m0:symbol>
           </m0:request>
        </m0:getQuote>
     </soapenv:Body>
</soapenv:Envelope>
           

Sample 653: NHTTP Transport Priority Based Dispatching

 

Here is the priority configuration file used by the NHTTP transport to determine the priority based on HTTP level properties.

<priorityConfiguration>
    <priority-executor>
        <!-- two priorities specified with priority 10 and 1. Both priority messages has a queue depth of 100 -->
        <queues isFixedCapacity="true" nextQueue="org.apache.synapse.commons.executors.PRRNextQueueAlgorithm">
            <queue size="100" priority="10"/>
            <queue size="100" priority="1"/>
        </queues>
        <!-- these are the default values, values are put here to show their availability -->
        <threads core="20" max="100" keep-alive="5"/>
    </priority-executor>

    <!-- if a message comes that we cannot determine priority, we set a default priority of 1 -->
    <conditions defaultPriority="1">
        <condition priority="10">
            <!-- check for the header named priority -->
            <equal type="header" source="priority" value="5"/>
        </condition>
        <condition priority="1">
            <equal type="header" source="priority" value="1"/>
        </condition>
    </conditions>
</priorityConfiguration>

Objective: Demonstrate the priority based dispatching of NHTTP transport.

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000. Priority is applied only when ESB is loaded with enough messages to consume its core number of threads. So to observe the priority based dispatching, it is required to use a load testing tool like JMeter, SOAP UI or Apache bench.

Open axis2.xml in repository/conf directory and uncomment the following parameter to the configuration. priorityConfigFile. Set the value to repository/samples/resources/priority/priority-configuration.xml

We'll use the sample number 150. Start ESB with the sample configuration 150 (i.e. wso2esb-samples.sh -sn 150).

In this sample, client should send a HTTP header that specifies the priority of the message.This header name is priority. This header is retrieved in the prioirty configuration. Then it is matched against the value 1 and 10. Depending on this value message is executed with priority 1 or 10.

Here are two sample XML files that can be used to invoke the service using a tool like JMeter, or Apache Ab. For SOAP UI, user can use the WSDL repository/conf/sample/resources/proxy/sample_proxy_1.wsdl to create the request. The only difference between the two demonstrated requests here is the symbol. One has the symbol as IBM and other has MSFT. For one type of request set the priority header to 1 and for the next set the priority header to 10. Then load ESB with high volume of traffic from both types of requests using the load testing tool. In the back end server it prints the symbol of the incoming requests. User should be able to see more of high priority symbol.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:To>http://localhost:8281/services/SimpleStockQuoteService</wsa:To>
        <wsa:MessageID>urn:uuid:1B57D0B0BF770678DE1261165228620</wsa:MessageID>
        <wsa:Action>urn:getQuote</wsa:Action>
     </soapenv:Header>
     <soapenv:Body>
        <m0:getQuote xmlns:m0="http://services.samples">
           <m0:request>
              <m0:symbol>IBM</m0:symbol>
           </m0:request>
        </m0:getQuote>
     </soapenv:Body>
</soapenv:Envelope>
           
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
        <wsa:To>http://localhost:8281/services/SimpleStockQuoteService</wsa:To>
        <wsa:MessageID>urn:uuid:1B57D0B0BF770678DE1261165228620</wsa:MessageID>
        <wsa:Action>urn:getQuote</wsa:Action>
     </soapenv:Header>
     <soapenv:Body>
        <m0:getQuote xmlns:m0="http://services.samples">
           <m0:request>
              <m0:symbol>MSFT</m0:symbol>
           </m0:request>
        </m0:getQuote>
     </soapenv:Body>
</soapenv:Envelope>
           

Sample 654: Smooks Mediator

 

Here is the sample with smooks mediator.

<definitions xmlns="http://ws.apache.org/ns/synapse">
    <localEntry key="transform-xslt-key"
                src="file:repository/samples/resources/smooks/transform.xslt"/>
    <localEntry key="smooks-key" src="file:repository/samples/resources/smooks/smooks-config.xml"/>
    <proxy name="StockQuoteProxy" transports="vfs">
        <parameter name="transport.vfs.ContentType">text/plain</parameter>
        <!--CHANGE-->
        <parameter name="transport.vfs.ContentType">text/plain</parameter>
       <parameter name="transport.vfs.FileURI">file:///home/user/dev/test/smooks/in</parameter>
       <parameter name="transport.vfs.FileNamePattern">.*\.txt</parameter>
        <parameter name="transport.PollInterval">5</parameter>
        <!--CHANGE-->
        <parameter name="transport.vfs.MoveAfterProcess">file:///home/user/dev/test/smooks/original</parameter>
        <!--CHANGE-->
        <parameter name="transport.vfs.MoveAfterFailure">file:///home/user/dev/test/smooks/original</parameter>
        <parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
        <parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
        <parameter name="Operation">urn:placeOrder</parameter>
        <target>
            <inSequence>
                <smooks config-key="smooks-key"/>
                <xslt key="transform-xslt-key"/>
                <iterate expression="//m0:placeOrder/m0:order" preservePayload="true"
                         attachPath="//m0:placeOrder" xmlns:m0="http://services.samples">
                    <target>
                        <sequence>
                            <header name="Action" value="urn:placeOrder"/>
                            <property action="set" name="OUT_ONLY" value="true"/>
                            <send>
                                <endpoint>
                                    <address format="soap11"
                                            uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                                </endpoint>
                            </send>
                        </sequence>
                    </target>
                </iterate>
            </inSequence>
            <outSequence/>
        </target>
        <publishWSDL uri="file:repository/samples/resources/smooks/PlaceStockOrder.wsdl"/>
    </proxy>
</definitions>

Objective:Demonstrate the smooks mediatot EDI message processing.

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000. Then add the plain text builder to the messageBuilders section of the axis2.xml found in the repository/conf directory. Here is the sample configuration.

<messageBuilder contentType="text/plain" class="org.apache.axis2.format.PlainTextBuilder"/>

Enable the vfs transport in axis2.xml by uncomenting the vfs transport sender and receiver configurations in the axis2.xml.

User has to edit the synapse_sample_654.xml found in the repository/samples directory. These are the configuration parameters that needs to be edited.

  • transport.vfs.FileURI
  • transport.vfs.MoveAfterProcess
  • transport.vfs.ActionAfterFailure

Start ESB with the sample configuration 654 (i.e. wso2esb-samples.sh -sn 654).

Drop the edi.txt file found in the repository/samples/resources/smooks directory to the transport.vfs.FileURI parameter specified directory.

Sample 655: Message Relay - Basics

 

This sample is similar to sample 150 except we have added two log mediators to show the actual message going through the ESB.

<?xml version="1.0"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
    <proxy name="StockQuoteProxy" startOnLoad="true">
        <target>
            <inSequence>
                <log level="full"/>
                <send>
                    <endpoint name="epr">
                        <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                    </endpoint>
                </send>
            </inSequence>
            <outSequence>
                <log level="full"/>
                <send/>
            </outSequence>
        </target>
        <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
    </proxy>
    <sequence name="fault">
        <log level="full">
            <property name="MESSAGE" value="Executing default &quot;fault&quot; sequence"/>
            <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
            <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
        </log>
        <drop/>
    </sequence>
    <sequence name="main">
        <log/>
        <drop/>
    </sequence>
</definitions>

Objective:Demonstrate the Message Relay.

Prerequisites: Deploy the SimpleStockQuoteService in sample Axis2 server and start it on port 9000. Then uncomment the Message Relay's Message Builder and Message Formatter in the axis2.xml. These configurations can be found in the messageFormatters and messageBuilders section of the axis2.xml. A message formatter or builder is defined for a content type. So make sure you comment out the normla builders and formatters for a content type when uncomenting the message relay builders and formatters.

Here are the Message Relay Formatter and Builder classes. You need to uncomment the entries containing the following builder and formatter.

org.wso2.carbon.relay.ExpandingMessageFormatter
org.wso2.carbon.relay.BinaryRelayBuilder

Send a message to the sample using the sample axis2 client.

ant stockquote -Daddurl=http://localhost:8280/services/StockQuoteProxy

You can see the messages going through the proxy by looking at the console because we have two log mediators in this sample. The actual message is not built and printed as a Base64 encoded string.

Sample 656: Message Relay - Builder Mediator

 

This sample is similar to sample 655. We have added the builder mediator to build the actual message before logging it.

<?xml version="1.0"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
  <proxy name="StockQuoteProxy" startOnLoad="true">
    <target>
      <inSequence>
        <builder/>
        <log level="full"/>
        <send>
          <endpoint name="epr">
            <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
          </endpoint>
        </send>
      </inSequence>
      <outSequence>
        <builder/>
        <log level="full"/>
        <send/>
      </outSequence>
    </target>
    <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
  </proxy>
  <sequence name="fault">
    <log level="full">
      <property name="MESSAGE" value="Executing default &quot;fault&quot; sequence"/>
      <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
      <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
    </log>
    <drop/>
  </sequence>
  <sequence name="main">
    <log/>
    <drop/>
  </sequence>
</definitions>

Objective:Demonstrate the Message Relay with Builder mediator.

Prerequisites:Set up is same as sample 655.

ant stockquote -Daddurl=http://localhost:8280/services/StockQuoteProxy

You can see the actual messages going through the proxy by looking at the console because we have two log mediators in this sample. Becuase we have the builder mediator in place, unlike in sample 655 we have the actual message printed.

Sample 657: Distributed transaction management

 

This sample is similar to sample 655. We have added the builder mediator to build the actual message before logging it.

<definitions xmlns="http://ws.apache.org/ns/synapse"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://ws.apache.org/ns/synapse http://synapse.apache.org/ns/2010/04/configuration/synapse_config.xsd">

    <sequence name="myFaultHandler">
        <log level="custom">
            <property name="text" value="** Rollback Transaction**"/>
        </log>
        <transaction action="rollback"/>
        <send/>
    </sequence>

    <sequence name="main" onError="myFaultHandler">
        <in>
            <send>
                <endpoint>
                    <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                </endpoint>
            </send>
        </in>

        <out>
            <transaction action="new"/>

            <log level="custom">
                <property name="text" value="** Reporting to the Database esbdb**"/>
            </log>
            <dbreport useTransaction="true" xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <dsName>java:jdbc/XADerbyDS</dsName>
                        <icClass>org.jnp.interfaces.NamingContextFactory</icClass>
                        <url>localhost:1099</url>
                        <user>synapse</user>
                        <password>synapse</password>
                    </pool>
                </connection>
                <statement>
                    <sql>delete from company where name =?</sql>
                    <parameter expression="//m0:return/m1:symbol/child::text()"
                               xmlns:m0="http://services.samples"
                               xmlns:m1="http://services.samples/xsd"
                               type="VARCHAR"/>
                </statement>
            </dbreport>

            <log level="custom">
                <property name="text" value="** Reporting to the Database esbdb1**"/>
            </log>
            <dbreport useTransaction="true" xmlns="http://ws.apache.org/ns/synapse">
                <connection>
                    <pool>
                        <dsName>java:jdbc/XADerbyDS1</dsName>
                        <icClass>org.jnp.interfaces.NamingContextFactory</icClass>
                        <url>localhost:1099</url>
                        <user>synapse</user>
                        <password>synapse</password>
                    </pool>
                </connection>
                <statement>
                    <sql>INSERT into company values ('IBM','c4',12.0)</sql>
                </statement>
            </dbreport>
            <transaction action="commit"/>
            <send/>
        </out>
    </sequence>

</definitions>

Objective:Demonstrate the use of the transaction mediator in a distributed transaction

Prerequisites:
Start the Synapse configuration numbered 267: i.e. wso2esb-samples -sn 267
Start the Axis2 server and deploy the SimpleStockQuoteService if not already done

To run this sample it is required to deploy synpase on JBoss application server(This is only tested with JBoss application sever), you can use the war distribution to deploy synapse on JBoss application server. Use the synpase_sample_652.xml as the synapse confiuration file and start JBoss with that synpase configuration file. Also you need to define two XA datasources for above two datasources. You'll need to refer JBoss documentation to see how to do this.
It also required to have two database instances, this will be used by the two XA datasources. Refer the Sample Setup Guide to see how you can set up the derby database server.
In this sample a record is delete from one database and it is added into the second database. If either of the operations(deleting from the 1st database and adding into the second database) fails everything will be roll backed. The records will be untouched.

Invoke the client as follows.

ant stockquote -Daddurl=http://localhost:9000/services/SimpleStockQuoteService -Dtrpurl=http://localhost:8280/ -Dsymbol=SUN/