Wednesday, December 14, 2011

Writing a custom class mediator in wso2esb

In this post we will look at how to write a very simple class mediator for wso2esb. All what you have to do is, just extend the AbstractMediator class (org.apache.synapse.mediators.AbstractMediator) or implement the Mediator interface (org.apache.synapse.Mediator). AbstractMediator contains the implementation for some methods , so it would be easy to use that class.
Say, in a scenario, when exception occurs  at ESB, we want to extract the error details , and need to do further processing. In the following  sample,  error details are extracted and printed as sysout..

package org.wso2.carbon.custommediator
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;

/**
* This custom mediator extracts error detail from synapse messagecontext.
* SynapseConfiguration would be;
*<insequence>
*   <class name="org.wso2.carbon.custommediator.CustomErrorDataMediator">
*   </class>
*</insequence>
**/

public class CustomErrorDataMediator extends AbstractMediator {

public boolean mediate(MessageContext synapseMsgContext) {
  String errorMesssage = (String) synapseMsgContext.getProperty("ERROR_MESSAGE");
  Exception exception = (Exception)  synapseMsgContext.              getProperty("ERROR_EXCEPTION");
  String errorCode = (String) synapseMsgContext.getProperty("ERROR_CODE");
  String errorDetail = (String) synapseMsgContext.getProperty("ERROR_DETAIL");

  System.out.println("Error Message is "+errorMesssage +"ErrorCode "+errorCode);

  return true;
 }
}

To build above code (*.jar as output), use following pom.xml file..

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">


    <modelVersion>4.0.0</modelVersion>
    <groupId> org.wso2.carbon.custommediator</groupId>
    <artifactId> org.wso2.carbon.custommediator</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>
 
    <dependencies>
        <dependency>
            <groupId>org.apache.synapse</groupId>
            <artifactId>synapse-core</artifactId>
            <version>1.4.0-wso2v2</version>       
        </dependency>      
    </dependencies>

    <build>
        <plugins>  
          <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>2.0</version>
                 <configuration>
                     <source>1.5</source>
                     <target>1.5</target>
                 </configuration>
             </plugin>
        </plugins>
    </build>

</project>



Keep the *.jar in ESB/repository/component/lib folder and place the class mediator in your faultsequence.Whenever fault sequence get invoke, you will see the sysout at your server console.

Thursday, November 24, 2011

Retriving clientIP/Host within the sequence in Synapse

<property name="client-host" expression="get-property('axis2', 'REMOTE_HOST')"/>         
<property name="client-add" expression="get-property('axis2', 'REMOTE_ADDR')"/>
<log level="custom">    
    <property name="REMOTE_ADDR :" expression="get-property('client-add')"/>

    <property name="REMOTE_HOST:" expression="get-property('client-host')"/>
</log>

Tuesday, November 22, 2011

Overcoming : "AxisFault: Timeout waiting for connection" issue

This issue[1] you might face when you run your axis2client code in a loop  against a service..

To overcome above issue, set the "MULTITHREAD_HTTP_CONNECTION_MANAGER" property in the axis2 ConfigurationContext.

ConfigurationContext configContext =   ConfigurationContextFactory.  createConfigurationContextFromFileSystem("CARBON_HOME\\repository\\deployment\\client", "CARBON_HOME\\repository\\conf\\axis2_client.xml");

MultiThreadedHttpConnectionManager httpConnectionManager =  new MultiThreadedHttpConnectionManager();       

configContext.setProperty(HTTPConstants.MULTITHREAD_HTTP_CONNECTION_MANAGER,  httpConnectionManager);

[1]
Caused by: org.apache.axis2.AxisFault: Timeout waiting for connection
       at org.apache.axis2.AxisFault.
makeFault(AxisFault.java:430)
       at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:197)
       at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
Caused by: org.apache.commons.httpclient.
ConnectionPoolTimeoutException:
Timeout waiting for connection
       at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.doGetConnection(MultiThreadedHttpConnectionManager.java:490)
       at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager.getConnectionWithTimeout(MultiThreadedHttpConnectionManager.java:394)

