Monday, July 25, 2016

[WSO2][ESB][JMS] Getting error with IBM MQ jars

Environment: ESB 5.0.0
                       IBM MQ version 8
                       Java 1.8

Precondition: ESB should contain suitable jars of IBM MQ

Situation: Going to start ESB server and getting the error

Error:

Caused by: java.lang.ClassNotFoundException: javax.jms.JMSRuntimeException cannot be found by com.ibm.mq.allclient_1.0.0

Solution:

Remove following line from <ESB_Home>\repository\conf\etc\launch.ini.

  • javax.jms,\

Friday, July 22, 2016

[WSO2][ESB] Converting SOAP response to JSON and missing a part

Environment: ESB 4.9.0
                         Java 1.8.0
             
Preconditions: Create a proxy which will convert SOAP response into JSON format (within the out sequence)

Sample out sequence:

<outSequence xmlns="http://ws.apache.org/ns/synapse">
   <property name="messageType" value="application/json" scope="axis2" type="STRING"></property>
   <send></send>
</outSequence> 

Error: It will only convert part of the response into JSON.

Sample Response:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"       xmlns:xsd="http://www.w3.org/2001/XMLSchema"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:easyDownloadResponse xmlns:ns1="http://usermanage.ivas.huawei.com" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<easyDownloadReturn href="#id0"/>
</ns1:easyDownloadResponse>
<multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://response.usermanage.ivas.huawei.com" id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:EasyDownloadResp">
<eventClassName xsi:type="xsd:string" xsi:nil="true"/>
<failedResources xsi:type="soapenc:Array" xsi:nil="true"/>
<operationID xsi:type="xsd:long">0</operationID>
<resultCode xsi:type="xsd:int">0</resultCode>
<resultInfo xsi:type="xsd:string" xsi:nil="true"/>
<returnCode xsi:type="xsd:string">000000</returnCode>
<toneTransactionID xsi:type="soapenc:Array" xsi:nil="true"/>
<transactionID xsi:type="xsd:string" xsi:nil="true"/>
</multiRef>
</soapenv:Body> </soapenv:Envelope> 

Converted JSON :

{"easyDownloadResponse":{"@encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/","easyDownloadReturn":{"@href":"#id0"}}}

Solution:

Add JSON conversion property as follows:

<outSequence xmlns="http://ws.apache.org/ns/synapse">
   <property name="messageType" value="application/json/badgerfish" scope="axis2" type="STRING"></property>
   <send></send>
</outSequence>


Sunday, July 17, 2016

[WSO2][ESB][Cluster] Task Scheduling Error

Environment:  ESB 4.9.0
                        Java: 1.8.0
                        Clustered Environment (2 worker nodes with a manager node)
                        Added inbound endpoints for JMS transport

Preconditions: All nodes in cluster should be down

Situation: Start manager node. Can be seen following error.
                 When start worker nodes also can be seen the error.

Error:

 [2016-06-21 06:11:17,741] ERROR - NTaskTaskManager Scheduling task [[NTask::-1234::JMSListener3-JMS--SYNAPSE_INBOUND_ENDPOINT]::JMS--SYNAPSE_INBOUND_ENDPOINT] FAILED. Error: No available task nodes for resolving a task location  
 org.wso2.carbon.ntask.common.TaskException: No available task nodes for resolving a task location  
   at org.wso2.carbon.ntask.core.impl.clustered.ClusteredTaskManager.getTaskLocation(ClusteredTaskManager.java:232)  
   at org.wso2.carbon.ntask.core.impl.clustered.ClusteredTaskManager.locateMemberForTask(ClusteredTaskManager.java:209)  
   at org.wso2.carbon.ntask.core.impl.clustered.ClusteredTaskManager.getMemberIdFromTaskName(ClusteredTaskManager.java:283)  
   at org.wso2.carbon.ntask.core.impl.clustered.ClusteredTaskManager.scheduleTask(ClusteredTaskManager.java:91)  
   at org.wso2.carbon.mediation.ntask.NTaskTaskManager.schedule(NTaskTaskManager.java:103)  
   at org.wso2.carbon.mediation.ntask.NTaskTaskManager.init(NTaskTaskManager.java:350)  
   at org.wso2.carbon.mediation.ntask.NTaskTaskManager.update(NTaskTaskManager.java:363)  
   at org.wso2.carbon.mediation.ntask.internal.NtaskService.updateAndCleanupObservers(NtaskService.java:103)  
   at org.wso2.carbon.mediation.ntask.internal.NtaskService.setConfigurationContextService(NtaskService.java:96)  
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
   at java.lang.reflect.Method.invoke(Method.java:497)  

Solution:  Start worker nodes in worker profile as follows;

sh wso2server.sh -DworkerNode=true
When you are starting manager node, it may pop up the same error. Because worker nodes are not up yet. After worker nodes are active, you should not get the similar error again.

Relevant issue reported in StackOverflow: http://stackoverflow.com/questions/38051732/wso2-esb-cluster-environment-task-sheduling/


Tuesday, July 12, 2016

[WSO2][ESB][JMS] Configuring jms message store without message processor

