getting null response from recieveAndConvert() spring -amqp - spring-amqp

I have created on replyQ and done biniding with one direct exchange.
Created the message by setting replyto property to "replyQ"
And sending the message on rabbit to the other service.
The service at other end getting the message and sending reply on given replyTo queue.
and now I am trying to read from a replyQ queue using
template.receiveAndConvert(replyQueue));
But getting null response and i can see the message in the replyQ.
That is the service is able to send the reply but am not able to read it from the given queue
Please help what is going wrong.

template.receiveAndConvert() is sync, blocked for some time one time function, where default timeout is:
private static final long DEFAULT_REPLY_TIMEOUT = 5000;
Maybe this one is your problem.
Consider to switch to ListenerContainer for continuous queue polling.
Another option is RabbitTemplate.sendAndReceive(), but yeah, with fixed reply queue you still get deal with ListenerContainer. See Spring AMQP Reference Manual for more info.

I don't know if this could help anyone, but I found out that declaring the expected Object as a parameter of a method listener did the work
#RabbitListener(queues = QUEUE_PRODUCT_NEW)
public void onNewProductListener(ProductDTO productDTO) {
// messagingTemplate.receiveAndConvert(QUEUE_PRODUCT_NEW) this returns null
log.info("A new product was created {}", productDTO);
}

Related

Proper way to NOT send a reply back from webhook

I have setup a webhook and everything is working properly, however iam used to using a long number where STOP is handled automatically, but now I have a short code where we have to handle STOP ourselves. This isnt an issue on sending a message as I can check with my 'blacklist' numbers before sending the message. My question is in the Reply webhook, what is the best way or standard way to NOT send the reply message.
Below is twilios sample code (i added the comment where i would check if they are black listed)
public class SmsController : TwilioController
{
public TwiMLResult Index(SmsRequest incomingMessage)
{
var messagingResponse = new MessagingResponse();
// check for phone number in blacklist to NOT SEND
messagingResponse.Message("The copy cat says: " +
incomingMessage.Body);
return TwiML(messagingResponse);
}
}
If the number is blacklisted and i dont want to send the reply how do I "gracefully" not reply to them as this example takes a TwiMLResult and message response. Do i just set the message to an empty string ? do I return null? Any thoughts ? Thank you !

Spring cloud AWS - send message to fifo queue

I'm using spring-cloud-aws to send a message to SQS FIFO queue.
It's failing with
The request must contain the parameter MessageGroupId
There doesn't seem to be anywhere on the QueueMessagingTemplate in spring-cloud-aws-messaging that allows me to set this mandatory MessageGroupId.
Is there currently a way of writing to a SQS FIFO queue in this manor or would I have to revert to directly using amazons API?
Spring Cloud AWS support FIFO queues since 2017, in accordance with: Add Support for FIFO SQS Queues #252
You just need to add the two required params(messageGroupId and messageDeduplicationId) like example below:
public void send(String topicName, Object message, String messageGroupId, String messageDeduplicationId) throws MessagingException {
Map<String, Object> headers = new HashMap<>();
headers.put("message-group-id", messageGroupId);
headers.put("message-deduplication-id", messageDeduplicationId);
messagingTemplate.convertAndSend(topicName, message, headers);
}
I dont believe that FIFO support is possible with versions 1.1.x of spring-cloud-aws due to how the QueueMessagingTemplate uses a QueueMessagingChannel that does not support configuring the SendMessageRequest in this way.
Examine https://github.com/spring-cloud/spring-cloud-aws/blob/master/spring-cloud-aws-messaging/src/main/java/org/springframework/cloud/aws/messaging/core/QueueMessageChannel.java#L78 for details.
I have opened https://github.com/spring-cloud/spring-cloud-aws/issues/246 for this reason, though have no idea if support will be added.
It also does not appear that I can use a custom QueueMessageTemplate; this would be a reasonable workaround if I could.

How SignalR manages connection between Postbacks

