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