Apache Artemis V 2.1.0 - stomp

I was using Artemis 1.5.3 and my addressing scheme was jms.topic.xxx for pub-sub and jms.queue.xxx for point to point and all worked great. However I switch to version 2.1.0 and the jms.topic.xxx work like a point to point routing, meaning not all subscribers receive the message. Previously, I was using ActiveMQ and their naming prefix was /topic.xxx and /queue.xxx. I also tried setting the multicast config in broker.xml per activemq.apache.org/artemis/docs/2.1.0/address-model.html but Artemis is complaining and will not start. Any help would be much appreciated.

Without seeing what the actual errors are in the logs, I am going to assume that your instance is not starting up because of the way that you are defining your queues and/or topics. In version 2.x and newer, Artemis changed the way you define a queue or topic (They switched to an Address Model http://activemq.apache.org/artemis/docs/2.1.0/address-model.html). Below is an example. I hope this helps.
….. rest of broker.xml configuration
<addresses>
<!-- default queues for artemis -->
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
<!-- Define topics -->
<address name="SomeTestTopic">
<multicast/>
</address>
<!-- Define queues -->
<address name="RequestReplyQueue">
<anycast>
<queue name="RequestReplyQueue" />
</anycast>
</address>
</addresses>

Related

WebSphere liberty wasJmsServer Dead Letter queue

Could anyone point me to some reference on setting up DLQ on WLS liberty profile version 16.0.0.2 using Liberty embedded JMS messaging provider?
I have a queue configured with a spring jms listener and when the message listener throws a RuntimeException, the message should go to deal letter queue after few retries.
Thanks.
With the wasJmsServer feature the term is the exception destination. This can be configured as an attribute on the queue object. This references the name of another queue. As an example:
<messagingEngine>
<queue id="dlq" />
<queue id="myQueue" exceptionDestination="dlq" />
</messagingEngine>
there is a default name for exception destination which is _SYSTEM.Exception.Destination, so if you have this:
<messagingEngine>
<queue id="_SYSTEM.Exception.Destination" />
<queue id="myQueue" />
</messagingEngine>
then you should have all the 'bad' messages on the default queue. By default messages will only be sent to the exception destination if delivery failed 5 times. This can be overridden with the maxRedeliveryCount setting:
<messagingEngine>
<queue id="_SYSTEM.Exception.Destination" />
<queue id="myQueue" maxRedeliveryCount="2"/>
</messagingEngine>
The configuration for this is available in the Knowledge Center for WebSphere Liberty.

jms dynamic destination from original jmsReplyTo

There is one request queue and the reply queues are created by the client server instances and pinned to each instance rather than using temporary queues.
The use case needs to get an inbound jms message and then send that message to an asynchronous process. Once the async reply messsage is received from the service I need to take those results and reply back to the original message's jmsReplyTo. The Jms gateway would not work in this instance AFAIK>
I am using a jms message driven channel adapter for the message in with a series of channels and service activators to handle the out of process calls and async replies. I am trying to use the DynamicDestinationResolver to no avail. Additionally I have tried to set the outbound destination address programatically but could not figure out a good way to do this.
This seems like a common pattern but I could not find a good example for a completely disconnected async request response. Disconnected meaning that the usual async jms request reply did not seem to fit the need.
Context Config:
<!-- Input from Amq -->
<amq:queue id="requestQueue" physicalName="${request.queue}" />
<int-jms:message-driven-channel-adapter id="jmsIn"
connection-factory="jmsConnectionFactory"
destination="requestQueue"
channel="queueRequestChannel" concurrent-consumers="5" />
<int:channel id="queueRequestChannel" />
<int:service-activator input-channel="queueRequestChannel" ref="switchMessageHandler" method="processSwitchMessage"
output-channel="cardNetworkOutChannel"/>
<!-- Output to Card Network-->
<int:channel id="cardNetworkOutChannel" />
<!--<int:service-activator input-channel="cardNetworkOutChannel" ref="cardNetworkHandler" method="send8583Message" />-->
<!-- Simply used to mock the card network by transforming a SwithMessage to a SwitchMessageResponse * Not needed for target solution -->
<int:transformer id="requestResponseTransformer" ref="nettyCardNetworkClientMock" input-channel="cardNetworkOutChannel"
method="process" output-channel="cardNetworkInChannel"/>
<!-- Input from Card Network -->
<int:channel id="cardNetworkInChannel" />
<int:service-activator input-channel="cardNetworkInChannel" ref="switchMessageHandler" method="sendSwitchMessage"
output-channel="queueReplyChannel"/>
<int:channel id="queueReplyChannel"/>
<int-jms:outbound-channel-adapter
destination-resolver="simpleDestinationResolver" connection-factory="jmsConnectionFactory"
channel="queueReplyChannel" destination-expression="headers.jms_replyTo" />
I just updated the jms sample app to make the server side use independent adapters instead of the inbound gateway and it works just fine...
<!-- <jms:inbound-gateway id="jmsin" -->
<!-- request-destination="requestQueue" -->
<!-- request-channel="demoChannel"/> -->
<channel id="demoChannel"/>
<jms:message-driven-channel-adapter destination="requestQueue" channel="demoChannel" />
<service-activator input-channel="demoChannel" ref="demoBean" output-channel="reply" />
<channel id="reply" />
<jms:outbound-channel-adapter channel="reply" destination-expression="headers['jms_replyTo']" />
Turn on DEBUG logging - we put out lots of useful stuff.
EDIT
I just made it async by...
<channel id="reply">
<queue/>
</channel>
<jms:outbound-channel-adapter channel="reply" destination-expression="headers['jms_replyTo']">
<poller fixed-delay="3000"/>
</jms:outbound-channel-adapter>
EDIT2
Depending on what you are using on the client side, many clients require the inbound message id to be used as the correlation id. (This is true for the outbound gateway by default, with named reply queue, unless you provide a correlation-key).
So, to set up the correlationId, you can use a header enricher; I just tested this...
<chain input-channel="reply">
<header-enricher>
<header name="jms_correlationId" expression="headers['jms_messageId']" />
</header-enricher>
<jms:outbound-channel-adapter destination-expression="headers['jms_replyTo']"/>
<poller fixed-delay="1000" />
</chain>
This is not the issue if the client side is setting the correlation id header itself.

Getting duplicate ackMessage on ActiveMQ when using Mule Flows for connection

When using mule flows as listed below, we are getting duplicate ackMessages on activeMQ. That is, the count of acknowledge messages is double the dispatch Messages.
<flow name="dequeueFlow" initialState="stopped">
<jms:inbound-endpoint queue="my.mq.queueName"
connector-ref="MyDequeueJmsConnector">
<jms:transaction action="ALWAYS_BEGIN"/>
</jms:inbound-endpoint>
<processor ref="MyRequestProcessor" />
</flow>
<jms:activemq-connector name="MyDequeueJmsConnector"
specification="1.1"
connectionFactory-ref="AmqConnectionFactory"
disableTemporaryReplyToDestinations="true"
persistentDelivery="true"
cacheJmsSessions="false"
numberOfConsumers="10"
acknowledgementMode="AUTO_ACKNOWLEDGE"
maxRedelivery="1">
</jms:activemq-connector>
In JmsConnector, the acknowledgementMode is set: acknowledgementMode="AUTO_ACKNOWLEDGE".
Instead of flows, if we are using default JMS connections, not seeing the issue. Any pointers on how this can be avoided?
Software Versions:
Mule Enterprise 3.4.1
ActiveMQ 5.9.0

WSO2 ESB: get JMS message property

I have proxy that listens to JMS queue on message broker. When I send the message to a queue, I set custom properties to JMS message. But when I log the message received by the proxy, there is no custom JMS properties. How would I get custom JMS properties in proxy?
I use WSO2 ESB 4.6.0 with ActiveMQ 5.8.0.
<proxy xmlns="http://ws.apache.org/ns/synapse" name="MyProxy" transports="https,TTP,http,jms" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<log level="full"/>
</inSequence>
<outSequence>
<drop/>
</outSequence>
<endpoint>
<address uri="jms:/MyQueue?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue" format="pox"/>
</endpoint>
</target>
</proxy>
It is necessary to get transport headers in order to access custom JMS properties. I've found 2 ways for that:
1) from XML configuration:
<log level="custom">
<property name="jms property" expression="get-property('transport', 'custom_prop_key_1')"/>
</log>
2) from custom Class Mediator:
public boolean mediate(MessageContext synCtx) {
((Map)((Axis2MessageContext) synCtx).getAxis2MessageContext().getProperty("TRANSPORT_HEADERS")).get("custom_prop_key_1");
...
}
I do not think they are available in the SOAP message directly. They should be available in Axis2 / Transport scope. Usually JMS transport add only the JMS message's payload to SOAP body. So please try following.
Can you check them retrieving using properties in ESB and log them.
<log level="custom">
<property name="JMS_PROPERTY---->" expression="get-property('axis2','your-property-name')"/>
</log>
You can refer this on scope of properties. (If it is set at Transport headers you can change scope from 'axis2' to 'transport' and try.)
I have not personally tried this and suggesting the answer logically.

