Wednesday, September 14, 2016

How to enable Linux Audit Daemon in hosts where WSO2 carbon run times are deployed

Please find the post from: https://medium.com/@DilshaniSubasinghe/how-to-enable-linux-audit-daemon-in-hosts-where-wso2-carbon-runtimes-are-deployed-424f06358e0e#.bz02qivf0

Tuesday, July 26, 2016

[WSO2][ESB] Set Timeout value of transport sender

Hi all,

In this blog post, indicating about set the timeout value of transport sender. By default, it has a timeout period of 30000ms (30s).

Go to <ESB-Home>/repository/conf/axis2/axis2_blocking_client.xml and set the values as follows.

 <transportSender name="https">  
 ...  
 ...  
  <parameter name="SO_TIMEOUT">90000</parameter>  
  <parameter name="CONNECTION_TIMEOUT">90000</parameter>  
  ...  
  ...  
 </transportSender>   



Note: These values are not available in axis2_blocking_client.xml by default and you have to add them.



PS: This will be a possible solution for  "java.net.SocketTimeoutException: Read timed out" exception. 


 java.net.SocketTimeoutException: Read timed out  
 at java.net.SocketInputStream.socketRead0(Native Method)  
 at java.net.SocketInputStream.read(SocketInputStream.java:129)  
 at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)  
 at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)  





Sunday, June 26, 2016

[IBM MQ] Create a topic using IBM MQ

Hi all,

I am configuring integration scenario of IBM MQ with WSO2 ESB. In particular scenario, used IBM MQ 8.0.0.2 and ESB 5.0.0 in the windows environment (Oracle JDK 1.8).

If you need to understand the installation mechanism from the first step, you can follow this blog post. 

Assumption: You have configured ESB with IBM MQ for Queues.

Let's begin creating a topic in IBM MQ.

1. Open IBM MQ UI (Websphere Installation1 window) through administrative mode.

How to do that ?
  • Go to window start button and search for Websphere
  • Right click on icon and  click on "Run as Administrator"
2. Create a Topic under Queue Manger





3. Add Destination




Note: Give the "Topic string" (Which was defined when creating the Topic) as the Topic in next window. (Refer next screen shot)


4. Create Topic Connection Factory if you don't specify previous connection factories as Topic Connection Factory/ Connection Factory (General term for both topics and queues)






You are done with Topic Configuration. When you are going to subscribe to Topic from external clients (Ex: ESB) you can see those subscriptions through "Subscription panel"



Happy Coding ... :)

Saturday, June 25, 2016

[WSO2][ESB Cluster] HornetQ host configuration when connecting to a cluster

When we are going to use HornetQ with  cluster environment (Ex: ESB Cluster), have to configure HorentQ hosts. If not HornetQ will not identify exact configuration.

In HornetQ run.sh script ($HorenetQ_Home/bin/) update as follows:

# Use the following line to run with different ports
#export CLUSTER_PROPS="-Djnp.port=1099 -Djnp.rmiPort=1098 -Djnp.host=localhost -Dhornetq.remoting.netty.host=localhost -Dhornetq.remoting.netty.port=5445"

Uncomment above line and update relevant parameters.

# Use the following line to run with different ports
export CLUSTER_PROPS="-Djnp.port=1099 -Djnp.rmiPort=1098 -Djnp.host=10.100.7.120 -Dhornetq.remoting.netty.host=localhost -Dhornetq.remoting.netty.port=5445"

** Update -Djnp.port and -Djnp.host with relevant values. -Djnp.host should be the IP/host_name of an instance which HornetQ installed.


[SFTP] Connecting to remote server for file sharing

You can use to connect remote server and easily share files between local and remote server using SFTP.

You can use SFTP with your "key" which is using to access the remote server OR just access without credentials if you don't have any

Using SFTP server:

sftp -i <key file> username@remote_hostname/ip   OR
sftp username@remote_hostname/ip

Ex:

 sftp -i dilshani.pem centos@192.***.**.71  

When you connected through SFTP server it can see the sftp server as follows:


 sftp>  

You can get files or send files secure manner.

Send files:

put <file_name> <remote_location>

 sftp> put test.text /home/centos/files  

** Note: If you are using above command, file should be located in same folder, which is going to start sftp server. Otherwise it can be give the path of file befor file name.

Get files:

get <remote_location/file_name> <local_location>

 sftp> get /home/centos/files/test.text  

** Note: you can navigate to any folder using cd command

cd <file_directory>

 sftp> cd /home/centos/files  

When you are done with file sharing, close the server with "exit" command.

 sftp> exit  


Happy Sharing :)



ActiveMQ Tips

How to change the default port of Active MQ ?

1. Go to activemq.xml ($ActiveMQ_Home/conf/)

2. Edit openwire port

<transportConnectors>
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

By default, 61616 is port of Active MQ. You can give whatever the port you want.


Login to Active MQ dashboard 

In Active MQ, there is a web dashboard which will display every detail of topics/queues created within active mq broker. You can access to that using following url (using any browser)
  • http://<ip>: 8161
          Ex: http://localhost:8161/


Default username and password for Active MQ
  • When accessing active MQ you may not need any password unless you add it through the installation process.
  • When you login to web console (even though you did not add any password/ username), you will have to provide username and password. 
  • Use username: admin and password: admin

General JMS parameter values for Active MQ
  • java.naming.factory.initial : org.apache.activemq.jndi.ActiveMQInitialContextFactory
  • java.naming.provider.url : tcp://localhost:61616  (Note: if you are calling remote active mq broker, you should add relevant ip/host name instead of "localhost")

 Integration with WS02 ESB

  •  If you are going to configure Active MQ with WSO2 ESB, you can refer WSO2 documentations.
  • But you have to remember about the version of client jars you are going to put into ESB. Even though you are using active MQ which has higher version than 5.8, you have to put Active MQ 5.8 client jars
Client Libraries:
  • activemq-broker-5.8.0.jar
  • activemq-client-5.8.0.jar
  • geronimo-jms_1.1_spec-1.1.1.jar
  • geronimo-j2ee-management_1.1_spec-1.0.1.jar

