Using Azure Servicebus queue with Camel in transactional mode - java

I already setup a connection to an Azure Servicebus queue with camel-amqp successfully and could read messages from it. Then I tried to switch to transactional mode. This time, it fails with the following warning, which will be repeated every 5 seconds:
c.c.j.DefaultJmsMessageListenerContainer : Setup of JMS message listener invoker failed for destination 'incoming' - trying to recover. Cause: Could not create JMS transaction; nested exception is javax.jms.JMSException: An AMQP error occurred (condition='amqp:internal-error'). [condition = amqp:internal-error]
My route looks like this:
from("amqp:queue:incoming?connectionFactory=#connectionFactory&transacted=true&transactionManager=#transactionManager").
The transactionManager is of type org.springframework.jms.connection.JmsTransactionManager and the (well configured) connectionFactory of type org.apache.qpid.jms.JmsConnectionFactory.
Could anybody imagine what is missing, maybe some additional configuration?

Related

RabbitMQ - Spring boot consumer does not reconnect after rabbit node failover

I have got a multiple-node RabbitMQ broker with 3 node setup. Failover tests in which one of the scenarios was restarting 2 of 3 rabbit nodes. After restarting the one node Spring boot application was gone and also it wasn't reconnecting. All I got is this error message from SpringBoot application:
java.io.IOException
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=403, reply-text=ACCESS_REFUSED - access to exchange 'EXAMPLE_NAME' in vhost 'EXAMPLE_VHOST' refused for user 'EXAMPLE_USER', class-id=40, method-id=10)
I am using the apache camel RabbitMq consumer to connect to the broker.
I tried use Spring property but without any solution.
camel.component.rabbitmq.automatic-recovery-enabled=true
Or
camel.component.rabbitmq.automatic-recovery-enabled=true
After nodes are restarted and again up there is something like this in the Rabbit UI client:
Can anyone have a solution to use other properties or something else?

Connection reset exception when invoke an external service expose via CDN from spring boot rest template

From a spring boot 2.2.13 application i make a POST request using RestTemplate exchange method to a external service which reside after a CDN.
The CDN documentation said for Persistent Connection (PCONN) idle timeout is 500s.
We have face the issue of every time we make a request after a idle time of 500s, it throws a exception. Then subsequent requests got success.
"message" : "I/O error on POST request for \"https://endpoint\": Connection reset; nested exception is javax.net.ssl.SSLException: Connection reset"
So the cause we predict is since no request came with in 500s, from CDN side it closed the connection but from client side (spring boot app) was not acknowledged and it still keep the tomcat socket connection open and then the first request utilize that broken connection would face this exception. or any different cause?
So get rid of it I set below connection timeout value, assuming it would explicitly closed any idle connection of tomcat embedded server, which are over 10s and this issue would get resolved.
But even after adding this i still get the exception like above same way.
#Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.setReadTimeout(Duration.ofMillis(60000))
.setConnectTimeout(Duration.ofMillis(10000)).build();
}
What could be the issue here?

javax.jms.JMSException: Could not post command: KeepAliveInfo

Short description of the issue:
I'm using ActiveMQ 5.10.2 (AMQ) in a project where I have Application A sending data over to Application B via amq and saw this exception :
javax.jms.JMSException: Could not post command: KeepAliveInfo
Here's the full stack trace:
ERROR JMSConsumer:148 - Consumer Exception
javax.jms.JMSException: Could not post command: KeepAliveInfo {} due to: java.net.SocketTimeoutException: Read timed out
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:54)
...
Caused by: java.io.IOException: Could not post command: KeepAliveInfo {} due to: java.net.SocketTimeoutException: Read timed out
at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:33)
at org.apache.activemq.transport.http.HttpClientTransport.oneway(HttpClientTransport.java:138)
...
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
That exception was seen in App B and due to this exception it could not connect to the AMQ. Restarting the app allowed it to talk to the AMQ again.
Does anyone know how I can reproduce that exception so I can do proper error handling/recovery?
More details about the issue:
As mentioned above, I'm trying to recreate the exception to do proper error handling/recovery. But so far I'm unable to reproduce it.
I've looked online and don't see too much on this specific exception nor on the keepaliveinfo message other than from activemq's own site.
Per its link https://activemq.apache.org/activemq-inactivitymonitor if the useInactivityMonitor parameter is set to true, which is the default value, then the apps connecting to that AMQ on the same topic/queue will have that keepaliveinfo message sent if it doesn't detect any normal traffic. In my environment that parameter is set to true
My thought is, with this value set to true, something happened in my environment (perhaps the AMQ got in a funky state or was low in memory) that it failed to handle a keepaliveinfo message sent from my apps and then that jms exception occurred.
In trying to reproduce that exception I have done the following tests to no avail:
Test 1:
Start App A, App B and the AMQ. After everything is up and running and data is flowing I would then stop the AMQ broker.
I got this exception :
javax.jms.JMSException: Failed to perform GET on: <my amq ip>:443 Reason: Connection refused: connect
Which isn't the exception I noticed before.
Test 2:
I would start App A, App B, and the AMQ, and then after everything is up and running I would then stop App A (which sends data to App B via AMQ).
I did not witness any keepaliveinfo messages getting sent and more importantly I don't see the specific jms exception above.
Test 3:
I started App B and the AMQ. I modified App A to connect to the AMQ but commented out the code that sends data to App B on the queue/topic.
Again I did not witness this message JMSException: could not post command: keepaliveinfo
Test 4
I modified the AMQ broker activemq.xml file to have its <memoryUsage> <storeUsage> and <tempUsage> values to be really low. In a way to simulate that the ActiveMQ is super busy and can't handle more data being sent. More info on those parameters are mentioned here https://activemq.apache.org/producer-flow-control.html
After restarting AMQ and App A and App B, I still didn't witness that exception message.
End of tests
So again, does anyone know what is the setup/conditions on reproducing this issue?
Extra note:
It seems like I can avoid this exception altogether if I set the useInactivityMonitor parameter to false. With that set then no keepaliveinfo messages are sent if no normal traffic occurs over a connection. But I don't want to change it to false.
And here is my pom file defining the amq artifact id's:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.10.2</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-http</artifactId>
<version>5.10.2</version>
</dependency>

