WSO2 Message Broker JNDI usage - wso2

I am trying to use Message Broker but i have some questions.
1 I have created a queue on message broker and i could add new message to message broker with proxy service on ESB. However when i try to listen this queue on Application Server i could not get queue connection factory on my code. If i follow this blog http://pzf.fremantle.org/2011/04/introduction-to-wso2-message-broker_05.html i could achieve the get message from my queue. But i think i should not create connection to message broker on my code, i should get connection from application server. So i have uncomment to JMSListener attribute and you could see it at the below. If i try to get queue from here with this code
Context initCtx = new InitialContext();
initCtx.lookup("myQueueConnectionFactory");
i am getting javax.naming.NameNotFoundException: Name myQueueConnectionFactory is not bound in this Context exception. Do you have any suggestion to get connection from application server.
<parameter locked="false" name="myTopicConnectionFactory">
<parameter locked="false" name="java.naming.factory.initial">org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter>
<parameter locked="false" name="java.naming.provider.url">repository/conf/jndi.properties</parameter>
<parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">TopicConnectionFactory</parameter>
<parameter locked="false" name="transport.jms.ConnectionFactoryType">topic</parameter>
</parameter>
<parameter locked="false" name="myQueueConnectionFactory">
<parameter locked="false" name="java.naming.factory.initial">org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter>
<parameter locked="false" name="java.naming.provider.url">repository/conf/jndi.properties</parameter>
<parameter locked="false" name="transport.jms.ConnectionFactoryJNDIName">QueueConnectionFactory</parameter>
<parameter locked="false" name="transport.jms.ConnectionFactoryType">queue</parameter>
</parameter>
<parameter name="default" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.apache.qpid.jndi.PropertiesFileInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">resources/jndi.properties</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
</parameter>
2 How many times message broker send queue item to subscriber. For example message broker send item to subscriber and somehow subcriber can not accomplished the job. So item is not deleted from message broker queue. When will it try to send this item to subscriber again and how many times it will try to send this item to send subscriber.
Thanks,

When you are saving the message to the Queue using ESB, you need to specify the ConnectionFactory from your endpoint uri configuration as given below.
<address uri="jms:/myQueueName?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.wso2.andes.jndi.PropertiesFileInitialContextFactory&java.naming.provider.url=tcp://localhost:5672&transport.jms.DestinationType=queue&java.naming.provider.url=repository/conf/jndi.properties" statistics="enable"/>

Related

WSO2 EI 6.3.0 unable to connect with IBM Websphere MQ v8 using JMS