Welcome all value additions regarding Active MQ :) 



[IBM MQ] How to make a remote connection through WSO2 ESB


Hi all,

This blog post about creating a remote connection to the IBM MQ which is located in a remote server. To do that, you have to have IBM MQ installed in remote server. For IBM MQ installation you can refer this blog post.

Let's remotely connect to IBM MQ ...

Environment : IBM MQ Version 8.0.0.2 installed in Windows 2012 R2 server
                        Client is WSO2 ESB 5.0.0 installed in ubuntu 15.10

Steps to connect:
  • First, you have to take .bindings file you used (Which is in jndiDirectory)
  • Add .bindings file in to a local file directory (Ex: /home/dilshani/Dev/jndiDirectory)
  • Edit .bindings file 
** Open .bindings file using text editor and replace all places having "localhost" with relevant IP of the server which is installed IBM MQ.
  • Add client jars into [ESB_HOME]/repository/components/lib folder   
* com.ibm.mq.allclient 
* fscontext
* jms
* providerutil

** You can find these jars inside the java folder in IBM MQ installation file directory (Ex: C:/)
  •  Remove following line from $ESB_HOME/repository/conf/etc/launch.ini. 
                            javax.jms,\
  • Add WSO2 ESB axis2.xml configs related to JMS transport (You may find axis2.xml file in [ESB_HOME]/repository/conf/axis2/)
Sample Configs:

 <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">  
   <parameter name="default" locked="false">  
   <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>  
   <parameter name="java.naming.provider.url" locked="false">file:///home/centos/esb/jndiDirectory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">myTopicConnectionFactory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>  
   <parameter name="transport.jms.Destination" locked="false">testTopic</parameter>  
   <parameter name="transport.jms.DestinationType" locked="false">topic</parameter>  
   <parameter name="transport.jms.UserName" locked="false">administrator</parameter>  
   <parameter name="transport.jms.Password" locked="false">wso2321#qa</parameter>  
  </parameter>  
  <parameter name="myQueueConnectionFactory1" locked="false">  
   <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>  
   <parameter name="java.naming.provider.url" locked="false">file:///home/centos/esb/jndiDirectory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">myQueueConnectionFactory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>  
   <parameter name="transport.jms.UserName" locked="false">administrator</parameter>  
   <parameter name="transport.jms.Password" locked="false">wso2321#qa</parameter>  
   <parameter name="transport.jms.Destination">LocalQueue1</parameter>  
  </parameter>  
  <parameter name="myTopicConnectionFactory1" locked="false">  
    <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>  
   <parameter name="java.naming.provider.url" locked="false">file:///home/centos/esb/jndiDirectory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">myTopicConnectionFactory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>  
   <parameter name="transport.jms.DestinationType" locked="false">topic</parameter>  
   <parameter name="transport.jms.UserName" locked="false">administrator</parameter>  
   <parameter name="transport.jms.Destination">testTopic</parameter>  
   <parameter name="transport.jms.Password" locked="false">wso2321#qa</parameter>  
  </parameter>  
 </transportReceiver>  

And also you have to add transport sender configurations too.

 <transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender">  
   <parameter name="default" locked="false">  
   <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>  
   <parameter name="java.naming.provider.url" locked="false">file:///home/centos/esb/jndiDirectory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">myTopicConnectionFactory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>  
   <parameter name="transport.jms.Destination" locked="false">testTopic</parameter>  
   <parameter name="transport.jms.DestinationType" locked="false">topic</parameter>  
   <parameter name="transport.jms.UserName" locked="false">administrator</parameter>  
   <parameter name="transport.jms.Password" locked="false">wso2321#qa</parameter>  
  </parameter>  
  <parameter name="myQueueConnectionFactory1" locked="false">  
   <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>  
   <parameter name="java.naming.provider.url" locked="false">file:///home/centos/esb/jndiDirectory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">myQueueConnectionFactory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>  
   <parameter name="transport.jms.UserName" locked="false">administrator</parameter>  
   <parameter name="transport.jms.Password" locked="false">wso2321#qa</parameter>  
   <parameter name="transport.jms.Destination">LocalQueue1</parameter>  
  </parameter>  
  <parameter name="myTopicConnectionFactory1" locked="false">  
   <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>  
   <parameter name="java.naming.provider.url" locked="false">file:///home/centos/esb/jndiDirectory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">myTopicConnectionFactory</parameter>  
   <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>  
   <parameter name="transport.jms.DestinationType" locked="false">topic</parameter>  
   <parameter name="transport.jms.UserName" locked="false">administrator</parameter>  
   <parameter name="transport.jms.Destination">testTopic</parameter>  
   <parameter name="transport.jms.Password" locked="false">wso2321#qa</parameter>  
  </parameter>  
 </transportSender>  
  • Start ESB server and it will create JMS connection.

** Note: If you get any error, please take following steps to solve the issue.
  •  Ping the server and see whether it can be reach
Ex:
       ping <serever ip>
  • Telenet the port and see whether it open to connect
Ex:
       telnet <server-ip> <port>
  • Restart the IBM MQ 
** Check whether "channel" is inactive and .bindings file connected. (You can do it via IBM MQ UI)

Thursday, June 9, 2016

[WSO2][ESB][JMS] Local Transactionality Sample

Hi all,

Let's consider about JMS Transport parameter [1] "jms.transport.transactionality" sample. In here I use local transactionality.

When it's comes to transactionality, it helps to establish reliability message transformation. We can use tranactions and roll back them when having any issue/error. Within WSO2 ESB, it supports main two type of transactios through JMS Transport. Those are local and jta.

Local transactions use basically for locally used wso2 ESB instances while jta using for distributed systems. JTA transactions may engage with distributed system having clusters of esb which adding data to database etc.

Lets take a simple example of local tranactions which will roll back transaction in a failure. Lets' begin...

Rrerequisite:

1. Message broker should be up and running (Ex: wso2 MB)

2. ESB should be configured with relevant message broker. Add "transport.Transactionality" parameter and "transport.jms.SessionTransacted" parameter.