Friday, November 18, 2011

Getting system time within the mediation flow in synapse

There are two default system properties available synapse, which can be used to retrieve the system time/date in a mediation flow..There are usecases, when an user needs to append the system time at the message arrival point to the synapse engine.
Use the property mediator to hold the system time..

<property name="sysDate" expression="get-property('SYSTEM_DATE')" scope="default"
type="STRING"/>
<property name="sysTime" expression="get-property('SYSTEM_TIME')" scope="default" type="STRING"/>

sample sequence would be;

<sequence name="get">
<property name="sysDate" expression="get-property('SYSTEM_DATE')" scope="default" type="STRING"/>
<property name="sysTime" expression="get-property('SYSTEM_TIME')" scope="default" type="STRING"/>
<log>
<property name="SYSTEM TIME IS*******" expression="get-property('sysTime')"/>
</log>
<log>
<property name="SYSTEM DATE IS*******" expression="get-property('sysDate')"/>
</log>
</sequence>



Thursday, November 17, 2011

Invoking a RESTful service via WSO2ESB

In the ESB, when we define a proxy, it is not a must to provide the service wsdl, unless if you want to hide/add a new elements in your service contract.
Lets check a  very simple basic proxy to process a HTTP GET request
  • Get wso2esb binary distribution.
  • Deploy the simplestockquote service and start the sample axis2server.
  • Start ESB.
Create the following proxy;
<proxy name="RestProxy" transports="https http" startOnLoad="true" trace="disable">
        <target>  
            <endpoint>
              <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
            </endpoint>             
            <outSequence>
                <send/>
            </outSequence>
        </target>
    </proxy>

Execute the following GETrequest url in your browser;
http://localhost:8280/services/RestProxy/getSimpleQuote?symbol=IBM

Now you will see the response in your browser. If you place the tcpmon between client and ESB, you can check your http 'get' request,

GET /services/RestProxy/getSimpleQuote?symbol=IBM HTTP/1.1
Host: 127.0.0.1:5555
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.24) Gecko/20111103 Firefox/3.6.24
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: region1_configure_menu=; region3_registry_menu=visible; region4_monitor_menu=;

In the above sample client sends the 'symbol=IBM' as the parameter for the operation "getSimpleQuote"..Say in the mediation logic user may need to change the parameter as 'SUN'.(ie:symbol=SUN)..For that he/she can use "REST_URL_POSTFIX" property ..Which basically adds the suffix for the REST service endpoint.
eg:
   <property name="REST_URL_POSTFIX" value="/getSimpleQuote?symbol=SUN" scope="axis2"/>

So, the insequence would be;
    <inSequence>
                <property name="REST_URL_POSTFIX" value="/getSimpleQuote?symbol=SUN" scope="axis2"/>
                <send>
                    <endpoint>
                        <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                    </endpoint>
                </send>
    </inSequence>


User could add your own mediation logic with whatever the mediators within the sequence..

Related post;
REST support in WSO2ESB - Introduction
REST Support in WSO2ESB - Handling JSON messages

Monday, November 14, 2011

Programmatically enabling log4j appenders

The standard way to enable 'appenders' in log4j is using log4j.properties file..Here lets check out how an user can enable the 'appenders' programmaticly..This is useful , when user wants a logging mechanism separately, which differs from his/her global logging setting..
This is a sample code i have written to grab proxy service level logging information separately..

    private void setLogger(ProxyService proxy) throws IOException {

        String filename = "logs/" + proxy.getName() + ".log";
        String datePattern = "yyyy-MM-dd";
        String SYSTEM_LOG_PATTERN = "[%d] %5p - %x %m {%c}%n";

        PatternLayout layout = new PatternLayout(SYSTEM_LOG_PATTERN);

        DailyRollingFileAppender appender = null;

        appender = new DailyRollingFileAppender(layout, filename, datePattern);

        Logger proxyLogger = Logger.getLogger("SERVICE_LOGGER." + proxy.getName());

        proxyLogger.setLevel((Level) Level.DEBUG);

        proxyLogger.setAdditivity(false);
        proxyLogger.addAppender(appender);

    }   

