Tuesday, July 29, 2014

Configure WebSphere MQ with default JMS provider.

The default JMS provider is bundled with the WebSphere Application server installation, We can use the default JMS provider rather than using external JMS providers (like ActiveMQ ) for our message oriented middle-ware solutions.


The default JMS provider can be used with the help of Service Integration Bus (SIB) feature of WebSphere, so your Enterprise Application will use Connection factory to connect to the SIB and then get the connected to the destination queue.

Steps below is using WebSphere 8.5 and can be used with other version around this.

Step 1: Create SIB

  •           Click on the Buses from the Service Integration  and add new Bus 
  •           As shown below give your SIB name and un-select “bus security”
  •           Continue on finishing the wizard and finally save configuration.

Step 2: Attache your server (ex: server1) to the newly created BUS

  •           Click on new created BUS and click “Bus Member” to add your server to this bus.


  • Click on Add button to add your server to the SIB and select File Store as your persistence store of messages and Finish the wizard with other default settings.


Step 3: Create Queue Connection Factory


  • Click on Queue Connection factory under Resource from left pane on admin console and continue with creating similar to connection factory.



  •           Add new connection factory using “Default JMS Provider” 



  •           Provide your connection factory name and JNDI name and select your bus from the drop down list





Step 4: Create destination queue

  • Select the Queue link from the Resources pane on left pane on Admin console.
  • Click “New”  to start creating queue and select “Default messaging provider”
  • Give your test queue name and JNDI name as shown below and select “Create Service Integration Bus destination” from the Queue name selection to proceed with creating destination queue. It will prompt you with wizard to create the destination queue and give Identifier as “TestQD” and select other default settings and finish. So now your queue JNDI of “jms/TestQ” will be mapped to the actual destination of “TestQD” queue. Also make sure you save the configurations at the end.



Step 5: Use your queue with sample JMS sender and listener.

You are ready with the connection factory and destination Queue with below JNDI names,so write your own sample to push message to the queue and listener to read it.

JNDI Name of Connection factory: jms/TestQCF

JNDI name of the queue:jms/TestQ


Wednesday, June 25, 2014

Sharing WSO2 Governance Registry Lifecycle across Multiple Tenants

The goal of multitenancy is to maximize the resource sharing across multiple users while hiding the fact that these users are on the same server and ensuring optimal performance. It is possible to register tenants in Governance Registry as well, allowing tenants to maintain separate registry domains to their institutions.

However, there is no simple tool or wizard to share your Lifecyle created in super tenant across other tenants, so below steps will help you to do this part using Greg Admin console login.

Step 1: Create a life cycle in the super tenant


- Login to Greg Admin console
- Go to  : Home > Extensions > Configure > Lifecycles
- Click on "Add new Life Cycle" and create a life cycle , let says life cycle name is "SampleLifeCycleTest"

Step 2:  Download created life cycle


- Now, go to the registry path
Home > Resources > Browse

/_system/config/repository/components/org.wso2.carbon.governance/lifecycles

- Click on a life cycle required and download into a folder.
- ex: /home/work/SampleLifeCycleTest

Step 3: Login to new tenant and upload the life cycle


- If you have not created the new tenat still, you can refer below on how to add tenant
https://docs.wso2.org/display/Governance460/Multitenancy

- Now log-out from the super tenant and login to the new tenant you created already

- Go to the registry path
/_system/config/repository/components/org.wso2.carbon.governance/lifecycles

- Click on add resource
- Choose the earlier downloaded lifecycle file (/home/work/SampleLifeCycleTest)
- Enter Media Type is given as application/xml
- Click add

Step 4:  Verify the life cycle added


- Now go and see your new life cycle will be in your tenant
Home > Extensions > Configure > Lifecycles


Step 5: Use your life cycle in a service

Since this is added from registry , it will take few minutes to refresh cache and use within a service, also you can restart the server (or re-login to the tenant) and use this lifecyle inside your services from Greg.


References:
https://docs.wso2.org/display/Governance460/Lifecycles
https://docs.wso2.org/display/Governance460/Multitenancy



Monday, June 23, 2014

WSO2 ESB : Mail sending with HTML complex tag supports