Sample axis2.xml Configuration:

 <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">   
  <parameter name="myTopicConnectionFactory" locked="false">   
     <parameter name="java.naming.factory.initial" locked="false">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>   
     <parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>    
     <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
     <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>  
     <parameter name="transport.jms.Transactionality" locked="true">local</parameter>   
     <parameter name="transport.jms.SessionTransacted" locked="true">true</parameter>  
     <parameter>   

    <parameter name="myQueueConnectionFactory" locked="false">   
     <parameter name="java.naming.factory.initial" locked="false">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>   
     <parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>   
     <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>   
     <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>   
     <parameter name="transport.jms.Transactionality" locked="true">local</parameter>   
     <parameter name="transport.jms.SessionTransacted" locked="true">true</parameter>   
    </parameter>       

    <parameter name="default" locked="false">   
     <parameter name="java.naming.factory.initial" locked="false">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>   
     <parameter name="java.naming.provider.url" locked="false">repository/conf/jndi.properties</parameter>   
     <<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>   
     <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>   
     <parameter name="transport.jms.Transactionality" locked="true">local</parameter>   
     <parameter name="transport.jms.SessionTransacted" locked="true">true</parameter>   
    </parameter>   
   </transportReceiver>   


3. ESB should be up and running.

4. Axis2 server should be started in port 9000

Sample:

Create a proxy with following configuration: (For proxy insequence and fault sequence, I created two seperate sequences )

 <proxy name="ErrorProxy" startOnLoad="true" transports="https http jms">  
     <target faultSequence="fault" inSequence="ErrorInSequence"/>  
     <parameter name="transport.jms.ContentType">  
       <rules>  
         <jmsProperty>contentType</jmsProperty>  
         <default>text/xml</default>  
       </rules>  
     </parameter>  
     <parameter name="transport.jms.ConnectionFactory">myQueueConnectionFactory</parameter>  
     <parameter name="transport.jms.DestinationType">queue</parameter>  
     <parameter name="transport.jms.SessionTransacted">true</parameter>  
     <parameter name="transport.jms.Destination">errorQueue</parameter>  
   </proxy>  

Error Sequence Configuration:

  <sequence name="fault">  
     <log level="full"/>  
     <property name="SET_ROLLBACK_ONLY" scope="axis2" value="true"/>  
   </sequence>  

Insequence Configuration:

   <sequence name="ErrorInSequence">  
     <call blocking="true">  
       <endpoint>  
         <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>  
       </endpoint>  
     </call>  
     <description/>  
   </sequence>  

Running Sample:

* Publish messages to queue (errorQueue) in Message Broker. I used external jms message publisher.

External JMS Publisher Java Class:

 import javax.jms.*;  
 import javax.naming.Context;  
 import javax.naming.InitialContext;  
 import javax.naming.NamingException;  
 import java.util.Properties;  
 /**  
  * Created by dilshani on 5/11/16.  
  * This class will publish messages to MB Queue  
  */  
 public class QueuePublisher {  
   public static final String QPID_ICF = "org.wso2.andes.jndi.PropertiesFileInitialContextFactory";  
   private static final String CF_NAME_PREFIX = "connectionfactory.";  
   private static final String QUEUE_NAME_PREFIX = "queue.";  
   private static final String CF_NAME = "qpidConnectionfactory";  
   String userName = "admin";  
   String password = "admin";  
   private static String CARBON_CLIENT_ID = "carbon";  
   private static String CARBON_VIRTUAL_HOST_NAME = "carbon";  
   private static String CARBON_DEFAULT_HOSTNAME = "localhost";  
   private static String CARBON_DEFAULT_PORT = "5672";  
   String queueName = "QueueProxy";  
   int publishMsgCount=1;  
   public static void main(String[] args) throws NamingException, JMSException {  
     QueuePublisher queueSender = new QueuePublisher();  
     queueSender.sendMessages();  
   }  
   public void sendMessages() throws NamingException, JMSException {  
     Properties properties = new Properties();  
     properties.put(Context.INITIAL_CONTEXT_FACTORY, QPID_ICF);  
     properties.put(CF_NAME_PREFIX + CF_NAME, getTCPConnectionURL(userName, password));  
     properties.put(QUEUE_NAME_PREFIX + queueName, queueName);  
     Properties properties2 = new Properties();  
     properties2.put(Context.INITIAL_CONTEXT_FACTORY, QPID_ICF);  
     properties2.put(CF_NAME_PREFIX + CF_NAME, getTCPConnectionURL(userName, password));  
     System.out.println("getTCPConnectionURL(userName,password) = " + getTCPConnectionURL(userName, password));  
     InitialContext ctx = new InitialContext(properties);  
     // Lookup connection factory  
     QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.lookup(CF_NAME);  
     QueueConnection queueConnection = connFactory.createQueueConnection();  
     queueConnection.start();  
     QueueSession queueSession = queueConnection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE );//  
     Queue queue = (Queue)ctx.lookup(queueName);  
     javax.jms.QueueSender queueSender = queueSession.createSender(queue);  
     //sending 5 messages to the above created queue here  
     for(Integer i=1;i<=publishMsgCount;i=i+1){  
       TextMessage textMessage = queueSession.createTextMessage("::::Test Message:::: "+i+":::Publish to queue:::"+queueName+":::From IP:::"+CARBON_DEFAULT_HOSTNAME);  
       textMessage.setStringProperty("msgID", i.toString());  
       queueSender.send(textMessage);  
       System.out.println("Publishing Test Message "+i+"::Published From IP::"+CARBON_DEFAULT_HOSTNAME);  
     }  
     queueSender.close();  
     queueSession.close();  
     queueConnection.close();  
   }  
   public String getTCPConnectionURL(String username, String password) {  
     // amqp://{username}:{password}@carbon/carbon?brokerlist='tcp://{hostname}:{port}'  
     return new StringBuffer()  
         .append("amqp://").append(username).append(":").append(password)  
         .append("@").append(CARBON_CLIENT_ID)  
         .append("/").append(CARBON_VIRTUAL_HOST_NAME)  
         .append("?brokerlist='tcp://").append(CARBON_DEFAULT_HOSTNAME).append(":").append(CARBON_DEFAULT_PORT).append("'")  
         .toString();  
   }  
 }  