Thursday, November 3, 2011

Configuring WSO2 ESB with Oracle™AQ as Messaging Media

"OracleAQ provides database integrated messaging functionality. Its' underlying system works with oracle database. OracleJMS (OJMS) is the JMS interface to the Advanced Queuing (AQ) feature in the Oracle database. OJMS has JNDI support, which could be used to get 'ConnectionFactory' at run time and the connections returned from it will be able to transparently connect to the JMS server."

I have written a detail tutorial about the configurations needed to connect AQ , which is published [1] at wso2 site..Thanks Edwin  for the great help on AQ and LDAP configurations..
[1]http://wso2.org/library/tutorials/2011/11/configuring-wso2-esb-with-oracle-as-messaging-media


Saturday, October 29, 2011

Signing files in windows

Gpg4win helps users to securely encrypt  and sign  files with the help of encryption and digital signatures in windows platform. Gpg4win is the official GnuPG distribution for Windows .You can download it here.

After installing it you can use GUI to create a key or else use the command prompt to genertae the key.

#gpg --gen-key

This will ask number of options to be filled(name,mail,city code, etc..)After the successful generation, you can export your public key;
#gpg --armor --export  > KEYS
eg:  
gpg --armor --export ratha > KEYS

This will save your public key at your current directory. Save it safely. You might need to provide your public key when you sign the files.

Now create a checksum file for your file;(You may need to install OpenSSL utility for windows)
(eg: lets use a zip file to be signed)
Change directory path your 'test.zip' folder location..

#openssl md5  <test.zip> test.zip.md5

This will create a checksum named " test.zip.md5".

Then sign the test.zip file;
#gpg --armor --output test.zip.asc --detach-sig test.zip

Finally verify whether, you have signed the packs without any issue;

#gpg --verify test.zip.asc test.zip

Output indicates it is a bad signature or good one;
gpg: Signature made 10/29/11 13:08:56 Sri Lanka Standard Time using RSA key ID 125C5F48
gpg: Good signature from "vijayaratha


If you check via the GUI, it will list out available certificates;



Monday, October 10, 2011

Java JNDI based client for OJMS

To work with Java Naming and Directory Interface (JNDI) in OJMS , which is the JMS interface for AQ, we need to register the oracle database with LDAP server. JMS administrator can register ConnectionFactory objects in a LDAP server.
Lets check following sample code, which is used to register the connection factory objects @ LDAP server.

void register_Factory_in_LDAP() throws Exception {
        Hashtable env = new Hashtable();
        // ldap settings
        env.put(Context.INITIAL_CONTEXT_FACTORY, AQjmsConstants.INIT_CTX_FACTORY);
        env.put(Context.PROVIDER_URL, "ldap://localhost:10389/");
        env.put(AQjmsConstants.SERVER_DN, "cn=ORCL,cn=OracleContext,ou=Services, o=sgi,c=us");
        env.put(Context.SECURITY_PRINCIPAL, "uid=ratha,ou=Services, o=sgi,c=us");
        env.put(Context.SECURITY_CREDENTIALS, "secret");
        env.put(Context.SECURITY_AUTHENTICATION, "simple");

        String url = "jdbc:oracle:thin:@localhost:1521/orcl";
        Properties properties = new Properties();
        properties.setProperty("user", "ratha");
        properties.setProperty("password", "ratha");
        try {
            AQjmsFactory.registerConnectionFactory(env, "test_queue_factory", url, properties,
                                                   "queue");
            System.out.println("Connection factory craeted ");

        } catch (Exception e) {
            e.printStackTrace();
          }
    }

