spring-boot-starter-artemis with AMQP protocol - spring-boot

I was following the https://docs.spring.io/spring-boot/docs/2.0.0.M3/reference/html/boot-features-messaging.html#boot-features-artemis guide.
With Core protocol with JMS, app is able to send message to Artemis broker.
spring.artemis.mode=native
spring.artemis.host=<broker host>
spring.artemis.port=61616
spring.artemis.user=admin
spring.artemis.password=<password>
When I switched to AMQP protocol with 5672 port, I am getting below error.
spring.artemis.mode=native
spring.artemis.host=<broker host>
spring.artemis.port=5672
spring.artemis.user=admin
spring.artemis.password=<password>
Caused by: org.apache.activemq.artemis.api.core.ActiveMQConnectionTimedOutException: AMQ219013: Timed out waiting to receive cluster topology. Group:null
at org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:712) ~[artemis-core-client-2.12.0.jar:2.12.0]
at org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.createConnectionInternal(ActiveMQConnectionFactory.java:884) ~[artemis-jms-client-2.12.0.jar:2.12.0]
... 68 common frames omitted
what changes I have to make along to enable transition over AMQP protocol in my spring boot app? Thanks.

In order to use the AMQP protocol you'd need to somehow force Spring to use the Qpid JMS client implementation rather than ActiveMQ Artemis' core JMS client implementation, but I don't believe that is possible.

Related

Is it possible to use OpenWire protocol with spring-boot-starter-artemis?

I set up ActiveMQ Artemis consumer using spring-boot-starter-artemis and JMS. I also launched broker locally and I aim to configure these to communicate over OpenWire protocol. To constrain communication to that protocol I modified acceptor in broker.xml (protocols=OPENWIRE). It looks like that:
<acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>
However, unfortunately I'm getting the following error:
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Failed to create session factory; nested exception is ActiveMQConnectionTimedOutException[errorType=CONNECTION_TIMEDOUT message=AMQ219013: Timed out waiting to receive cluster topology. Group:null]
How can I configure the client to use OpenWire protocol?
What is the default protocol they communicate on? Before I constrained the communication, Artemis Console was presenting the connection has been established on CORE protocol, which as far as I understand collective protocol. Which one i target protocol they really communicate on and how can I check this out?
The reason you're receiving ActiveMQConnectionTimedOutException is because you trying to use spring-boot-starter-artemis to connect to an acceptor which is configured to only support the OpenWire protocol. This will never work because spring-boot-starter-artemis depends on artemis-jms-client which will only use the ActiveMQ Artemis "core" protocol, not OpenWire.
You should configure the acceptor in broker.xml to support core, e.g.:
protocols=CORE,OPENWIRE
If you want the client to use OpenWire then you need to use the OpenWire JMS client library from ActiveMQ "Classic."

Does ActiveMQ uses TCP as its transport layer protocol

I've encounter a problem where our WebSocket connections to ActiveMQ 5.13.3 are terminated abruptly. I thought, I might use WireShark to inspect the TCP layer for clues why the connection may be corrupted, but I'm not sure the ActiveMQ uses TCP protocol as its transport layer protocol for sending the messages.
All the kinds of clients and protocols which ActiveMQ supports use TCP as their transport layer. WebSockets specifically use TCP.
ActiveMQ Broker supports many transport layer protocols, including TCP.
References:
If you are using ActiveMQ Classic:
https://activemq.apache.org/components/classic/
If you are using ActiveMQ Artemis:
https://activemq.apache.org/components/artemis/

ActiveMQ 5 redelivery policies ignored with AMQP

I have a Spring Boot application using Qpid JMS to speak AMQP with an ActiveMQ 5.15.14 broker. Even though the redelivery plugin is configured, the redelivery policies of the broker are ignored. However the redelivery policy of the client (Qpid) does come into play.
When the exact same code and client configuration is connected to a ActiveMQ Artemis broker, the redelivery policy of the broker kicks in which is what I'm looking for.
Anything you are aware of that could explain this different behavior between ActiveMQ 5 and ActiveMQ Artemis? Both brokers are using pretty much OOTB configuration aside from the redelivery policies, and schedulerSupport is enabled in my ActiveMQ 5 broker as well. Here's what the redelivey configuration looks like in activemq.xml:
<redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
<redeliveryPolicyMap>
<redeliveryPolicyMap>
<defaultEntry>
<redeliveryPolicy initialRedeliveryDelay="5000" maximumRedeliveries="9" redeliveryDelay="60000" />
</defaultEntry>
</redeliveryPolicyMap>
</redeliveryPolicyMap>
</redeliveryPlugin>
One more thing to consider : the redelivery policies of the ActiveMQ 5 broker are applied when I use Openwire (JMS) instead of AMQP.
The AMQP protocol head in ActiveMQ 5.x is far more primitive than that of the Artemis broker implementation and is likely not reacting correct to the dispositions that are being sent back from the AMQP client. Also the 5.x broker can react differently based on the transformer setting in the 'transportConnector' on the broker which can be one of JMS, NATIVE or RAW. The JMS transformer will give the most ActiveMQ compatible behaviour but requires a complete transformation internally to an OpenWire message and then back to AMQP when going from AMQP sender to AMQP receiver which can hurt performance significantly. The NATIVE transformation will attempt to preserve some insights into the redelivered state of the message but won't catch every case most likely. With the RAW mode there will be no insight into the message delivery count at all and as such you definitely won't get any redelivery processing on the broker side.
I short, if you are looking for a fully functional AMQP broker then choose Artemis as it has had a lot of work, if you just need something that can get messages flowing then 5.x should work but don't expect the same quality of service.

Can we send messages between two clients using different protocols(STOMP - TCP) with ActiveMQ?

I have a scenario , where i have my sender code written in Node.js which uses STOMP protocol to publish it to the destination(queue) and the receiver code written in java which use TCP protocol to receive the message from the destination(queue) through ActiveMQ server.Will it be possible for the clients(sender/receiver) to communicate? or it should be the same protocol at either end?
The ActiveMQ documentation covers this on the Stomp page (http://activemq.apache.org/stomp.html) in the paragraphs
Working with JMS Text/Bytes Messages and Stomp
Message transformations
Stomp extensions for JMS message semantics
ActiveMQ extensions to Stomp
ActiveMQ supports richt message conversion between messages from different protocols. Not all multi-protocol have this feature, for example ActiveMQ Apollo (issue 267).
Not an issue. ActiveMQ acts as a multiprotocol message exchange so messages received by the broker in any supported protocol can in turn be sent to receivers in any other supported protocol.

How does Spring mange websocket connections to RabbitMQ?

I have a game server that uses websocket for real time multiplayers. It is a Spring 4 application and I use RabbitMQ as my broker. This is my configuration:
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/portfolio">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/queue, /topic"/>
</websocket:message-broker>
From a very small test with 4 clients I saw 4 connections open on Rabbit.
Does each client that connects to my server using websocket eventually open a new connection to the broker (RabbitMQ)? Can this be configured?
Yes, each websocket client gets its own TCP connection to the broker. The documentation has a section for connections to the broker (emphasis mine):
A STOMP broker relay maintains a single "system" TCP connection to the broker. This connection is used for messages originating from the server-side application only, not for receiving messages. [...]
The STOMP broker relay also creates a separate TCP connection for every connected WebSocket client. [ ... ]
If this can be configured or not I don't know, I'm not all that familiar with this part of Spring, but I assume it should be; Spring is open to extension. My suggestion is to post an issue on the spring-websocket-portfolio project and ask for specifics.
EDIT : OP opened the following issue on the spring-websocket-portfolio project.

Resources