I have inbound gateway(ig1) which has reply channel(rep1) which has HTTP outbound gateway which calls one internal API and send response back to reply channel(rep1)
I have another inbound gateway(ig2) which has reply channel(rep2)
Can I send response from rep2 to rep1 basically how can I connect 2 reply channels, and can it be done?
Related
I have a sample message flow where a TCP Output Node communicates to an external system and receives response to a TCP Client receive node. My issue is, is there a way whether I can ensure that the TCP request and TCP response are correctly mapped and processed. We have observed in certain circumstances few request and responses getting mismatched. I understand there is a $LocalEnvironment/Destination/TCPIP/Output/Id property in the TCP IP Client Output Node and $LocalEnvironment/TCPIP/Receive/Id in the TCP IP Client receive Node. Should these be same for a single request and response? Should I write an ESQL check to ensure the request and response are correlated? Any advice would be very much helpful.
I am using Artemis 2.6.2 with STOMP only and the following constellation:
Broker:
No queues configured in broker.xml, everything is auto created.
Server:
SUBSCRIBE to destination TaskResponse without selector/filter
SEND to destination TaskRequest with header clientId = ID (the ID of the client what the server would request to)
Client 123:
SUBSCRIBE to destination TaskRequest with selector clientId = 123
SEND to destination TaskResponse with header clientId = 123
When I watch at the Artemis Console the following happens:
No server and no client is connected: No address or queue is present
Server connect: Artemis creates a multicast address TaskResponse and a multicast queue for this address with empty filter
Client 123 connect: Artemis creates a multicast address TaskRequest and a multicast queue for this address with filter clientId = 123
Message exchange: Messages are transfered from server to client and back to server as expected.
Client 123 disconnect: Artemis removes the multicast address TaskRequest and the coresponding multicast queue with filter clientId = 123
Server sends message to TaskRequest for client 123: According to STOMP client on server the message is sent successful. On the broker the message disappears.
Same behavior vice versa: Client 123 is connected and server is not: According to STOMP client on client 123 the message is sent successful. On the broker the message disappears.
My guess is that the message is discarded because there is no route to a subscriber. If I enable the option "send-to-dla-on-no-route" in address-settings section of broker.xml the message goes directly to dead letter queue.
Do you know a way to preserve the messages until the subscriber reconnects?
Appendix 1: STOMP Messages
I am using the Stomp.Net Library with SelectorsCore Example but reduced only to selector s1. The workflow is a bit other than what I wrote above.
Unfortunately I did not found an example to enable logging of STOMP messages into a file in Artemis. Therefore I recorded the packets with WireShark, exported as text and uploaded into Gist StompMessages.txt. You can see there the diffrent STOMP messages, e.g. search for CONNECT, SEND, etc.
Solution
The solution was to use the option anycastPrefix=/queue/ in the acceptor element in broker.xml to force the queues to type ANYCAST:
<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true;anycastPrefix=/queue/</acceptor>
What you are observing is the expected behavior. If you send a message to an address with no queues (or in STOMP terms - a destination with no subscribers) then the message will have nowhere to go and will be discarded. This is normal pub/sub semantics.
If you want to preserve the messages even if no subscriber is present you can either:
Use anycast (i.e. point-to-point) semantics rather than multicast. This is discussed in the Artemis documentation.
Use "durable" STOMP subscribers as discussed in the Artemis documentation. The caveat here is that the subscription will still need to be created before messages are sent and you will also need to make sure you remove the subscription when you are done with it or it may accumulate messages.
Is there a mechanism in the SMS protocol to associate a response with the message it is responding to? Does a reply carry with it any piece of data that would uniquely identify the message it is responding to?
I'm implementing a tcp client which will send request to a server and expect an response. But when the client 1st connect to the server, the server will send a hello msg, with tcp outbound gateway, it expects to send then receive. How can I do receive (only when first connect) then do my usually send and receive logic? And if I need to keep the connection alive, is there a way to send keep alive msg to the same connection by some scheduling task?
Instead of a gateway use Collaborating Channel Adapters for completely async operations.
Collaborating adapters can also be used (server-side or client-side) for totally asynchronous communication (rather than with request/reply semantics).
You can use operating system keep alives (SO_KEEPALIVE). Or you can roll your own application-level keep alives with a polled inbound channel adapter...
<int:inbound-channel-adapter channel="toTcp" expression="'foo'">
<int:poller fixed-delay="60000" />
</int:inbound-channel-adapter>
I am trying to use spring integration and bit confused about outbound gateway. Below is my question.
This is what I understand about outbound gateway.
Spring integration amqp outbound gateway takes messages from requestChannel and write it to rabbitmq queue (requestQueue) and waits for reply on rabbitmy replyQueue. Once the reply is available, it reads and add it to responseChannel.
The question is, if multiple requests are being sent concurrently by multiple job instances and responses for different requests by different jobs are available on same rabbitmq replyQueue.
Then how does outbound gateway choose responses ? Does it use correlation id to fetch only responses to request sent by the same gateway and ignores other responses ?
It depends on how the gateway is configured; by default a separate (auto-delete) reply queue is created for each request.
If it is configured with a RabbitTemplate that uses an explicit reply queue (and a reply-listener), the template does the correlation internally, by setting a correlationId on the message. That way, each reply is returned to the proper caller.
You need to be sure to set the reply-timeout on the outbound gateway to a large enough value; it defaults to 5 seconds.
EDIT:
Note that in order to concurrently run jobs (per your other question), you must use the default reply routing and not a dedicated reply queue. Unlike JMS, AMQP does not have a message selector so you can't have multiple gateways using the same reply queue.