// DO lookup

 void get_Factory_from_LDAP() throws Exception {

        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, AQjmsConstants.INIT_CTX_FACTORY);
        // ldapserver is your LDAP host and 389 is your port
        env.put(Context.INITIAL_CONTEXT_FACTORY, AQjmsConstants.INIT_CTX_FACTORY);
        env.put(Context.PROVIDER_URL, "ldap://localhost:10388/");
        env.put(Context.SECURITY_PRINCIPAL, "uid=ratha,ou=Services, o=sgi,c=us");
        env.put(Context.SECURITY_CREDENTIALS, "secret");

        DirContext inictx = new InitialDirContext(env);
        inictx = (DirContext) inictx.lookup("cn=ORCL,cn=OracleContext,ou=Services, o=sgi,c=us");
        // go to the connection factory holder cn=OraclDBConnections
        DirContext connctx = (DirContext) inictx.lookup("cn=oracledbconnections");

        // get connection factory "test_queue_factory"
        QueueConnectionFactory qc_fact = (QueueConnectionFactory) connctx.lookup("cn=ratha");

        System.out.println("Factory look up success " + qc_fact.toString());
        QueueConnection QCon = qc_fact.createQueueConnection();
        System.out.println("Connection created " + QCon.toString());
       DirContext destctxQF = (DirContext) inictx.lookup("cn=OracleDBQueues");
        System.out.println("OracleDBQueues look up success " + destctxQF.toString());
        Queue queue = (Queue) destctxQF.lookup("cn=ratha.test");
        System.out.println("Queue look up success :" + queue.toString());

        Session session = QCon.createQueueSession(true, QueueSession.AUTO_ACKNOWLEDGE);
        QCon.start();
        QueueSender sender = ((QueueSession) session).createSender(queue);
        System.out.println("Sender creation success :" + sender.toString());
    
       String msg = "test";
       TextMessage message = session.createTextMessage(msg);

       sender.send(message);
       // MessageConsumer consumer = session.createConsumer(queue);
       // TextMessage msg2 = (TextMessage) consumer.receive();
       // System.out.println("MESSAGE RECEIVED " + msg2.getText());

}

LDAP: error code 34 - Invalid root DN given : cn=oracledbconnections,null

This issue occurs when we try to connect OracleAQ via  Oracle JMS. To overcome above issue, check whether you have set following property,
    env.put(AQjmsConstants.SERVER_DN, "cn=ORCL,cn=OracleContext,ou=Services, o=sgi,c=us");

The second parameter provides the DN value of "ORCL", which is the third level, labeled cn=orcl, is the database.

 

Thursday, October 6, 2011

Creating partitions in ApacheDS

With ApacheDS as you may know, we can create our  customized partitions in order to keep our data according to  our requirements.
Lets have a look on creating partitions..

Steps
  • As I mentioned in my previous post , install and create a connection for the LDAP server.
  •  Double click on server link. You will see the server.xml's graphical view. From that select 'Partitions' tab

  • Under partitions section you will see default two partitions are listed out
    • System
    • example
  • Click on the 'Add' button. You will see a new partition will be created. Provide ID and suffix. Click on 'Save' button @ toolbar.

  • You can do this @ server.xml by adding new .Go to the ApcheDS installation directory find the server.xml and copy one of the existing "example" partition.
  • Now you  created a new partition called "acme.com". But you can not view the partition at LDAP browser. For that you have to create a new 'context entry' for the newly created partition.
  • Go to LDAP browser,'Root DSE '-->Right click->'New Context entry' .Select 'Create entry from scratch' option.
  • Select 'ObjectClass' as 'Domain' click  'Add' so you will see added object classes at your right pane.

  • Now enter the DN as you provided when you create the partition.
    • eg: dc=acme,dc=com
  • Click 'next' and Finish.You will see the newly created entry at LDAP browser .

  • When you try to make connections to newly created partition , You have to create a user/uid for this partition .

Creating a queuetable @ OracleAQ gives "ORA-01017: invalid username/password" error

If you face such issue[1], when you try to create a 'queuetable' at OracleAQ (Even though you provided all authorizations and authentications correctly), check the following global parameter is set to 'false"


connect / as sysdba
# sqlplus sys/admin@orcl as sysdba;
# ALTER SYSTEM SET GLOBAL_TOPIC_ENABLED = FALSE;


[1]Error