* You may see response from backend (Axis2 server on port 9000)

* Shut down axis 2 server and Publish messages to jms queue.

* Check ESB server terminal. It may print error sequence log several times. (Which is trying to rollback the transaction)

Note : As its' rollback transaction, message will be send to jms queue. But again it will be taken from proxy as it listen to that and will try to send. Then again move to fault sequence and it will be working like a round. (Untill time out)

Now you have a working sample of ESB local transactionality.


Wednesday, May 25, 2016

[WSO2][ESB] Class mediator sample

Hi all,

Here I present sample class mediator which I used in JMS local transactions. You can download relevant dependency jars thorough following links:

Dependency jars:

  •  Synapse core - http://www.java2s.com/Code/JarDownload/synapse/synapse-core-2.1.0.jar.zip
  •  Apache axiom - http://www.java2s.com/Code/JarDownload/apache-axiom/apache-axiom-api-1.2.7.jar.zip 
 package org.wso2.carbon.mediator;  
 import org.apache.synapse.MessageContext;  
 import org.apache.synapse.mediators.AbstractMediator;  
 /**  
  * This class counting messages received and use as class mediator
  */  
 public class MessageCounterMediator extends AbstractMediator {  
     private static int MESSAGE_COUNT = 0;  
     public boolean mediate(MessageContext synCtx) {  
       MESSAGE_COUNT++;  
       synCtx.setProperty("MESSAGE_COUNT", MESSAGE_COUNT);  
       return true;  
     }  
 }  

For more information, refer https://docs.wso2.com/display/ESB470/Sample+380%3A+Writing+your+own+Custom+Mediation+in+Java

You can write own java classes and use them within WSO2 ESB. :) :)

Tuesday, May 24, 2016

HornetQ JMS Subscriber

Hi all,

HornetQ is a JMS broker which is support JMS 2.0 specification. Here you can find a JMS subscriber written for queue within HornetQ.

 import javax.jms.*;  
 import javax.naming.Context;  
 import javax.naming.InitialContext;  
 import java.util.Properties;  
 /**  
  * This is a hornetq subscriber java class for a queue  
  */  
 public class HornetQSubscriber {  
   private static final String DEFAULT_CONNECTION_FACTORY = "QueueConnectionFactory";  //TopicConnectionFactory when using for topics
   private static final String DEFAULT_DESTINATION = "queue/mySampleQueue";  //Can change when it is a topic
   private static final String INITIAL_CONTEXT_FACTORY = "org.jnp.interfaces.NamingContextFactory";  
   private static final String PROVIDER_URL = "jnp://localhost:1099";  
   public static void main(final String[] args) {  
     try {  
       runExample();  
     } catch (Exception e) {  
       e.printStackTrace();  
     }  
   }  
   public static void runExample() throws Exception {  
     Connection connection = null;  
     Context initialContext = null;  
     try {  
       // /Step 1. Create an initial context to perform the JNDI lookup.  
       final Properties env = new Properties();  
       env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);  
       env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));  
       initialContext = new InitialContext(env);  
       // Step 2. perform a lookup on the Queue  
       Queue queue = (Queue) initialContext.lookup(DEFAULT_DESTINATION);  
       // Step 3. perform a lookup on the Connection Factory  
       ConnectionFactory cf =  
           (ConnectionFactory) initialContext.lookup(DEFAULT_CONNECTION_FACTORY);  
       // Step 4. Create a JMS Connection  
       connection = cf.createConnection();  
       // Step 5. Create a JMS Session  
       Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);  
       // Step 6. Create a JMS Message Consumer  
       MessageConsumer messageConsumer =  
           session.createConsumer(queue);  
       // Step 7. Start the Connection  
       connection.start();  
       System.out.println("Message consumer started on Queue: " + DEFAULT_DESTINATION +  
           "\n");  
       // Step 8. Receive the message  
       int message_count=0;  
       while (messageConsumer.receive()!=null) {  
         message_count++;  
         System.out.println("Received a message ------------"+message_count);  
       }  
     } finally {  
       // Step 9. Close JMS resources  
       if (connection != null) {  
         connection.close();  
       }  
       // Also the initialContext  
       if (initialContext != null) {  
         initialContext.close();  
       }  
     }  
   }  
 }  

* Note : you can modify class when you are going to publish JMS messages to topics. Relevant places are highlighted within the class.

Wednesday, May 11, 2016

How to write a JMS publisher for queue in WSO2 MB ?

Hello all,

We are gonna write a JMS publisher for queue WSO2 MB. Let's begin ...

Prerequisites:
  • WSO2 MB pack should be downloaded.
  • MB should be up and running (You can follow WSO2 MB documentation, if you are not familiar with MB) 
  • Java should be installed (As we implement JMS publisher as a Java Class)
Environment used:
  • Oracle jdk 1.8
  • MB 3.1.0
  • IDEA as 