Environment - ESB 4.9.0
                         Oracle jdk1.8.0_72
                         MB 3.1.0

Preconditions: ESB should be configured with MB
                          ESB and MB should  up and running

Situation: Create a proxy in ESB which will send incoming message in to jms message store 

 <proxy name="InformationIncome" startOnLoad="true" trace="disable" transports="http https">  
     <description/>  
     <target>  
       <inSequence>  
         <log level="full"/>  
         <property name="FORCE_SC_ACCEPTED" scope="axis2" value="true"/>  
         <property name="OUT_ONLY" value="true"/>  
         <property name="content-Type" scope="transport"  
           type="STRING" value="application/json"/>  
         <property name="messageType" scope="axis2" type="STRING" value="application/json"/>  
         <payloadFactory media-type="json">  
           <format>  
         {  
         "processDefinitionId":"myProcess:6:25188",  
         "variables": [  
          {  
           "name":"text",  
           "value":"$1"  
          }  
         ]  
       }   
       </format>  
           <args>  
             <arg evaluator="json" expression="$.text"/>  
           </args>  
         </payloadFactory>  
         <header  
           expression="fn:concat('Basic ', base64Encode('admin:admin'))"  
           name="Authorization" scope="transport"/>  
         <log level="full"/>  
         <store messageStore="InformationIncomeMS"/>  
       </inSequence>  
     </target>  
   </proxy>  

  <messageStore  
     class="org.apache.synapse.message.store.impl.jms.JmsStore" name="InformationIncomeMS">  
     <parameter name="store.jms.destination">JMSQueue</parameter>  
     <parameter name="store.producer.guaranteed.delivery.enable">false</parameter>  
     <parameter name="java.naming.factory.initial">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>  
     <parameter name="java.naming.provider.url">repository/conf/jndi.properties</parameter>  
     <parameter name="store.jms.JMSSpecVersion">1.1</parameter>  
   </messageStore>  

Add another proxy which will listen to message store queue.
 <proxy name="JMSQueue" startOnLoad="true" trace="disable" transports="jms">  
     <description/>  
     <target>  
       <inSequence>  
         <log level="full">  
           <property name="Message" value="==============This is listening sequence======"/>  
         </log>  
       </inSequence>  
     </target>  
   </proxy>  

Publish a message to Proxy.

Error:
 [2016-07-12 17:51:05,124] ERROR - BaseUtils Unsupported JMS message type org.wso2.andes.client.message.JMSObjectMessage  
 [2016-07-12 17:51:05,125] ERROR - JMSMessageReceiver Unknown error processing message  
 org.apache.axis2.transport.base.BaseTransportException: Unsupported JMS message type org.wso2.andes.client.message.JMSObjectMessage  
      at org.apache.axis2.transport.base.BaseUtils.handleException(BaseUtils.java:168)  
      at org.apache.axis2.transport.jms.JMSUtils.setSOAPEnvelope(JMSUtils.java:177)  
      at org.apache.axis2.transport.jms.JMSMessageReceiver.processThoughEngine(JMSMessageReceiver.java:195)  
      at org.apache.axis2.transport.jms.JMSMessageReceiver.onMessage(JMSMessageReceiver.java:122)  
      at org.apache.axis2.transport.jms.ServiceTaskManager$MessageListenerTask.handleMessage(ServiceTaskManager.java:575)  
      at org.apache.axis2.transport.jms.ServiceTaskManager$MessageListenerTask.run(ServiceTaskManager.java:468)  
      at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)  
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)  
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)  
      at java.lang.Thread.run(Thread.java:745)  


Solution:

Add a message processor to handle messages in message store
   <messageProcessor  
     class="org.apache.synapse.message.processor.impl.forwarder.ScheduledMessageForwardingProcessor"  
     messageStore="InformationIncomeMS" name="testP" targetEndpoint="aspnet">  
     <parameter name="client.retry.interval">1000</parameter>  
     <parameter name="throttle">false</parameter>  
     <parameter name="max.delivery.attempts">4</parameter>  
     <parameter name="member.count">1</parameter>  
     <parameter name="max.delivery.drop">Enabled</parameter>  
     <parameter name="interval">1000</parameter>  
     <parameter name="is.active">true</parameter>  
     <parameter name="target.endpoint">aspnet</parameter>  
   </messageProcessor>  



Sample code for endpoint:

 <endpoint xmlns="http://ws.apache.org/ns/synapse" name="aspnet">  
   <address uri="http://localhost:9000/services/SimpleStockQuoteService">  
    <suspendOnFailure>  
      <progressionFactor>1.0</progressionFactor>  
    </suspendOnFailure>  
    <markForSuspension>  
      <retriesBeforeSuspension>0</retriesBeforeSuspension>  
      <retryDelay>0</retryDelay>  
    </markForSuspension>  
   </address>  
 </endpoint>  

Analysis:


Once we store messages in a message store we need to use message processor to process the stored messages. When a message stored in a JMS Message Store, that message is getting serialized before storing it in the JMS Queue. After serializing, it is saved as Object message. It is the implementation behavior and it is getting deserialized when it is processed by the message processor. Basically, without using the message processor, can not consume that message.