oracle.jms.AQjmsException: ORA-01017: invalid username/password;
logon denied ORA-06512: at "SYS.DBMS_AQADM", line 81
at oracle.jms.AQjmsSession.createQueueTable(AQjmsSession.java:4803)
at oracle.jms.AQjmsSession.createQueueTable(AQjmsSession.java:4778)

Installing and configuring ApacheDS

ApacheDS is an open source project, which provides directory server , which is LDAP v3 compliant. You can download ApcheDS here, which comes with eclipse based LDAP browser + LDAP server. So, you don't need to use extrernal LDAP browsers (eg: JXplorer)  to configure your directory server.

Steps
  • Download , install and start the Apache Directory Studio™ (v1.5.3)
  •  Go to 'File' menu and click 'New'. Select 'ApcheDS' server. Go to 'next' page.
  •  Provide a unique name to identify your LDAP server instance.(eg: ServerA) Click 'Finish'
  • You will see your newly created server @ servers panel.
  •  Double click on ServerA's link.You will see a window which lists all options to configure the server.

  •  At the 'General' tab, you can provide the port numbers for different protocols. Here leave the default port numbers as it is.
    •  LDAP =10389
    • LDAPS=10636
  •  Go to 'servers' panel and click the 'start' button.

  • Now, server instance created. We have to create a connection for that server.(ie:ServerA)
  • Go to 'LDAP' menu and select 'New Connection'
  • Provide 
    • Connection name - Connection A
    • Hostname - localhost
    • Port no -10389 (This is the port number ServerA instance running)

  • Click 'Next'. 
    • Authentication Method - "Simple Authentication"
    • Bind DN - "ou=system,uid=admin" (this is the one by default available partition and the user)
    • Bind password - 'secret' (default  passoword)
  • If you provide all the above parameters correctly , your connection will start successfully. You can see the available partitions at LDAP browser.
That is it for installation and starting the server.


Monday, October 3, 2011

Creating a queue in OracleAQ

Oracle provides database integrated messaging functionality,which is called OracleAQ. 
Oracle JMS (OJMS) is the JMS interface to the Oracle Database Streams Advanced Queuing (AQ) feature.
To work with OracleAQ, we need to install Oracle database server.(V11g)


In this post lets have a look on how we can create a queue programmatically using OJMS libraries and AQ libraries.
For this, specific user should have required authorization to create queues..
  • Connect as 'sys/admin' ;
  • create user ratha identified by ratha;
  • grant create session to ratha;
  • grant connect, resource to ratha;
  • grant aq_administrator_role to ratha  identified by  ratha;
  • grant execute on dbms_aq to  ratha;
  • grant execute on dbms_aqadm to  ratha;
  • exec dbms_aqadm.grant_system_privilege('ENQUEUE_ANY','ratha');
  • exec dbms_aqadm.grant_system_privilege('DEQUEUE_ANY','ratha'); 
  • grant execute on sys.aq$_jms_text_message to ratha; 
  • Connect as 'ratha/ratha'
After providing required authorization for the new user 'ratha' (password : ratha) you could be able to login as user 'ratha' and able to create table/queue etc..

With the particular user information, now lets try to create a queue in oracle database.

import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import oracle.AQ.AQQueueTable;
import oracle.AQ.AQQueueTableProperty;
import oracle.jms.AQjmsDestination;
import oracle.jms.AQjmsDestinationProperty;
import oracle.jms.AQjmsFactory;
import oracle.jms.AQjmsSession;

public class OracleAQClient {

public static QueueConnection getConnection() {

  String hostname = "localhost";
  String oracle_sid = "orcl";
  int portno = 1521;
  String userName = "ratha";
  String password = "ratha";
  String driver = "thin";
  QueueConnectionFactory QFac = null;
  QueueConnection QCon = null;
  try {
   // get connection factory , not going through JNDI here
   QFac = AQjmsFactory.getQueueConnectionFactory(hostname, oracle_sid, 
portno,driver);
   // create connection
   QCon = QFac.createQueueConnection(userName, password);
   } catch (Exception e) {
   e.printStackTrace();
  }
  return QCon;
 }