JMS Publisher class:

 import javax.jms.*;  
 import javax.naming.Context;  
 import javax.naming.InitialContext;  
 import javax.naming.NamingException;  
 import java.util.Properties;  
 /**  
  * This class will publish messages to MB Queue  
  */  
 public class QueuePublisher {  
   public static final String QPID_ICF = "org.wso2.andes.jndi.PropertiesFileInitialContextFactory";  
   private static final String CF_NAME_PREFIX = "connectionfactory.";  
   private static final String QUEUE_NAME_PREFIX = "queue.";  
   private static final String CF_NAME = "qpidConnectionfactory";  
   String userName = "admin";  
   String password = "admin";  
   private static String CARBON_CLIENT_ID = "carbon";  
   private static String CARBON_VIRTUAL_HOST_NAME = "carbon";  
   private static String CARBON_DEFAULT_HOSTNAME = "localhost";  
   private static String CARBON_DEFAULT_PORT = "5672";  
   String queueName = "JMSProxy";  //Change this with relevant queue name
   int publishMsgCount=5;  
   public static void main(String[] args) throws NamingException, JMSException {  
     QueuePublisher queueSender = new QueuePublisher();  
     queueSender.sendMessages();  
   }  
   public void sendMessages() throws NamingException, JMSException {  
     Properties properties = new Properties();  
     properties.put(Context.INITIAL_CONTEXT_FACTORY, QPID_ICF);  
     properties.put(CF_NAME_PREFIX + CF_NAME, getTCPConnectionURL(userName, password));  
     properties.put(QUEUE_NAME_PREFIX + queueName, queueName);  
     Properties properties2 = new Properties();  
     properties2.put(Context.INITIAL_CONTEXT_FACTORY, QPID_ICF);  
     properties2.put(CF_NAME_PREFIX + CF_NAME, getTCPConnectionURL(userName, password));  
     System.out.println("getTCPConnectionURL(userName,password) = " + getTCPConnectionURL(userName, password));  
     InitialContext ctx = new InitialContext(properties);  
     // Lookup connection factory  
     QueueConnectionFactory connFactory = (QueueConnectionFactory) ctx.lookup(CF_NAME);  
     QueueConnection queueConnection = connFactory.createQueueConnection();  
     queueConnection.start();  
     QueueSession queueSession = queueConnection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE );//  
     Queue queue = (Queue)ctx.lookup(queueName);  
     javax.jms.QueueSender queueSender = queueSession.createSender(queue);  
     //sending 5 messages to the above created queue here  
     for(Integer i=1;i<=publishMsgCount;i=i+1){  
       TextMessage textMessage = queueSession.createTextMessage("::::Test Message:::: "+i+":::Publish to queue:::"+queueName+":::From IP:::"+CARBON_DEFAULT_HOSTNAME);  
       textMessage.setStringProperty("msgID", i.toString());  
       queueSender.send(textMessage);  
       System.out.println("Publishing Test Message "+i+"::Published From IP::"+CARBON_DEFAULT_HOSTNAME);  
     }  
     queueSender.close();  
     queueSession.close();  
     queueConnection.close();  
   }  
   public String getTCPConnectionURL(String username, String password) {  
     // amqp://{username}:{password}@carbon/carbon?brokerlist='tcp://{hostname}:{port}'  
     return new StringBuffer()  
         .append("amqp://").append(username).append(":").append(password)  
         .append("@").append(CARBON_CLIENT_ID)  
         .append("/").append(CARBON_VIRTUAL_HOST_NAME)  
         .append("?brokerlist='tcp://").append(CARBON_DEFAULT_HOSTNAME).append(":").append(CARBON_DEFAULT_PORT).append("'")  
         .toString();  
   }  
 }  


** For this java class you have to add client libraries as dependencies. You can find relevant jars from $MB_HOME/client-lib/

Add all these jars as dependencies.
  • andes-client-3.1.1.jar
  • geronimo-jms_1.1_spec-1.1.0.wso2v1.jar
  • log4j-1.2.13.jar
  • org.wso2.carbon.logging-4.4.1.jar
  • org.wso2.securevault-1.0.0-wso2v2.jar
  • slf4j-1.5.10.wso2v1.jar
You are successfully done with JMS publisher. Add a queue in MB which you want to publish messages and add that name in the JMS publisher class.

(Note: In here I used "JMSProxy" queue to publish messages.)

Monday, April 25, 2016

XSLT Transformation Script elements

Hi all,

Lets clarify some of elements in an XSLT transform script.

I used this scenario within WSO2 ESB "XSLT" mediator. When defining XSLT mediator u have to give exact transform script to run exact mediation function.

Lets consider about some of elements of xslt transform script.
  • Can use following two methods to declare XSL style sheet
<xsl:stylesheet version="1.0"
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">

OR

<xsl:transform version="1.0"
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform">                          
  • <xsl:template> element is used to build templates.
"match" attribute used to associate with XML element. 

 <xsl:template match="/">  ----> This define consider whole document


Examples of match patterns:


<xsl:template match="table">
 
can be applied on any element named table.

<xsl:template match="x/y">

can be applied on any element named y whose parent is an element named x.

<xsl:template match="*">
can be applied to any element.

<xsl:template match="/*">

can be applied only to the top element of an XML document.

<xsl:template match="@*">

can be applied to any attribute.

<xsl:template match="text()">

can be applied to any text node.

<xsl:template match="comment()">

can be applied to any comment node.

<xsl:template match="processing-instruction()">

can be applied to any processing instruction node.

<xsl:template match="node()">

can be applied to any node: element, text, comment or processing instruction.


<xsl: output> element defines the format of the output document


<xsl:output method="xml|html|text|name"

version="string"

encoding="string"

omit-xml-declaration="yes|no"

standalone="yes|no"

doctype-public="string"

doctype-system="string"

cdata-section-elements="namelist"

indent="yes|no"

media-type="string"/>


<xsl:copy> element creates a copy of the current node. 

<xsl:copy use-attribute-sets="name-list">

  <!-- Content:template -->

</xsl:copy>

<xsl:apply-templates> element applies a template to the current element or to the current element's child nodes.

Like wise you can elements. In here, I summarised few of main elements. Value additions are welcome :)

Thursday, April 21, 2016

Starting with git repo

Hey,

I need to create a repository and make a clone of it. Creating a repo in git id easy and you can do it via github UI. I guess you are familiar with github and you may have played with some git repos.

This post will summarize steps of creating a clone in local machine and make a commit using that.
Lets begin...

Preconditions:

  • Have account in github.
  • Installed git in your local machine
  • Have access to repo which is going to clone (Most probably it may be a public or your own one)

Steps to follow:

You have to use following commands:

         git clone <link>
                Ex: git clone https://github.com/Dilshani/BlogStuff.git
     
         git config --global user.email "you@example.com"

         git config --global user.name "Your Name"
 
         git remote add <name for repo> <url of repo>

         git add .         -->  (This will add all new files to commit)

         git commit -m "message"

         git push origin master

Then newly added stuff will be committed to repo. (If you own the repo, you don't need to make a  commit request by github UI. Otherwise, you have to go and make a pull request)

When you are committing files again, you can proceed with "git add" command onwards.

Note: You can add files separately or add all at once.

git add <file name>  ----  > Add file by file

git add .   -----> Add all files at once

Now you know how to add commits to git hub repo. Well Done :)