You can use WSO2 ESB to send mails and receive mails with polling using Mail Transport facility as explained in https://docs.wso2.org/display/ESB481/MailTo+Transport


Sending Simple HTML email from ESB:

Sending a simple email body with following html content can be done easily using following builder and formatter in axis2 configuration for given content-type (text/html).

axis2.xml changes:

 <messageBuilder contentType="text/html"   
             class="org.apache.axis2.builder.ApplicationXMLBuilder"/>  
 <messageFormatter contentType="text/html"   
              class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>   

Sample HTML mail:

 <html>   
      <head>   
       <meta http-equiv="content-type" content="text/html" />   
      </head>   
      <body>   
           <h2 style='color:green'>Testing Simple mail</h2><p>Simple mail details..</p>   
      </body>   
 </html>  



However if we include special html tags to the email content like 
 <DOCTYPE> , 
<!-- Comment --> 
<?xml - xml declaration tags for rich content validating and rendering purpose , you cannot use above mentioned XML builder and formatter and you will get errors while passing the mail message through ESB as below.

 ERROR {org.apache.axis2.transport.mail.MailTransportListener} - Failed to process message {org.apache.axis2.transport.mail.MailTransportListener}   
 org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,122]   
 Message: DOCTYPE is not allowed   
     at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296)   
     at org.apache.axiom.om.impl.llom.OMDocumentImpl.getOMDocumentElement(OMDocumentImpl.java:109)   
     at org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:570)   
     at org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:566)   
     at org.apache.axis2.builder.ApplicationXMLBuilder.processDocument(ApplicationXMLBuilder.java:81)   
     at org.apache.axis2.transport.TransportUtils.createDocumentElement(TransportUtils.java:180)   
     at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:146)   
     at org.apache.axis2.transport.mail.MailTransportListener.processMail(MailTransportListener.java:501)   
     at org.apache.axis2.transport.mail.MailTransportListener.access$000(MailTransportListener.java:61)   
     at org.apache.axis2.transport.mail.MailTransportListener$MailProcessor.run(MailTransportListener.java:331)   
     at org.apache.axis2.transport.mail.MailTransportListener.processMail(MailTransportListener.java:295)   
     at org.apache.axis2.transport.mail.MailTransportListener.checkMail(MailTransportListener.java:199)   
     at org.apache.axis2.transport.mail.MailTransportListener.poll(MailTransportListener.java:80)   
     at org.apache.axis2.transport.mail.MailTransportListener.poll(MailTransportListener.java:61)   
     at org.apache.axis2.transport.base.AbstractPollingTransportListener$1$1.run(AbstractPollingTransportListener.java:67)   
     at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)   
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)   
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)   
     at java.lang.Thread.run(Thread.java:722)   


How to overcome this issue :


You can use BinaryRelayBuilder and ExpandingMessageFormatter to overcome this error and send text/html content-type mails through ESB as explained in below steps.

Step1: Configure mailto transport in ESB