 public static void createQueue(Session session, String user,
String qTable, String queueName) {
  try {
   /* Create Queue Tables */
   System.out.println("Creating Queue Table...");

   AQQueueTableProperty qt_prop;
   AQQueueTable q_table = null;
   AQjmsDestinationProperty dest_prop;
   Queue queue = null;
   qt_prop = new AQQueueTableProperty("SYS.AQ$_JMS_TEXT_MESSAGE");

   /* create a queue table *///
   // /* Drop the queue table if already exists */
   // try{
   // q_table = ((AQjmsSession) session).getQueueTable(user, qTable);
   // q_table.drop(true);
   // System.out.println("Droped older queuetable...");
   // }
   // catch(Exception e){
   // e.printStackTrace();
   // return;
   // }

   q_table = ((AQjmsSession) session).createQueueTable(user, qTable,
qt_prop);
   System.out.println("Qtable created");
   dest_prop = new AQjmsDestinationProperty();
   /* create a queue */
   queue = ((AQjmsSession) session).createQueue(q_table, queueName, 
dest_prop);
   System.out.println("Queue created");
   /* start the queue */
   ((AQjmsDestination) queue).start(session, true, true);
  } catch (Exception e) {
   e.printStackTrace();
   return;
  }
 }

 public static void sendMessage(String user, String queueName) {

  try {
   QueueConnection QCon = getConnection();  
   Session session = QCon.createQueueSession(false,
Session.CLIENT_ACKNOWLEDGE);
   QCon.start();
   Queue queue = ((AQjmsSession) session).getQueue(user, queueName);
   MessageProducer producer = session.createProducer(queue);
   TextMessage tMsg = session.createTextMessage("test");
   producer.send(tMsg);
   System.out.println("Sent message = " + tMsg.getText());

   session.close();
   producer.close();
   QCon.close();

  } catch (JMSException e) {
   e.printStackTrace();
   return;
  }
 }

 public static void browseMessage(String user, String queueName) {
  Queue queue;
  try {
   QueueConnection QCon = getConnection();  
   Session session = QCon.createQueueSession(false,
Session.CLIENT_ACKNOWLEDGE);
  
   QCon.start();
   queue = ((AQjmsSession) session).getQueue(user, queueName);
   QueueBrowser browser = session.createBrowser(queue);
   Enumeration enu = browser.getEnumeration();
   List list = new ArrayList();  
   while (enu.hasMoreElements()) {
    TextMessage message = (TextMessage) enu.nextElement();   
    list.add(message.getText());
   }
   for (int i = 0; i < list.size(); i++) {
    System.out.println("Browsed msg " + list.get(i));
   }
   browser.close();
   session.close();
   QCon.close();

  } catch (JMSException e) {
   e.printStackTrace();
  }

 }

 public static void consumeMessage(String user, String queueName) {  
  Queue queue;
  try {
   QueueConnection QCon = getConnection();  
   Session session = QCon.createQueueSession(false,
Session.CLIENT_ACKNOWLEDGE);
   QCon.start();
   queue = ((AQjmsSession) session).getQueue(user, queueName);
   MessageConsumer consumer = session.createConsumer(queue);
   TextMessage msg = (TextMessage) consumer.receive();
   System.out.println("MESSAGE RECEIVED " + msg.getText());

   consumer.close();
   session.close();
   QCon.close();
  } catch (JMSException e) {  
   e.printStackTrace();
  }
 }

 public static void main(String args[]) {
  String userName = "ratha";
  String queue = "test";
  // createQueue( userName, qTable, queue);
  sendMessage(userName, queue);
  browseMessage(userName, queue);
  // consumeMessage(userName, queue);
 }
}

You might need following jars in your class-path in order to run above java client
  • ojdbc6.jar (can be found at db_home\jdbc\lib)
  • jta.jar (can be found at db_home\jdbc\jlib)
  • jmscommon.jar (can be found at db_home\RDBMS\jlib folder)
  • aqapi.jar(can be found at db_home\RDBMS\jlib folder)


Tuesday, July 26, 2011