Sunday, April 10, 2016

[WSO2][ESB][Class Mediator]How to create an Empty OMElement Array?

Hi all,

Let's find out very interesting topic. While using store mediator in ESB, I just wanted to create an empty OMElement array.

If I clarify inside mediation within ESB, when it receive a message, it may convert into OMElements which will is used to next mediation process. Therefore, I can't send empty OMElement array from outside as it is an inside process of ESB (Just like sending SOAP or REST messages).

So we have to convert the message into OMElements within ESB.In my case, I have to add empty OMElement array to the message.

ESB is a marvellous middleware which will provide magical operations. Here it comes "Class Mediator". The Class mediator will retrieve a class and it may act as custom mediator.

So Class Mediator helped me to do my task.

Let's begin...

1) Write a java class which will set OMElement array to the message.

When writing java class which is going to deploy as a "Class Mediator", it must extend from "Abstract Mediator"

In here I used message context (org.apache.synapse.MessageContext) to add empty array.

As a property set new array without any elements.

Sample Configuration

 package org.wso2.test;  
 import java.util.ArrayList;  
 import org.apache.synapse.MessageContext;  
 import org.apache.synapse.mediators.AbstractMediator;  
 public class OMElementEmptyArray  
 extends AbstractMediator {  
   public boolean mediate(MessageContext context) {  
     context.setProperty("EMPTY_ARRAY", new ArrayList());  
     System.out.println("Routed through Class Mediator");  
     return true;  
   }  
 }  

2) Java class packaged as .jar and should be inside $ESB_HOME/repository/components/lib

3) ESB should be up and running.

4) Login to ESB and create an API which will add class mediator.

Sample Configuration:

 <api context="/SerializeProperty" name="StoreMediatorSerialize">  
     <resource methods="GET" protocol="http" url-mapping="/serializeOMArray">  
       <inSequence>  
         <class name="org.wso2.test.OMElementEmptyArray"/>  
       </inSequence>  
       <outSequence/>  
       <faultSequence/>  
     </resource>  
   </api>  

5) Invoke API.

Sample Invocation through REST Client:

GET      http://10.100.7.120:8280/SerializeProperty

Terminal will print follow log:

Routed through Class Mediator


Happy Coding !!!


Thursday, April 7, 2016

[WSO2] [QA] [TestLink] How to write a good Test Case ? (2)

Hey,

Hope you read the first part of this blog post. If not, better to read it first and come to this add more value. Then consider about best practices...

Best Practices:

1) Should not add links in the test case (Important in WSO2 culture, as its' product version release frequently.). If you need something relevant to a document/link add its name, not the link.

Ex:

Not this link : https://docs.wso2.com/display/ESB490/Header+Mediator

Add it as: Refer Header Mediator Documents 

2) Should not add several test steps. Then it will be bored to read.

3) Add short, point form steps to test case. It makes easy to read.

Ex:

Add sequence mediator to the above sequence.
Select "Key Type" as dynamic key 
Give previously created property as Referring sequence.

Ex: {get-property('property')}

4) Add relevant configuration in user-friendly manner (Ex: Adding header mediator with relevant configurations)

Ex: Rather than saying "Create a Header mediator with this and this", you can give configuration as below:

Create a sequence with header mediator which adding "SOAP Header" to incoming SOAP message.

Header Mediator configuration:
  • Name:wsa:newHeader
  • Action:Set
  • Value:Accept
  • Scope:Synapse

[WSO2] [QA] [TestLink] How to write a good Test Case ?

Hello Beginners,

So you may be a beginner or someone who are interesting to improve yourself. Great :) Lets begin...

In my case, I am using Test Link to add test cases. How are we going to write a good test case ?

1) First, you must have the overall idea of what you are going to test and write test cases. So read feature or use case and understand it well.

In my case, I will read documentations and relevant scenarios to learn exact feature.

2) Then design the plan or mind map to test. Through that, you will identify many possible scenarios to test.

As we are human, we may miss some points or testing scenarios. So it will be great if you are using a paper of design to sketch the diagram/design.

Ex:

Aggregate Mediator ----> How we implement Aggregate mediator (Can use iterate/clone mediator)
                                          At where? (In sequence /  out sequence)
                                          What can we do with that? (Aggregate messages/aggregate and put in to one element etc.)
       
Note: It will better to design/sketch diagrams rather than note down. Because visual representations easy to grab and easy to follow.

3) Let's write a test case for identified scenario.

Let's take example from Header Mediator (WSO2 ESB). Through Header mediator, it can handle HTTP headers and SOAP headers. Let's consider "Adding new SOAP header ".

So giving the name of the test case as "Adding new SOAP header for incoming messages".

Name of the test case must identify
  • What is the action we do through the test case (Ex: Adding)
  • What will be the result (Ex: New SOAP header)
  • For what we doing/ Where are we going to do that (Ex: For incoming messages)

4) Then it is the summary. As the name indicate it must summarize what you are going to do through the test case.

It may also include things which considered in the "Name". If something to specify more, you can use the summary to do that. But always it may short and sweet as the "Name" given.

Sample Summary:

This test case will cover adding new SOAP header for messages

5) Then it is "Preconditions".

In here, You must include everything which is required to continue test steps without any problem.

For example: I am testing WSO2 ESB header and it is needed to have ESB server up and running. And other requirements also should be included according to the scenario.

Sample Preconditions:
  • User should be login to ESB with proper credentials
  • Deploy the SimpleStockQuoteService on axis2 server and start axis2 server
6) Let's write test steps. Every step is must be meaningful and must have an expected result.

Add sample configurations to test steps and sample results in expected results.

Sample Test Steps:

Step Action

Create a sequence with header mediator which adding header to incoming SOAP message.

Header Mediator configuration:
  • Name:wsa:newHeader
  • Action:Set
  • Value:Accept
  • Scope:Synapse

Note: As a good practice add relevant configuration in a user friendly manner. Rather than saying "Create a Header mediator with this and this", you can give configuration as above example.

Expected Result

Sequence should be created.