1> Just want to understand how SignalR 1.x functions in a particular scenario
Lets say we have a 10 clients connected to Hub and one of the connected clients say client-1 performs a postback so OnDisconnected is called than OnConnected is called right ?
What happens if during this phase if client-2 try's to send message to client-1 exactly between the said scenario ie (msg is sent after client-1 is disconnected and before connected again )will client-1 miss the message or there's internal mechanism which makes sure client-1 does not miss the message sent by client-2
2> Second query I have is that I'm trying to pass a querystring using following code
var chat = $.connection.myHub;
$.connection.myHub.qs = { "token": "hello" };
but not able to retrieve it on the server side from the Context object
using
Context.QueryString.AllKeys
I even tried
var chat = $.connection.myHub;
$.connection.myHub.qs = "token=hello" ;
But it does not work ie when I check the keys, token is not present in AllKeys
Will appreciate if someone just help me out.
1: If a postback occurs a client will disconnect and then connect. However, when the client performs a connect again it will have a different Connection Id than it had prior to the postback. Therefore, any message sent to the old connection id will be missed because when the users browser connects again it will be known as a different client.
2: You're trying to set the query string on the hub proxy, not the connection. What you should be doing is:
$.connection.hub.qs = { foo: "bar" };

How to send and receive domain objects with rabbitMQ plugin and grails

I've went over the excellent documentation for the rabbitMQ plugin. However, I am still confused about a few things.
Scenario
My application will take a file upload from the user, do various things to the file and accordingly set certain properties on the domain object. Some of this work can be labor intensive so I am using a queue. I envision requests being queued and the consumer picking up the requests from the queue and consuming them.
Questions
I want to store a domain object in the queue. I do this by: rabbitSend 'myqueue', colorObj. colorObjis an object of domain class Color
However, in the ColorService handleMessage(...) When I fetch the item from the queue, the item is not of type Color. Please note that on the rabbitMQ dashboard I can see the items being inserted in the queue, so my queue initiation in config.groovy is fine (I am using amq.direct)
How can I send and fetch a domain object from the queue?
From the behavior I've seen thus far, the handleMessage does not need to be instantiated. Even if I don't call the ColorService it still executes handleMessage by itself. Is that a normal behavior?
Below is the code:
controller
Color colorObj = colorService.newRequest(params, request.getFile('color.filename')
if (colorObj.validate)
rabbitSend 'myqueue', colorObj
...
service
class ColorService {
static rabbitQueue = 'myqueue'
void handleMessage(message) {
println "came in message: " + message instanceof Color //this prints false
}
}
As Tim says, if you can get by with just passing the domain instance ID that is simplest. You do need to be careful of changes to the domain instance while the message is in transit though.
Alternatively, if it's the data you're interested in, I prefer to serialise the objects as JSON using something like
rabbitSend 'myqueue', (colorObj as JSON).toString()
Of course, now your listener is receiving a string, so you'll have to convert it back:
void handleMessage(String message) {
def color = new Color(JSON.parse(message))
println "came in message: " + color instanceof Color
}
There is a little bit of discussion around this on the GPRABBITMQ-15 issue.
As it shows in the documentation, you can either send a String or a Map
Why not send the id of your domain object:
rabbitSend 'myqueue', colorObj.id
Then, load it back in when the message is processed:
void handleMessage(message) {
println "Got ${Color.get( message )}"
}
Or, if you don't need the domain object until the message is processed, send a map of all the required data, and have the service create the domain object after it is processed successfully?

How can I apply timeout function to LMAX Disruptor Queue?

To developers/users of LMAX Disruptor http://code.google.com/p/disruptor/ :
My question:
Can anyone suggest an approach to how apply a timeout function to Disruptor e.g. using EventHandler?
Here is one scenario that came up in my line of work:
Outbox - messages sent to the Server over a network
Inbox - ACK messages received from the Server
ACK Handler - marks outbox messages as ACKed
Timeout Handler - marks outbox message as NACKed (much needed, but where can it fit into the Disruptor design?)
Is there anyone who share the same opinion?
Or can anyone point out why it is unnecessary.
I hope the ensuing debate would be brief.
Thank you.
To clarify the timeout-handler would "fire" after a certain period of time when a message could not be delivered?
The way it works with disruptor is you have a ringbuffer for inbound and a ringbuffer for outbound messges... so email comes in, place it into the inbound ring buffer using an appropriate event. then process the message (i.e. decode, analye, log, store) and send it along to another sytem by placing it into the outbound ringbuffer... another handler takes the message and stores it into a database or sends it to another server using smtp... if a error / timeout etc. occurs, your create an event in the inbound ringbuffer signaling the error (NACK) and process this message. does that make sense?!?

Resources