Queue interchanges first and second element when use poll with browser

The issue I faced is, when i used QueueBrowser with  poll, Browser browsed elements in order but consumer started to remove from 2nd element. My scenario was simple,
First browser, then poll..

Our common Message Store implementation is written in a way to support all JMS providers ande code works fine with the most of the JMS providers(Qpid,ActiveMQ 5.3.XX) but didn't work with ActiveMQ 5.4.2/5.5 version..


public void peek() throws Exception {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost"); Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = (ActiveMQDestination) session.createQueue("TEST.FOO");
QueueBrowser browser = session.createBrowser((Queue) destination);

Enumeration enumeration = browser.getEnumeration();

if (enumeration.hasMoreElements()) {
Object msg = enumeration.nextElement();
TextMessage m = (TextMessage) msg;
System.out.println("Browsed msg " + m.getText());

}

browser.close();
session.close();
connection.close();

}

public void poll() throws Exception {

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory( "vm://localhost");
Connection connection = connectionFactory.createConnection();
connection.start();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destination = (ActiveMQDestination) session.createQueue("TEST.FOO");

MessageConsumer consumer = session.createConsumer(destination);

TextMessage m = (TextMessage) consumer.receive(1000);
if (m != null) {
System.out.println(" Polled Messg" + m.getText());
}

consumer.close();
session.close();
connection.close();
}


I tested with above test code and it works fine with ActiveMQ V5.4.2..Not only works in the application..
To overcome the issue, we did an extra iteration wherever we use the Queuebrowser and it solved the issue..


@ the peek() call we added iteration,


  if (enumeration.hasMoreElements()) {
   Object msg = enumeration.nextElement();
   TextMessage m = (TextMessage) msg;
             while(enumeration.hasMoreElements()){
                           enumeration.nextElement();
                        }

  }

Tuesday, July 19, 2011

Configuring WSO2ESB 4.0.0 with QPid

This is how we need to  configure ESB with Qpid,

1) Edit axis2.xml file(ESB_HOME/rpository/conf/axis2.xml) like;

Under transport In section;
<!--Transport Ins -->
<!--Uncomment this and configure as appropriate for JMS transport support with Apache Qpid -->

<transportReceiver name="jms" class="org.apache.axis2.transport.jms.
JMSListener">

 <parameter name="myTopicConnectionFactory" locked="false">
   <parameter name="java.naming.factory.initial" locked="false">
    org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter> 
    repository/conf/jndi.properties</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>
 <parameter name="myQueueConnectionFactory" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">
    org.apache.qpid.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>

</transportReceiver>

Under Transport Outs section;


<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/>

2) At jndi.properties file(ESB_HOME/repository/conf/jndi.properties);
Add following lines to create connectionfactory, queue , topic etc..

connectionfactory.TopicConnectionFactory = amqp://admin:admin@carbon/carbon?brokerlist='tcp://localhost:5672'
connectionfactory.QueueConnectionFactory = amqp://admin:admin@carbon/carbon?brokerlist='tcp://localhost:5672'
queue.MyQueue = example.MyQueue
queue.DLCStore = example.DLCStore


3) Your MessageStore configuartaion should have minimum three parameters;

<messageStore xmlns="http://ws.apache.org/ns/synapse" class="org.wso2.carbon.message.store.persistence.jms.JMSMessageStore" name="testMsgStore">
    <parameter name="java.naming.factory.initial">org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter>
    <parameter name="java.naming.provider.url">repository/conf/jndi.properties</parameter>
    <parameter name="store.jms.destination">MyQueue</parameter>
</messageStore>



I have written a KB about configuring Qpid with WSO2 ESB,which has been published @ WSO2 OT..

Sunday, March 27, 2011

How to avoid java " Class Cast exception occurs @ ArrayList,toArray()"

Very simple way to avoid class cast exception which occurs at the run time when we use "ArrayList.toArray()" function is,
Object[] objArray = mylist.toArray(new Entry[mylist.size()]);
 Entry[] entry = (Entry[]) objArray;


Here 'Entry' is a class object ..