Sample configuration:

<sequence name="seq30" xmlns="http://ws.apache.org/ns/synapse">
    <log level="full">
        <property name="Message" value="==========Before Header========="/>
    </log>
    <header name="wsa:newHeader" scope="default" value="Accept" xmlns:wsa="http://www.w3.org/2005/08/addressing"/>
    <log level="full">
        <property name="Message" value="==========After Header========="/>
    </log>
</sequence>



7) Check twice. Every step you write needed to care about.

Keep maintain less number of test steps while having steps which are easy to read.

Highlight words you want to impress.

8) Add correct status of Test case. After finished your test case, change Status to "Ready for review"

In Test Link, there are several status for test cases:

Draft - When you are working on the test case
Ready for review - Finished test case
Review in progress
Rework - This will add by reviewer if something has to change. And reviewer may add some comments under status saying what should have to change.
Obsolete - When this test case not useful anymore.
Future - In future, must add something. This may be used in improving the feature. After development, it has to update.
Final - Test case is done.

So now we are in Final State of the blog post.

Happy QAing :) :) :)

Wednesday, March 30, 2016

[WSO2 ESB]How to retrive dynamic file which is saved in local folder?

Lets check out the way to retrieve file through ESB mediators.

In here I used

  • XML file which is contains a sequence (File which is saved in local folder)
  • Use Property mediator to retrieve file 
  • Use sequence mediator to run the dynamic file which is saved in local folder (In here I selected sequence mediator, because I saved sequence within XML file)
Lets begin...


  1. XML file should be put into a folder

  • In here Pre-defined sequence added to XML file and saved it with sequence name (dynamic_seq_2.xml). 
Sample configuration:

 <sequence name="dynamic_seq_2" xmlns="http://ws.apache.org/ns/synapse">  
   <in>  
     <log level="full">  
       <property name="message" value="*** Test Message ***"/>  
     </log>  
   </in>  
    <send>  
       <endpoint>  
         <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>  
       </endpoint>  
     </send>  
 </sequence>  

  • Saved "dynamic_seq_2.xml" file in "$ESB_HOME/repository/samples/resources/sequence/"
2. Start axis2 server.

Note: Sample axis2 server comes with ESB pack ($ESB_HOME/samples/axis2Server/). I used it.

          I used SimpleStockQuote service as the backend. Therefore you have to deploy SimpleStockQuote service if you didn't do.

Navigate to $ESB_HOME/samples/axis2Server/src/SimpleStockQuote/ through terminal.
Run "ant" command
 $ ant  

          Then start axis2 server.

Navigate to $ESB_HOME/samples/axis2Server/ through terminal.
Start server
 $ sh axis2server.sh  

3  Start WSO2 ESB server

4. Navigate to Source View (Home > Manage > Service Bus  > Source View  > Service Bus Configuration)

Change registry provider as "ESBRegistry" and give path to the folder which you saved dynamic sequence.

Sample configuration:

 <registry provider="org.wso2.carbon.mediation.registry.ESBRegistry">  
     <parameter name="root">file:repository/samples/resources/</parameter>  
     <parameter name="cachableDuration">15000</parameter>  
 </registry>  

5. Restart ESB

6. Navigate to sequences (Home > Manage > Service Bus > Sequences) and Click on "Add sequences"

7. Create a sequence

   Add property which will have path to retrieve dynamic sequence.

   Add sequence mediator with dynamic key. Give previously created property as Referring sequence.

Sample Configuration

 <sequence name="seq5">  
     <property name="property" scope="default" type="STRING" value="sequence/dynamic_seq_2.xml"/>  
     <sequence key="{get-property('property')}"  
      xmlns:ns3="http://org.apache.synapse/xsd" xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"/>  
 </sequence>  

8.  Create a proxy service with sequence.

Sample Configuration:

 <proxy name="dynamicKeySeq" startOnLoad="true" trace="disable" transports="http https">  
     <description/>  
     <target inSequence="seq5"/>  
 </proxy>  

9.  Invoke proxy service.

Sample Message:

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples" xmlns:xsd="http://org.apache.synapse/xsd">  
   <soapenv:Body>  
    <ser:placeOrder>  
      <!--Optional:-->  
      <ser:order>  
       <!--Optional:-->  
       <xsd:price>91.7473384496671</xsd:price>  
       <!--Optional:-->  
       <xsd:quantity>7616</xsd:quantity>  
       <!--Optional:-->  
       <xsd:symbol>IBM</xsd:symbol>  
      </ser:order>  
    </ser:placeOrder>  
   </soapenv:Body>  
 </soapenv:Envelope>  

Then ESB logs should be indicating redirecting through dynamic sequence.

[2016-03-30 10:32:50,908]  INFO - LogMediator To: http://localhost:8280/services/dynamicKeySeq, WSAction: urn:placeOrder, SOAPAction: urn:placeOrder, ReplyTo: http://www.w3.org/2005/08/addressing/anonymous, MessageID: urn:uuid:02abb47f-bd35-4717-98e3-b3f1f7e2b73e, Direction: request, message = *** Test Message ***, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://org.apache.synapse/xsd" xmlns:ser="http://services.samples"><soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>urn:placeOrder</wsa:Action><wsa:To>http://localhost:8280/services/dynamicKeySeq</wsa:To></soapenv:Header><soapenv:Body>
      <ser:placeOrder>
         <!--Optional:-->
         <ser:order>
            <!--Optional:-->
            <xsd:price>91.7473384496671</xsd:price>
            <!--Optional:-->
            <xsd:quantity>7616</xsd:quantity>
            <!--Optional:-->
            <xsd:symbol>IBM</xsd:symbol>
         </ser:order>
      </ser:placeOrder>
   </soapenv:Body></soapenv:Envelope>

Note: Configuring part of ESB to retrieve local files, done with first 4 steps. Retrieving part done through adding mediator. Confirming and validation part done through sequence mediator logs.

According to your requirements, can modify mediators and relevant configurations.

All comments and value additions are warmly welcome !! :)

Tuesday, March 29, 2016

[WSO2 ESB] How to read a value of SOAP element using property mediator

Hi all,