Mule 2.2.6 - strategies for handling JMS connection loss

I am using Mule 2.2.6, with the following setup:
2 servers, each with an instance of ActiveMQ
1 server running Mule 2.2.6
Now, I have a service that picks up a message from one ActiveMQ, and places it on the other. But, this is leading to problems with lost messages when the target ActiveMQ is down. Then, Mule will pick up a message from the source ActiveMQ, but run into this exception upon trying to place it on the destination AtiveMQ:
ERROR [org.mule.DefaultExceptionStrategy] Caught exception in Exception Strategy: No JMS Connection
java.lang.IllegalStateException: No JMS Connection
at org.mule.transport.jms.JmsMessageDispatcher.doDispatch(JmsMessageDispatcher.java:81)
at org.mule.transport.AbstractMessageDispatcher.dispatch(AbstractMessageDispatcher.java:105)
at org.mule.transport.AbstractConnector$DispatchWorker.doRun(AbstractConnector.java:2561)
at org.mule.work.AbstractMuleEventWork.run(AbstractMuleEventWork.java:41)
at org.mule.work.WorkerContext.run(WorkerContext.java:310)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1061)
at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:575)
at java.lang.Thread.run(Thread.java:662)
Upon this happening, the message is just lost, which is way below what is acceptable.
When examining the mule configuration, I noticed that there were no jms-transactions associaited with the service that moves messages from one ActiveMQ to the other, but after adding a transaction, the problem remained the same.
Configuration:
ActiveMQ connectors:
<jms:activemq-connector name="jmsConnectorOuter" specification="1.1"
persistentDelivery="true" disableTemporaryReplyToDestinations="true" honorQosHeaders="true"
numberOfConsumers="1" connectionFactory-ref="activeMqConnectionFactoryOuter" maxRedelivery="-1">
<ee:retry-forever-policy frequency="5000" asynchronous="false" />
</jms:activemq-connector>
<jms:activemq-connector name="jmsConnector" specification="1.1"
persistentDelivery="true" disableTemporaryReplyToDestinations="true" honorQosHeaders="true"
numberOfConsumers="1" connectionFactory-ref="activeMqConnectionFactory" maxRedelivery="-1">
<ee:retry-forever-policy frequency="5000" asynchronous="false" />
</jms:activemq-connector>
Jms-endpoints:
<endpoint name="queue.destination" address="jms://queue.destination" connector-ref="jmsConnector" />
<endpoint name="queue.source" address="jms://queue.source" connector-ref="jmsConnectorOuter" />
Service:
<service name="OuterActiveMQService">
<inbound>
<jms:inbound-endpoint ref="queue.source">
<jms:transaction action="ALWAYS_BEGIN" timeout="60000" />
</jms:inbound-endpoint>
</inbound>
<outbound>
<pass-through-router>
<jms:outbound-endpoint ref="queue.destination" />
</pass-through-router>
</outbound>
</service>
What can be done to make sure that messages aren't lost when the ActiveMQ connection to the destination is lost?
You need to add:
<jms:transaction action="ALWAYS_JOIN" />
in the outbound JMS endpoint to make it join the transaction.

Resources