Camel Transacted: MQ Session closed on every commit - apache-camel

I have:
Camel route (transacted=true), consuming from an MQ Queue
Using Spring's WebSphereUowTransactionManager
Transactionality works
Running on IBM Liberty
But, I get this message:
Setup of JMS message listener invoker failed for destination 'MY.QUEUE' - trying to recover.
Cause: Local JMS transaction failed to commit; nested exception is com.ibm.msg.client.jms.DetailedIllegalStateException:
MQJCA1020: The session is closed.
The application attempted to use a JMS session after it had closed the session.
Modify the application so that it closes the JMS session only after it has finished using the session.
This appears to be related to this other Stack Overflow question, but I've tried changing the configuration in server.xml, with no success.

You can try setting cacheLevelName=CACHE_CONSUMER which allows to re-use the JMS consumer and avoids endless of creation/destruction of JMS resources, as indicated by the error message may be the cause.
You can see more about the importanse of cache levels on the Camel JMS documentation: http://camel.apache.org/jms

Related

In Mulesoft how to stop SFTP connector to read file when ActiveMQ is trying to reconnect

I have a reliable acquisition flow where an inbound SFTP connector is polling and reading the file and publishing to JMS ActiveMq. I have an issue when ActiveMQ is down. JMS connector get in to reconnection mode lets say every minute but SFTP is actively reading the files and try to publish the file in ActiveMq. which causes the loss of message and the concept of deadletter queue also does not work as JMS is down.
Is there a way we can stop reading the file until the JMS successfully reconnect? also what if the message was in flight and JMS get down before message end up in the queue? will the message rollback?
I am using Mule 3.9
If you set the flow processing strategy to synchronous and use only 1 receiver thread in the connector configuration. Then it should not try to read a new file if the previous one wasn't processed. Without those changes it is not a correct implementation of the reliable pattern.
More information:
Documentation of reliable patterns: https://docs.mulesoft.com/mule-runtime/3.9/reliability-patterns.
KB Article: https://help.mulesoft.com/s/article/How-to-fetch-files-in-order-using-the-FTP-connector
Example:
<sftp:connector name="sftpConn">
<receiver-threading-profile maxThreadsActive="1" />
</sftp:connector>
<flow name="mainFlow" processingStrategy="synchronous">
...

Camel: Routing from queue to HTTP

Bit of a Camel newbie but here goes.
I have the following route:
from("activemq:queue:outputQueue").inputType(HelloWorld.class)
.to("log:stream")
.marshal().json(JsonLibrary.Jackson, HelloWorld.class)
.to("http:localhost:5000/messageForYouSir?bridgeEndpoint=true");
This retrieves messages from the queue and sends them to the HTTP endpoint as JSON. Fine.
But what if there is an error? Say a HTTP error code of 400? Then I want the message to stay on the queue. I have tried looking into not acknowledging the message, but have not been able to make it work.
Also I have made an Exception handler
onException(HttpOperationFailedException.class)
.handled(false)
.setBody().constant("Vi fekk ein feil");
But still the messages are gone from the queue. Is there some magic spell that can make Camel not acknowledge the messages when there is some error?
You have to consume transacted from the queue to be able to do a rollback. This is configured on the connection configuration to the broker.
Take a look at the Camel JMS docs (the ActiveMQ component extends the JMS component), especially the sections about cache levels and transacted consumption.
The most simple setup is using broker transactions by simply set transacted = true and lazyCreateTransactionManager = false on the JmsConfiguration. This way no Spring TX manager is required.
If transacted consumption is in place and the HTTP server returns an error (basically if an Exception occurs in the Camel Route), Camel does automatically a rollback (if you don't catch the error).

How to ensure ordering in camel context polling weblogic jms queue

I am trying to setup a camel context that polls a weblogic jms queue, consumes the message and sends it to a webservice endpoint. Incase any error occurs in the transaction or the target system is unavailable, I need to redeliver the same message without losing sequence/ordering.
I have set up a camel jms route with single consumer and enabled transacted attribute as per https://camel.apache.org/transactional-client.html and set the redelivery as unlimited.
When the transaction fails with messageA, the jms message consumption from weblogic queue is rollbacked and the messageA is marked for redelivery (state string is marked delayed) in weblogic. But during this time if another message reaches the weblogic queue, the camel route picks the messageB and forwards it to the target endpoint although the messageA is still in retrying mode. This distorts the whole ordering of the messages.
The transaction client is used to ensure that messages are not lost while the application is shutdown during redelivery.
I expect that there are no message loss and the messages are always sent in the correct order as per generated into the weblogic queue to the target endpoint.
That a newly arrived message outpaces an existing message that has to be redelivered, sounds like a broker (Weblogic) issue or feature.
I never saw this behavior with ActiveMQ. A failed message that is redelivered, is redelivered immediately by the Apache broker.
It sounds like the message is "put aside" internally to redeliver it later. This can absolutely make sense to avoid blocking message processing.
Is there something like a "redelivery delay" set on Weblogic you can configure? I could imagine that a delayed redelivery is like an internal error queue with a scheduled consumer.

Camel transaction handler forces reconnecting to ActiveMQ

Trying to set up a route with transaction handling on a camel, this leads to connection to the activeMQ drop and reconnect every few milliseconds is this expected, is there a work around?
Logs showing repeatedly reconnecting to ActiveMQ server:
ActiveMQ FailoverTransport Successfully connected to ssl://serveraddress:61617
ActiveMQ FailoverTransport Successfully connected to ssl://serveraddress:61617
ActiveMQ FailoverTransport Successfully connected to ssl://serveraddress:61617
Changed connection factory to use CachingConnectionFactory, also tweaked configurations to incorporate caching connection.

Force Camel JMS/AMQP component to use separate sessions for producer and consumer

Some AMQP enabled brokers like Microsoft Service Bus or ActiveMQ allow only one active producer or consumer per session. The Apache JMS Camel component seems not be able to handle this correctly, which result that JMS throws exceptions when processing InOut messages sent from e.g. Service Bus.
A small JMS test application with separate sessions for producer and consumer works nice. With using the same session, it run into the same problem.
Issue is rooted in the Spring JMS template, which is used as base for the Camel JMS implementation.
Does anybody know how to overcome that behavior?
You can define a 2nd JMS component and use that for the "other".
Or you can turn off any kind of connection pooling maybe.
If you use XML then you can define a 2nd jms component
<bean id="jms2" class="org.apache.camel.component.jms.JmsComponent"/>

Resources