Property mediator in WSO2 ESB is a very useful mediator and can be use for various mediation purposes. In here I used property mediator to read SOAP element value.

1. I created a sequence with property mediator. Sample Configuration as follows:

 <sequence name="propertySeq">  
     <property expression="//ser:getSimpleQuote/ser:symbol/text()"  
       name="testProperty" scope="default" type="STRING"  
       xmlns:ns="http://org.apache.synapse/xsd"  
       xmlns:ser="http://services.samples" xmlns:xsd="http://sample.wso2.org/xsd"/>  
     <log level="custom">  
       <property expression="get-property('testProperty')"  
         name="PropertyValue" xmlns:ns="http://org.apache.synapse/xsd"/>  
     </log>  
   </sequence>  

2. I created a proxy service with above sequence.

 <proxy name="propertyProx" startOnLoad="true" trace="disable" transports="http https">  
     <description/>  
     <target endpoint="SimpleStockQuote" inSequence="propertySeq"/>  
 </proxy>  
 <endpoint name="SimpleStockQuote">  
     <address uri="http://localhost:9000/services/SimpleStockQuoteService/"/>  
 </endpoint>  

3. Invoke proxy service. 

Note: Through property mediator, I will retrieve value of "symbol" and used logs to indicated retruved value.

Sample SOAP message will be as follows:

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">  
   <soapenv:Header/>  
   <soapenv:Body>  
    <ser:getSimpleQuote>  
      <!--Optional:-->  
      <ser:symbol>WSO2</ser:symbol>  
    </ser:getSimpleQuote>  
   </soapenv:Body>  
 </soapenv:Envelope>  

Logs should be illustrate as follows: 

 [2016-03-29 18:28:22,380] INFO - LogMediator PropertyValue = WSO2  

Note: According to message type and according to the content you want to add to property mediator, you can change above configurations.

Happy Coding !! :)

Enrich Mediator - WSO2 ESB

Hi all,

Let’s discuss about Enrich mediator of WSO2 ESB. You can find it under core mediators.



And you also can find more information from WSO2 ESB Documentation. Before move to functionalities, I will give small description about “Source” and “Target”



Source - What will be using to do enriching ? (Ex: Property, inline content, body content etc.)
Target - Where and Action going to do Within the enrich process ? (Ex: Replace, add child to payload etc.)

I will here, list down main functionalities of Enrich mediator with regard to its available options. (I will give example scenarios for different Target Actions)

There are main three target actions as “Replace”, “Child” and “Sibling”. With the different source types (Inline, Property, Body etc.), you can perform number of different actions. I present basic sample scenarios for Target Actions.

1. Replace

Config
<sequence name="enrich_seq_3" xmlns="http://ws.apache.org/ns/synapse">
    <property name="testProperty" scope="default" type="STRING" value="WSO2"/>
    <enrich>
       <source clone="true" property="testProperty" type="property"/>
       <target action="replace" type="custom"
           xmlns:ns="http://org.apache.synapse/xsd"
           xmlns:ser="http://services.samples" xpath="//ser:getSimpleQuote/ser:symbol/text()"/>
    </enrich>
    <log level="full"/>
</sequence>

Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">
  <soapenv:Header/>
  <soapenv:Body>
     <ser:getSimpleQuote>
        <!--Optional:-->
        <ser:symbol>IBM</ser:symbol>
     </ser:getSimpleQuote>
  </soapenv:Body>
</soapenv:Envelope>

After Enriching
<?xml version='1.0' encoding='UTF-8'?>
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">
     <soapenv:Body>    
        <ser:getSimpleQuote>       
           <!--Optional:-->       
              <ser:symbol>WSO2</ser:symbol>    
           </ser:getSimpleQuote>   
        </soapenv:Body>
     </soapenv:Envelope>

2. Adding Child

Config
<sequence name="enrich_seq_11" xmlns="http://ws.apache.org/ns/synapse">
    <log level="full"/>
    <enrich>
       <source clone="true" type="body"/>
       <target action="child" type="body"/>
    </enrich>
    <log level="full"/>
</sequence>

Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">
  <soapenv:Header/>
  <soapenv:Body>
     <ser:getSimpleQuote>
        <!--Optional:-->
        <ser:symbol>IBM</ser:symbol>
     </ser:getSimpleQuote>
  </soapenv:Body>
</soapenv:Envelope>

After Enriching

<?xml version='1.0' encoding='UTF-8'?>
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">   
     <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"/>   
     <soapenv:Body>    
        <ser:getSimpleQuote>       
           <!--Optional:-->       
              <ser:symbol>IBM</ser:symbol>
              <ser:getSimpleQuote>       
                 <!--Optional:-->       
                    <ser:symbol>IBM</ser:symbol>    
                 </ser:getSimpleQuote>
              </ser:getSimpleQuote>   
           </soapenv:Body>
        </soapenv:Envelope>

3. Adding Sibling

Config
<sequence name="enrich_seq_11" xmlns="http://ws.apache.org/ns/synapse">
   <log level="full"/>
   <enrich>
       <source clone="true" type="body"/>
       <target action="sibling" type="body"/>
   </enrich>
   <log level="full"/>
</sequence>

Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">
  <soapenv:Header/>
  <soapenv:Body>
     <ser:getSimpleQuote>
        <!--Optional:-->
        <ser:symbol>IBM</ser:symbol>
     </ser:getSimpleQuote>
  </soapenv:Body>
</soapenv:Envelope>

After enriching
<?xml version='1.0' encoding='UTF-8'?>
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">   
     <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"/>   
     <soapenv:Body>    
        <ser:getSimpleQuote>       
           <!--Optional:-->       
              <ser:symbol>IBM</ser:symbol>    
           </ser:getSimpleQuote>
           <ser:getSimpleQuote>       
              <!--Optional:-->       
            <ser:symbol>IBM</ser:symbol>    
              </ser:getSimpleQuote>   
           </soapenv:Body>
        </soapenv:Envelope>

Note: As I mentioned earlier, this is basic functionalities u can do with Enrich mediator. Try out it through different aspects and find new mediation patterns ;)

Value additions are always welcome :)