I am trying to connect WSO2 Enterprise Integrator with IBM Websphere MQ v 8.0.0.5 by JMS Transport. The purpose is to be able to receive/publish messages on Queues that are made in IBM Websphere MQ via WSO2 Enterprise Integrator using JMS Protocol.
Link:
I followed this link provided by WSO2 official documentation. I followed all the steps exactly but when I deploy the JMS Listener Proxy, it becomes a faulty service and It shows me the following error on the console:
Error Stack Trace:
com.ibm.mq.MQException: JMSCMQ0001: WebSphere MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:412)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:8475)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7913)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:299)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:236)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6024)
at com.ibm.mq.jms.MQQueueConnectionFactory.createQueueConnection(MQQueueConnectionFactory.java:136)
at com.ibm.mq.jms.MQQueueConnectionFactory.createConnection(MQQueueConnectionFactory.java:209)
at org.apache.axis2.transport.jms.JMSUtils.createConnection(JMSUtils.java:786)
at org.apache.axis2.transport.jms.JMSListener.checkJMSConnection(JMSListener.java:155)
at org.apache.axis2.transport.jms.JMSListener.startEndpoint(JMSListener.java:99)
at org.apache.axis2.transport.jms.JMSListener.startEndpoint(JMSListener.java:54)
at org.apache.axis2.transport.base.AbstractTransportListenerEx.startListeningForService(AbstractTransportListenerEx.java:154)
at org.apache.axis2.transport.base.AbstractTransportListener.internalStartListeningForService(AbstractTransportListener.java:213)
at org.apache.axis2.transport.base.AbstractTransportListener$2.serviceAdded(AbstractTransportListener.java:126)
at org.apache.axis2.transport.base.tracker.AxisServiceTracker.serviceAdded(AxisServiceTracker.java:212)
at org.apache.axis2.transport.base.tracker.AxisServiceTracker$1.serviceUpdate(AxisServiceTracker.java:98)
at org.apache.axis2.engine.AxisConfiguration.notifyObservers(AxisConfiguration.java:666)
at org.apache.axis2.engine.AxisConfiguration.addServiceGroup(AxisConfiguration.java:420)
at org.apache.axis2.engine.AxisConfiguration.addService(AxisConfiguration.java:350)
at org.apache.synapse.core.axis2.ProxyService.buildAxisService(ProxyService.java:750)
at org.wso2.carbon.proxyadmin.service.ProxyServiceAdmin.addProxyService(ProxyServiceAdmin.java:273)
at org.wso2.carbon.proxyadmin.service.ProxyServiceAdmin.addProxy(ProxyServiceAdmin.java:710)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Proxy Service Code as mentioned in documentation:
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="MyJMSProxy"
transports="jms"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<log level="full"/>
<drop/>
</inSequence>
</target>
<parameter name="transport.jms.Destination">LocalQueue1</parameter>
</proxy>
Axis2 File Configuration:
Following are axis2 configurations for transport receiver and transport listener.
Transport Receiver:
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="default" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:/C:/jndidirectory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.UserName" locked="false">omerk</parameter>
<parameter name="transport.jms.Password" locked="false">password</parameter>
</parameter>
<parameter name="myQueueConnectionFactory1" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:/C:/jndidirectory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.UserName" locked="false">omerk</parameter>
<parameter name="transport.jms.Password" locked="false">password</parameter>
</parameter>
</transportReceiver>
Transport Listener:
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender">
<parameter name="default" locked="false">
<parameter name="vender.class.loader.enabled">false</parameter>
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:/C:/jndidirectory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.UserName" locked="false">omerk</parameter>
<parameter name="transport.jms.Password" locked="false">password</parameter>
</parameter>
<parameter name="myQueueConnectionFactory1" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:/C:/jndidirectory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.UserName" locked="false">omerk</parameter>
<parameter name="transport.jms.Password" locked="false">password</parameter>
</parameter>
</transportSender>
Research So far:
I tried googling it and apparently it is showing that It is not able to figure out the Queue Manager Name. But I am unable to figure out where to add this information and how? I tried adding it on the JMS Proxy Service Level Parameters but it didn't work. So any insight would be helpful.
TroubleShooting
For Troubleshooting, when I checked the Error logs of IBM Websphere MQ. IT was giving the following error:
AMQ5534: User ID 'omerk' authentication failed
EXPLANATION:
The user ID and password supplied by the 'carbon.bootstrap.Bootstrap' program
could not be authenticated.
Solution:
For my solution the authentication was not a requirement. So I basically disabled the authentication of my queue manager by running the following commands.
ALTER AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS) AUTHTYPE(IDPWOS) CHCKCLNT(NONE)
REFRESH SECURITY TYPE(CONNAUTH)
IT worked for me and solved my problem.

WSO2: Override JMS producer JNDI properties for MQ