How to load JMS configuration from a .bindings file in Spring

I am still new with Spring and Ibm/mq but I am using JMSTemplate in a Spring project (build with maven) to send messages to a MQ. It works fine when I use the application.propeties file to define the MQ server infos.
Now I am triyng to do the same with a ".bindings", the binding file that I generated from my MQ server. It has lines like: QUEUE_CONNECTION_FACTORY_NAME/ClassName=com.ibm.mq.jms.MyQueueConnectionFactory
Can I use JMSTemplate to load the configuration from that binding file? How?
What I know is that the main way to use this file is with a JNDI FSContext, But I did not find how:
Where do you put the .bindings file?
How do you load it? (and do you load from a bean xml or from a context in the java code)
Is it even possible? I saw some old messages on a board saying that: "Spring does not support a .binding file. Any configuration items in the .binding file need to be translated into the appropriate Spring XML configuration."
In the other side I have this that have an incomplete answer to my question:
How to load JNDI context from the file system into Spring?
I have an overload of information but not a simple how to do this.
EDIT:
Now I can load the content of the file but it seems not compatible.
My code is like this:
environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory");
environment.put(Context.PROVIDER_URL, "file:/Users/user/jndi");
Context mycontext = new InitialContext( environment );
ConnectionFactory connectionFactory = (ConnectionFactory) mycontext.lookup("QCONNECTION_FACTORY");
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(connectionFactory);
MQQueue dest = (MQQueue) mycontext.lookup("LQ1");
//Connection connection = connectionFactory.createConnection("***","***");
//Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
jmsTemplate.convertAndSend(dest, "hello");
My queue jndi info:
LQ1/RefAddr/12/Type=MDCTX
LQ1/RefAddr/12/Encoding=String
LQ1/RefAddr/12/Content=0
LQ1/RefAddr/16/Content=LQ1
LQ1/RefAddr/16/Type=QU
and the JMSAdmin script:
DEF Q(LQ1) QUEUE(LQ1)
def qcf(QCONNECTION_FACTORY)transport(CLIENT)channel(DEV.APP.CHANNEL)host(localhost)port(1414)qmgr(QM1)
end
But I am getting:
org.springframework.jms.JmsSecurityException: JMSWMQ2008: Failed to open MQ queue 'LQ1'.; nested exception is com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2008: Failed to open MQ queue 'LQ1'
JMS attempted to perform an MQOPEN, but IBM MQ reported an error.
Use the linked exception to determine the cause of this error. Check that the specified queue and queue manager are defined correctly.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2035' ('MQRC_NOT_AUTHORIZED').

V5 Messaging Provider with ListenerPort

I configured a queue and a QueueConnectionFactory using the V5 Messaging provider in WebSphere Application Server 6.1.
I also have a ListenerPort configured for this destination.
It throws an exception when I try to connect to this queue using the queue connection factory or when the Message Listener listening to this ListenerPort starts up.
javax.jms.JMSException: MQJMS2005: failed to create MQQueueManager
for 'localhost:WAS_Node01_server1'
and the nested exception is
com.ibm.mq.MQException: MQJE001: An MQException occurred: Completion Code 2, Reason 2059
MQJE011: Socket connection attempt refused
Can someone please point me to what possibily could have gone wrong in configuring the queue and queue connection factory?
The error indicates that the WebSphere MQ transport is being used. Per the clarification in your comments, no queue manager is present so a 2059 is expected. It will be necessary to configure a WAS messaging Engine to provide the native transport or to point to a queue manager.

Categories