Using SqsListener with SNS and SQS

msp picture msp · Apr 11, 2016 · Viewed 11.3k times · Source

I'm using spring-cloud-aws's SqsListener to receive AWS SNS HTTP Notifications in JSON Format from AWS's Simple Queue Service (SQS).

This is the code for the listener:

@SqsListener(value = "my-queue", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void handle(final MyObject obj) throws Exception {
// ...
}

The documentation linked above is only about sending and reading plain serialized objects to the Queue and I thought that receiving SNS messages is expected to work out of the box. But I end up receiving conversion errors:

10:45:51.480 [simpleMessageListenerContainer-2] ERROR o.s.c.a.m.l.SimpleMessageListenerContainer - Exception encountered while processing message. org.springframework.messaging.MessagingException: An exception occurred while invoking the handler method; nested exception is org.springframework.messaging.converter.MessageConversionException: No converter found to convert to class com.myproject.model.MyObject, message=GenericMessage

I also tried creating a wrapper object that looks like the expected SNS Json Format linked above, but I keep getting the same exception. The only type that works is a String in the signature. Shouldn't the SNS be converted automatically?

Answer

msp picture msp · Apr 11, 2016

Yes it should. And it does actually.

In order to have the correct HandlerMethodArgumentResolver invoked (in this case NotificationMessageArgumentResolver) on deserialization, which in turn invokes the correct converter NotificationRequestConverter you simply need to add the annotation org.springframework.cloud.aws.messaging.config.annotation.NotificationMessage to your method signature. E.g.

@SqsListener(value = "my-queue", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void handle(final @NotificationMessage MyObject obj) throws Exception {
// ...
}

This way the Message part of your SNS gets extracted and converted to MyObject.