- Download and install the ESB latest version ( http://wso2.com/products/enterprise-service-bus/ )

- Uncomment the mail TransportSender and TransportReceiver from the <ESB_HOME>/repository/conf/axis2/axis2.xml
-Configure with your mail server credentials as required.


 <transportSender name="mailto">  
    <parameter name="mail.smtp.host">smtp.gmail.com</parameter>  
    <parameter name="mail.smtp.port">587</parameter>  
    <parameter name="mail.smtp.starttls.enable">true</parameter>  
    <parameter name="mail.smtp.auth">true</parameter>  
    <parameter name="mail.smtp.user">synapse.demo.0</parameter>  
    <parameter name="mail.smtp.password">mailpassword</parameter>  
    <parameter name="mail.smtp.from">synapse.demo.0@gmail.com</parameter>  
 </transportSender>  


 <transportReceiver name="mailto">  
 </transportReceiver>  



Step 2: Add builder and formatter for content-type “text/html”

 <messageBuilder contentType="text/html"   
             class="org.wso2.carbon.relay.BinaryRelayBuilder"/>  
 <messageFormatter contentType="text/html"   
             class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>  


Step 3: Add the mail sending proxy in your ESB.

Please note that you need to force axis2 mail transport sender to use content-type based formatter specially formatting the mail message with with special html tags mentioned previously.

 <property name="FORCE_CONTENT_TYPE_BASED_FORMATTER" value="true" scope="axis2"/>  

Note: Please note, you need to have latest version of ESB or the patch https://wso2.org/jira/browse/CARBON-14796 applied to ESB 4.8.1 version to effect this property

If you have not specified the above parameter with value “true” , ESB will select default formatter related to the BinaryRelayBuilder which is org.apache.axis2.format.BinaryFormatter as default to handle binary content regardless you had specified the formatter in axis2 configuration file.


1:  <?xml version="1.0" encoding="UTF-8"?>   
2:  <proxy xmlns="http://ws.apache.org/ns/synapse"   
3:      name="JKMailTestProxy"   
4:      transports="https http"   
5:      startOnLoad="true"   
6:      trace="disable">   
7:    <description/>   
8:    <target>   
9:     <inSequence>   
10:       <property name="Subject" value="Testing rich text mail" scope="transport"/>   
11:       <property name="FORCE_CONTENT_TYPE_BASED_FORMATTER"   
12:            value="true"   
13:            scope="axis2"/>   
14:       <property name="OUT_ONLY" value="true"/>   
15:       <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>   
16:       <send>   
17:        <endpoint >   
18:          <address uri="mailto:synapse.demo.1@gmail.com"/>   
19:        </endpoint>   
20:       </send>   
21:       <drop/>   
22:     </inSequence>   
23:    </target>   
24:  </proxy>  



Step 4: Send mail with content including rich text and verify

Lets call proxy using SoapUI tool or curl commands.

Content-type :text/html

Content in  SOAP Body: 

 <?xml version="1.0" encoding="UTF-8"?>   
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">   
 <!-- Testing mail with rich content -->  
 <html>   
      <head>   
       <meta http-equiv="content-type" content="text/html" />   
      </head>   
      <body>   
           <h2 style='color:green'>Testing Simple mail</h2><p>Simple mail details..</p>   
      </body>   
 </html>  



The address  synapse.demo.1@gmail.com   will receive a mail from  synapse.demo.0@gmail.com






Wednesday, April 2, 2014

WSO2 ESB: File processing using VFS transport and mediation inside a sequence

VFS transport feature in ESB can be used to process the files in the system periodically and take actions as configured. Basically you can use this to transfer file from one location to other with the mediation in between.
Below example shows how to process simple csv flat file in a folder and process each record inside ESB proxy service and forward for further processing into a separate sequence.
We will be using smooks mediator to read csv records from the file and load those into the proxy payload as xml records.

Step 1: Download and install WSO2 ESB




Step 2: Enable VFS transport on ESB and enable JMS transport.

  • Uncomment the below two lines from /<WSO2_ESB>/repository/conf/axis2/axis2.xml


<transportSender name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportSender"/>
<transportReceiver name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportListener"/>


Step 3: Add local entry to refer smooks configuration file

  • Go to the WSO2 ESB Management console ( https://localhost:9443/carbon )
  • Select “Local Entries” from the left panel and add new “Source URL Entry” with below values
    • Name : smook_config
    • URL : file:repository/resources/smooks/smooks-config-mapping.xml
  • Also add copy smook-config-mapping.xml file to the <WSO2_ESB>/repository/resources/smooks/ folder

smook-config-mapping.xml
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.0.xsd">
<!--Configure the CSVParser to parse the message into a stream of SAX events. -->
<resource-config selector="org.xml.sax.driver">
<resource>org.milyn.csv.CSVParser</resource>
<param name="fields" type="string-list">firstname,lastname,gender,age,country</param>
</resource-config>

</smooks-resource-list>


Step 4: Create Proxy as VFS Listener and Sequence to process each record


Add Sequence to used by proxy to forward the each record:

<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="RecProcessSequence">
<log level="full">
<property name="==Processing record =====" value="=="/>
</log>
</sequence>

Add the Proxy :


This Listner proxy will read the files from the input path and load into the proxy payload and iterate each record and call sequence (RecProcessSequence) to process each record further.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TestSmookRecVFS"
transports="vfs"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<smooks config-key="smook_config">
<input type="text"/>
<output type="xml"/>
</smooks>
<iterate xmlns:ns2="http://org.apache.synapse/xsd"
xmlns:ns="http://org.apache.synapse/xsd"
xmlns:sec="http://secservice.samples.esb.wso2.org"
expression="//csv-set/csv-record">
<target>
<sequence>
<clone>
<target sequence="RecProcessSequence"/>
</clone>
</sequence>
</target>
</iterate>
</inSequence>
</target>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.PollInterval">10</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file:///home/jayalal/Work/SmookRes/out</parameter>
<parameter name="transport.vfs.FileURI">file:///home/jayalal/Work//SmookRes/in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file:///home/jayalal/Work/ /SmookRes/failed</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.txt</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>


Step 5: Testing and Verify

Copy the input.txt file into the “transport.vfs.FileURI” folder.
name1,lastname1,Male,30,country1
name2,lastname2,Female,40,country2
name3,lastname3,Female,40,country3
name4,lastname4,Female,30,country4
name5,lastname5,Female,40,country5


You will see the ESB logs will print the messages process by ESB.
[2014-01-29 15:11:41,922] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:de01ae68-6afc-4539-9c0e-f820fa181c19, Direction: request, ==Processing record ===== = ==, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><csv-record number="1"><firstname>name1</firstname><lastname>lastname1</lastname><gender>Male</gender><age>30</age><country>SriLanka</country></csv-record></soapenv:Body></soapenv:Envelope>
[2014-01-29 15:11:41,924] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:b436bd8d-a30b-40e1-83c2-00f109b793a5, Direction: request, ==Processing record ===== = ==, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><csv-record number="2"><firstname>name2</firstname><lastname>lastname2</lastname><gender>Female</gender><age>40</age><country>SriLanka</country></csv-record></soapenv:Body></soapenv:Envelope>


More References:















WSO2 ESB : Huge File Processing inside VFS Listner using Smooks Mediator

You can use WSO2 ESB for processing large files (in GBs ) using VFS transport while Smooks mediator can be used inside VFS listener to read records from the files and route it to a destination queue , database or flat file for further processing rather than loading full file content into the proxy payload.


Further to this concept, below example will show you how to process large file for reading millions of CSV records and route it to the JMS Queue for further processing. The steps will help you to directly copy and paste the files into the specific folders for deploying the services , however you can create same configuration from ESB console rather than directly copying to the deployment folders.

Step 1: Download and install WSO2 ESB


Step 2: Enable VFS transport on ESB and enable JMS transport.

  • Uncomment the below two lines from /<WSO2_ESB>/repository/conf/axis2/axis2.xml


<transportSender name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportSender"/>
<transportReceiver name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportListener"/>



Step 3: Add the smooks configuration

  • Copy smook-config-mapping.xml file to the <WSO2_ESB>/repository/resources/smooks/
smook-config-mapping.xml

<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.1.xsd"
xmlns:jms="http://www.milyn.org/xsd/smooks/jms-routing-1.2.xsd"
xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd">

<params>
<param name="stream.filter.type">SAX</param>
<param name="stream.filter.readerPoolSize">100</param>
</params>

<csv:reader fields="firstname,lastname,gender,age,country" separator="," quote="'" skipLines="1" />

<resource-config selector="csv-record">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>

<ftl:freemarker applyOnElement="csv-record">
<ftl:template>/repository/resources/smooks/csv_record_as_xml.ftl</ftl:template>
<ftl:use>
<ftl:bindTo id="csv_record_as_xml"/>
</ftl:use>
</ftl:freemarker>

<jms:router routeOnElement="csv-record" beanId="csv_record_as_xml" destination="TestQueue">
<jms:message>
<!-- Need to use special FreeMarker variable ".vars" -->
<jms:correlationIdPattern>${.vars["csv-record"].age}</jms:correlationIdPattern>
</jms:message>
<jms:jndi properties="/repository/resources/smooks/activemq.sr.jndi.properties" />
<jms:highWaterMark mark="10000000"/>
</jms:router>
</smooks-resource-list>



  • To add the config key in local entries , please copy smook_config.xml <WSO2-ESB>/repository/deployment/server/synapse-configs/default/local-entries

smook_config.xml

<?xml version="1.0" encoding="UTF-8"?>
<localEntry xmlns="http://ws.apache.org/ns/synapse"
key="smook_config"
src="file:repository/resources/smooks/smooks-config-mapping.xml">
<description/>
</localEntry>




Step 4: Add JMS configuration and FTL template which used by smook mediator to split the message and make out put format.

  • Add the 2 files called activemq.sr.jndi.properties and csv_record_as_xml.ftl into <WSO2-ESB>/repository/resources/smooks.

activemq.sr.jndi.properties

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url = tcp://localhost:61616
queue.TestQueue = TestQueue



csv_record_as_xml.ftl

<#assign csvrec = .vars["csv-record"]> <#-- special assignment because order-item has a hyphen -->
<Customer>
<firstname>${csvrec.firstname}</firstname>
<lastname>${csvrec.lastname}</lastname>
<gender>${csvrec.gender}</gender>
<age>${csvrec.age}</age>
<country>${csvrec.country}</country>
</Customer>




Step 5: Create your VFS listener proxy to read the file and pass it to the smooks mediator

  • Now copy the TestSmookRecVFS.xml proxy into the folder      <WSO2_ESB>/repository/deployment/server/synapse-configs/default/proxy-services
TestSmookRecVFS.xml
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="TestSmookRecVFS"
transports="vfs"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<log>
<property name="JK*********" value="INSIDE VFS******"/>
</log>
<property name="DISABLE_SMOOKS_RESULT_PAYLOAD" value="true"/>
<smooks config-key="smook_config">
<input type="text"/>
<output type="xml"/>
</smooks>
</inSequence>
</target>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.PollInterval">10</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file:///home/jayalal/Work/SmookRes/out</parameter>
<parameter name="transport.vfs.FileURI">file:///home/jayalal/Work/SmookRes/in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file:///home/jayalal/Work/SmookRes/failed</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.txt</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>




Step 6 : Testing and Verify


Put your flat file containing CSV records into the “ transport.vfs.FileURI” location. You will notice VFS lister will pick the file and transfer record into the JMS queue.


Input.txt

name1,lastname1,Male,30,country1
name2,lastname2,Female,40,country2
name3,lastname3,Female,40,country3
name4,lastname4,Female,30,country4



Please note, active MQ will not store message more than 200 in default, so better you have reading listener to read from other end (as explain in next step) , so you can verify all of your millions of records successfully queued into the JMS queue.

Step 7: Verify with JMS Listener


You can read messages coming to the “ TestQueue” by using JMS listener proxy inside the ESB and further process the message.

Add the JMS Listner to process the messages from the queue;
- Put the proxy service file called JKTestJMSListner.xml into <WSO2_ESB>/repository/deployment/server/synapse-configs/default/proxy-services


JKTestJMSListner.xml


<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="JKTestJMSListner"
transports="jms"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<log/>
</inSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="transport.jms.ConcurrentConsumers">1</parameter>
<parameter name="transport.jms.ConnectionFactory">myQueueConnectionFactory</parameter>
<parameter name="transport.jms.SessionTransacted">false</parameter>
<parameter name="transport.jms.Destination">TestQueue</parameter>
<parameter name="transport.jms.CacheLevel">consumer</parameter>
<parameter name="transport.jms.MaxConcurrentConsumers">1</parameter>
</proxy>




NOTES:

We have added below property to avoid the large file content into the payload since we already have consumed the file content and routed into the JMS queue.

<property name="DISABLE_SMOOKS_RESULT_PAYLOAD" value="true"/>


If this parameter is set to false (default value is false). Your file content will be loaded into the message context and may give out of memory error as below , this property will be available in ESB 4.9 onward or you have patch for fixes (https://wso2.org/jira/browse/ESBJAVA-3031) for your old ESB version.

You will be getting below exception if you have not included disable smook flag and your JVM memory is out.

java.lang.OutOfMemoryError: Java heap space
Dumping heap to /home/jayalal/Software/wso2esb-4.7.0/repository/logs/heap-dump.hprof ...
Heap dump file created [2015812579 bytes in 11.531 secs]
[2014-03-13 06:23:42,973] ERROR - NativeWorkerPool Uncaught exception
java.lang.OutOfMemoryError: Java heap space
at org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory.createOMText(OMLinkedListImplFactory.java:192)
at org.apache.axiom.om.impl.builder.StAXBuilder.createOMText(StAXBuilder.java:294)
at org.apache.axiom.om.impl.builder.StAXBuilder.createOMText(StAXBuilder.java:250)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:252)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.build(OMSerializableImpl.java:78)
at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:722)
at org.apache.axiom.om.impl.llom.OMElementImpl.detach(OMElementImpl.java:700)
at org.apache.axiom.om.impl.llom.OMNodeImpl.setParent(OMNodeImpl.java:105)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:296)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:212)
at org.apache.axiom.soap.impl.llom.SOAPBodyImpl.addChild(SOAPBodyImpl.java:231)
at org.wso2.carbon.mediator.transform.Output.setXMLPayload(Output.java:228)
at org.wso2.carbon.mediator.transform.Output.process(Output.java:95)
at org.wso2.carbon.mediator.transform.SmooksMediator.mediate(SmooksMediator.java:125)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:71)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:114)
at org.apache.synapse.core.axis2.ProxyServiceMessageReceiver.receive(ProxyServiceMessageReceiver.java:162)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.axis2.transport.base.AbstractTransportListener.handleIncomingMessage(AbstractTransportListener.java:328)
at org.apache.synapse.transport.vfs.VFSTransportListener.processFile(VFSTransportListener.java:590)
at org.apache.synapse.transport.vfs.VFSTransportListener.scanFileOrDirectory(VFSTransportListener.java:324)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:158)
at org.apache.synapse.transport.vfs.VFSTransportListener.poll(VFSTransportListener.java:107)
at org.apache.axis2.transport.base.AbstractPollingTransportListener$1$1.run(AbstractPollingTransportListener.java:67)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)