I am trying to override the JMS connection properties as outlined in the documentation:
https://docs.wso2.com/display/EI640/Using+the+ESB+as+a+JMS+Producer
You can define a JMS queue name and connection factory parameters in the JMS connection URL. Values of connection factory parameters depend on the type of the JMS broker.
I have multiple queue connection factories defined in my axis2.xml file to support multiple queue managers. However, the following configuration does not take effect (the messages are not sent to the right queue environment):
<endpoint name="myEndpoint" xmlns="http://ws.apache.org/ns/synapse">
<address format="pox" uri="jms://MY_QUEUE_NAME?transport.jms.ConnectionFactoryJNDIName=MYQUEUEQCF"/>
</endpoint>
The axis2 configuration matches with the above:
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender">
<parameter name="myConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:bindings</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">OTHERQCF</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.UserName" locked="false"></parameter>
<parameter name="transport.jms.Password" locked="false"></parameter>
</parameter>
<parameter name="secondConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:bindings</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MYQUEUEQCF</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.UserName" locked="false"></parameter>
<parameter name="transport.jms.Password" locked="false"></parameter>
</parameter>
</transportSender>
The messages are going through the first connection factory, OTHERQCF, and not via MYQUEUEQCF as expected, so they are sent to the wrong environment. The queue technology used is WebSphere MQ.
Is this a bug or am I missing something?
I have also tried with the following config and it does not take effect:
<endpoint name="myEndpoint" xmlns="http://ws.apache.org/ns/synapse">
<address format="pox" uri="jms://MY_QUEUE_NAME?transport.jms.ConnectionFactoryJNDIName=MYQUEUEQCF&java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory&java.naming.provider.url=file:bindings&transport.jms.DestinationType=queue"/>
</endpoint>
Finally found the solution: the WSO2 documentation is (as usual) incomplete and in this case, incorrect.
First of all, the second JMS producer must have CacheLevel above SESSION (i.e. value set to auto, consumer, or producer in axis.xml configuration, e.g.:
<parameter name="secondConnectionFactory" locked="false">
<parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">file:bindings</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MYQUEUEQCF</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.UserName" locked="false"></parameter>
<parameter name="transport.jms.Password" locked="false"></parameter>
<parameter name="transport.jms.CacheLevel" locked="false">producer</parameter>
</parameter>
This is because the JMSProducer will otherwise move to use the default connection factory based on the code on github.
Second of all, the documentation states the parameter name incorrectly. The parameter to use is called transport.jms.ConnectionFactory and not transport.jms.ConnectionFactoryJNDIName.
Additionally the parameter value is referring to the overall internal axis2 name of the connection factory, i.e. secondConnectionFactory in the example above, rather than the MYQUEUEQCF JNDI name.
So with the following configuration, the message is correctly sent to the second queue:
<endpoint name="myEndpoint" xmlns="http://ws.apache.org/ns/synapse">
<address format="pox" uri="jms://MY_QUEUE_NAME?transport.jms.ConnectionFactory=secondConnectionFactory&java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory&java.naming.provider.url=file:bindings&transport.jms.DestinationType=queue"/>
</endpoint>
Not sure if it´s the same under EI 6.x but for esb 4.8 you had to define a second transport sender witch you then refer in the send/endpoint.
<transportSender name="jmsSecond" class="org.apache.axis2.transport.jms.JMSSender">
<parameter name="secondConnectionFactory" .....
</transportSender>
<endpoint name="myEndpoint" xmlns="http://ws.apache.org/ns/synapse">
<address format="pox" uri="jmsSecond://MY_QUEUE_NAME?transport.jms.ConnectionFactoryJNDIName=MYQUEUEQCF"/>
</endpoint>

wso2 5.0.0 jms activemq consummer.exclusive

Using a proxy-service listening on a jms queue in wso2esb-5.0.0, how do I use the activemq consumer.exclusive=true property ?
I have the following configuration in axis2.xml :
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="default" locked="false">
<parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
<parameter name="java.naming.provider.url" locked="false">failover:(tcp://V1-AMQ01:61616,tcp://V1-AMQ02:61616)?jms.nonBlockingRedelivery=true&nested.consumer.exclusive=true</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.SessionTransacted">true</parameter>
<parameter name="transport.jms.SessionAcknowledgement" locked="true">CLIENT_ACKNOWLEDGE</parameter>
<parameter name="transport.Transactionality" locked="true">local</parameter>
<parameter name="redeliveryPolicy.maximumRedeliveries" locked="true">-1</parameter>
<parameter name="redeliveryPolicy.redeliveryDelay">4000</parameter>
<parameter name="transport.jms.CacheLevel" locked="true">consumer</parameter>
<parameter name="redeliveryPolicy.initialRedeliveryDelay">4000</parameter>
<parameter name="redeliveryPolicy.maximumRedeliveryDelay">864000</parameter>
<parameter name="redeliveryPolicy.useExponentialBackOff">true</parameter>
<parameter name="redeliveryPolicy.backOffMultiplier">3</parameter>
</parameter>
</transportReceiver>
All my proxy services listening on jms queues use this configuration. The esb doesn't consume any messages. When I remove the "&nested.consumer.exclusive=true" it correctly consumes messages.
If I look at the activemq console, I see 0 consumers on my queues (normally, 1)
If I delete the queues and restart the esb, the queues are not recreated (normally they are)
The option needs to be set on the proxy service:
<proxy name="Myqueue?consumer.exclusive=true&consumer.prefetchSize=0" startOnLoad="true" transports="jms" xmlns="http://ws.apache.org/ns/synapse">
However this creates errors in the log:
2018-07-31 18:50:02,981 WARN JMSListener - Error registering a MBean with objectname ' org.apache.axis2:Type=Transport,ConnectorName=jms-listener-1065586266,Group=Services,Service=JMS_SMS_MainNotification?consumer.exclusive=true&consumer.prefetchSize=0 ' for JMX management
javax.management.MalformedObjectNameException: Invalid character '=' in value part of property
at javax.management.ObjectName.construct(ObjectName.java:618)
But as far as I understand the alternative is to use transport.jms.Destination (cf https://docs.wso2.com/display/ESB490/JMS+Transport ) but this duplicates the axis2.xml configuration ?? Is that it ?

DSS - Endpoints have Ports Appended in the WSDLs, can they be removed?

First, thanks for reading. I hope to have a simple question and if anyone could provide an answer, I would appreciate it. We are having great success with WSO2 products, but have been struggling with the following.
Setup: DSS has a setup of PortOffset 1 (9444 port usage)
External Load Balancer that listens for https://SOMESERVER and
forwards to DSS Workers on ServerName:9444. When we create services in DSS, the WSDL will have an appended PORT on the endpoints. Is there a way to turn off this PORT being added to the WSDL endpoints
</wsdl:port>
<wsdl:port name="SecureSOAP12Endpoint" binding="ns0:ThisServiceSOAP12Binding">
<soap12:address location="https://SOMESERVER:9444/services/ThisService.SecureSOAP12Endpoint/"></soap12:address>
</wsdl:port>
ESB has Transport options to change WSDL Prefixes. We do not see the same in DSS and therefore ALL of our URLs have appended port of the carbon port (+offset).
<!-- ================================================= -->
<!-- Transport Ins (Listeners) -->
<!-- ================================================= -->
<transportReceiver class="org.apache.synapse.transport.passthru.PassThroughHttpListener" name="http">
<parameter locked="false" name="port">8280</parameter>
<parameter locked="false" name="non-blocking">true</parameter>
<parameter locked="false" name="bind-address">http://SOMESERVER</parameter>
<parameter locked="false" name="WSDLEPRPrefix">http://SOMESERVER</parameter>
<parameter locked="false" name="httpGetProcessor">org.wso2.carbon.transport.nhttp.api.PassThroughNHttpGetProcessor</parameter>
<parameter locked="false" name="priorityConfigFile">location of priority configuration file</parameter>
</transportReceiver>
<transportReceiver class="org.apache.synapse.transport.passthru.PassThroughHttpSSLListener" name="https">
<parameter locked="false" name="port">8243</parameter>
<parameter locked="false" name="non-blocking">true</parameter>
<parameter locked="false" name="bind-address">https://SOMESERVER</parameter>
<parameter locked="false" name="WSDLEPRPrefix">https://SOMESERVER</parameter>
<parameter locked="false" name="httpGetProcessor">org.wso2.carbon.transport.nhttp.api.PassThroughNHttpGetProcessor</parameter>
Two options:
You can try to replace the default listener with NIO listener. There are comments in the axis2.xml file on how to do that
Front your DSS instance with an ESB instance. I think this would be a better solution in the long run due to the additional capabilities you can get from it, like failover, load balancing, lightweight service composition and so on.

Sequence defined in the Message Processor doesn't receive the response

I have a separate proxy (in WSO2ESB4.8.1) which sends the message to the message store (which is configured with WSO2MB 2.2.0) and then the processor sends the message to the backend and backend receives the message, but the response from backend doesn't come back to the defined sequence, Seq_IfcFileCheckinResponse in the processor.
My backend is rest service and I am sending a json request.
I noticed following warning message in esb console,
WARN - JmsConsumer [JMSMessageStore-C-1]. Did not receive a javax.jms.ObjectMessage
Following configurations for message store and processor,
<messageStore class="org.apache.synapse.message.store.impl.jms.JmsStore"
name="JMSMessageStore">
<parameter name="java.naming.factory.initial">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>
<parameter name="store.jms.password">admin</parameter>
<parameter name="java.naming.provider.url">repository/conf/jndi.properties</parameter>
<parameter name="store.jms.connection.factory">QueueConnectionFactory</parameter>
<parameter name="store.jms.username">admin</parameter>
<parameter name="store.jms.destination">IfcQueue</parameter>
<parameter name="store.jms.JMSSpecVersion">1.1</parameter>
</messageStore>
and
<messageProcessor class="org.apache.synapse.message.processor.impl.forwarder.ScheduledMessageForwardingProcessor"
name="JMSMessageProcessor"
targetEndpoint="bimserverendpoint"
messageStore="JMSMessageStore">
<parameter name="message.processor.reply.sequence">Seq_IfcFileCheckinResponse</parameter>
<parameter name="client.retry.interval">5000</parameter>
<parameter name="max.delivery.attempts">2</parameter>
<parameter name="interval">1000</parameter>
<parameter name="message.processor.fault.sequence">ErrorSeq_IfcFileCheckinResponserSeq</parameter>
<parameter name="is.active">true</parameter>
</messageProcessor>
You should verify that :
property "OUT_ONLY" is not set to true in the proxy that put the message in the MessageStore
The value of http status code (for the response from your backend service) is 200 or 500 (use tcpmon between ESB and your backend service to have a look to the response)
The warning "Did not receive a javax.jms.ObjectMessage" is logged when you store the message or when the message processor dequeue it from the store ? (deactivate your message processor and call your proxy that store the message in the store)