Wednesday, February 12, 2014

Deploy and Enable Rampart in Axis2 ( Tomcat)


Please follow below steps to deploy rampart module and enable rampart for axis services which is deployed in Tomcat. Also you can follow same for deploying axis2 standalone or in another application server.

Step 1: Install and configure  axis2 in tomcat

Deploy axis2 in tomcat as explained here ( http://jayalalk.blogspot.com/2014/01/writing-axis2-services-and-deploying-in.html ). you can ignore this if you have already tomcat with axis2 module.

Step 2: Download the rampart module

Download the rampart latest binaries from http://axis.apache.org/axis2/java/rampart/download.html

Step 3: Extract the rampart distribution to a folder and copy modules and jar files


- Copy the  rahas-x.x.x.mar and rampart-x.x.x.mar  files from module directory to the TOMCAT_HOME/webapps/axis2/WEB-INF/modules
- Copy all the jars from lib folder to the TOMCAT_HOME/axis2/WEB-INF/lib

Step 4: Enable the rampart in axis2


- Add     <module ref="rampart"/> in  TOMCAT_HOME/webapps/axis2/WEB-INF/conf/axis2.xml to enable rampart for all services.
- If you want to enable rampart only for given service then you can edit services.xml and add <module ref="rampart"/>

Step 5: Verify the rampart enabled

- Login to adminstrative console  (http://localhost:8080/axis2/axis2-admin/ )
- Default user name password ( admin/axis2)
- Verify the modules engagement
System components --> Available Modules
System components --> Globally Engaged Modules

Sunday, January 12, 2014

Writing Axis2 Services and deploying in Tomcat

There are three different ways which we can write Axis2 services (Web service  )  and can be deployed in Axis2 Server itself or in a web container like Tomcat.

Different ways of deploying services


  1. As simple POJO class in ..\webapps\axis2\WEB-INF\pojo\HelloWorld.class
  2. As JAR bundle  in ..\webapps\axis2\WEB-INF\pojo\myservice.jar
  3. As a service archive in  ..\webapps\axis2\WEB-INF\services\myservice.aar

We will focus on deploying service as AAR archive, which is best out of 3 deployment types mentioned above.


Getting Ready:

- Download and install Java (Minimum version is JDK1.5). Set the JAVA_HOME environment .
- Install latest version of  Tomcat in your environment ( http://tomcat.apache.org), and verify working properly. ( Sample code on this blog was test with Tomcat 7 as it was the latest stable version)

Download and install Axis2 module in tomcat


1. Download Axis2 WAR Distribution from below location. ( Version 1.6.2  was the latest at this time )

2. Deploy the Axis2 War into tomcat as a web application

- Unzip the axis2-1.6.2-war.zip
- You will get axis2.war file , then unzip this again. you will get axis2 folder containing axis2 deployable web app.
- Now copy the "axis2" folder into <TOMCAT_HOME>/webapps

3. Now start the Tomcat if it is down already, and verify the axis2 default services are running.

- Check available services in axis2 module  http://localhost:8080/axis2/services/listServices
- You will notice the getVersion application is running.
- Verify the webservice is running properly by invoking http://localhost:8080/axis2/services/Version/getVersion
You will get the axis2 version details in your screen  :) , you have verify your web service with REST style

If you need to verify this as Web-Service call using SOAP UI or Java client you can get WSDL with from http://localhost:8080/axis2/services/Version?wsdl

Writing our sample service

Lets write our own sample Web-Service using simple button up method ,where we have not even required to write any WSDL rather just know the java methods/operations needs to be exposed.

1. Writing service class

We will write simple POJO class which we are going to expose as web-service through Axis2 services, and simple supportive class to help on writing our main service class.

Our main service class (CountryService.java)  will expose its public methods as axis2 web services.



package com.jk.axis2.ws;

public class CountryService {
      
       public Country getCountryDetails(String countryCode) {
             
              System.out.println("countryCode =" + countryCode);
              Country country = null;

              if (countryCode != null) {
                     if (countryCode.equalsIgnoreCase("SL")) {
                           country = new Country("Sri Lanka");
                           country.setCountryCode(countryCode);
                           country.setCity("Colombo");
                           return country;
                     } else if (countryCode.equalsIgnoreCase("FR")) {
                           country = new Country("France");
                           country.setCountryCode(countryCode);
                           country.setCity("Paris");
                           return country;
                     }
              }

              return new Country("NotDefined");
       }
            
       public String getServiceVersion(){
              return "This is initial version 1.0";
       }
      
       public String testEcho(String name){
              return "Testing echo with " + name ;
       }
}





Support Country bean  to provide services through CountryService.


package com.jk.axis2.ws;

public class Country {

       String countryCode =null;
       String city=null;
       String name =null;
      
       public Country(){
             
       }
      
       public Country(String name){
              this.name=name;
       }
      
       public String getCountryCode() {
              return countryCode;
       }
       public void setCountryCode(String countryCode) {
              this.countryCode = countryCode;
       }
       public String getCity() {
              return city;
       }
       public void setCity(String city) {
              this.city = city;
       }
       public String getName() {
              return name;
       }
       public void setName(String name) {
              this.name = name;
       }
                    
}




2. Writing  deployment configuration ( services.xml )

To deploy your service archive , you need to have deployment descriptor inside service archive  which tells deployment module to deploy your service as axis2 service.

Basically you can have one or many services inside one single archive file , and can be listed around <ServiceGroup> tag. In this sample we will have only one service inside our service archive.

Our sample services.xml file content.

<serviceGroup>
<service name="CountryService" scope="application">
<messageReceivers>
                                <messageReceiver mep="http://www.w3.org/ns/wsdl/in-only"
                                                                class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
                                <messageReceiver mep="http://www.w3.org/ns/wsdl/in-out"
                                                                class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
<parameter locked="false" name="ServiceClass">com.jk.axis2.ws.CountryService</parameter>
</service>
</serviceGroup>


We can define our message receivers inside services.xml  for  each operation separately or as a default for all the services inside services.xml.  We have defined message receivers for all services as .

you can overwrite this as you wish by simply adding messages receiver for specific operation in services.xml as below.

<service>
...
<operation name="testEcho">
<messageReceiver class="org.apache.axis2.receivers. RawXMLINOutMessageReceiver"/> </operation>
</service>


Deploy the sample CountryService.aar  in Axis2



1. Create your service archive file

-Create simple ZIP file and rename as "CountryService.aar"
-Content will be as below




2. Now copy the  CountryService.aar in to the <TOMCAT_HOME>/webapps/axis2/WEB-INF/services   directory

Now your WebService is ready to access.
You will see the CountryService is deployed already.

Try calling service in REST style.

If you need to access as SOAP webservice ,use the WSDL from the path.