With AWS Java SDK v1, you can subscribe SQS queue to an SNS topic using the method Topics.subscribeQueue where the endpoint object takes in queueUrl as shown below :
Topics.subscribeQueue(sns, sqs, myTopicARN, queueURL);
With AWS Java SDK v2, you can subscribe an SQS queue to an SNS topic using the method SunscribeRequest.builder where the endpoint object takes in queueArn.
Below is a sample java code snippet that I have tested to successfully subscribe an SQS queue to an SNS topic:
public static void subscribeSQStoSNS(String queueUrl, String topicArn, SqsClient sqsClient, SnsClient snsClient) {
/* with AWS Java SDK v1, you could subscribe an SQS queue to an SNS topic by
* calling "Topics.subscribeQueue"()[1] where the endpoint object takes in queueUrl.
*
* with AWS Java SDK v2, to subscribe an SQS queue to an SNS topic
* one needs to use "SunscribeRequest.builder"() [2] where the endpoint object takes in queueArn.
*
* [1] https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sns/util/Topics.html
* [2] https://sdk.amazonaws.com/java/api/2.0.0-preview-11/software/amazon/awssdk/services/sns/model/SubscribeRequest.Builder.html
*
*/
// Step 1: We call "get-queue-attributes" API to retrieve the SQS queue Arn
GetQueueAttributesRequest QueueAttributesRequest = GetQueueAttributesRequest.builder()
.queueUrl(queueUrl)
.attributeNamesWithStrings("All")
.build();
GetQueueAttributesResponse QueueAttributesResult = sqsClient.getQueueAttributes(QueueAttributesRequest);
Map<String, String> sqsAttributeMap = QueueAttributesResult.attributesAsStrings();
System.out.println("\n\n"+ QueueAttributesRequest);
String queueArn = sqsAttributeMap.get("QueueArn");
//System.out.println("\n\n"+ queueArn);
// Step 2: We call "SubscribeRequest.builder" to subscribe the SQS queue to the SNS topic
SubscribeRequest Qrequest = SubscribeRequest.builder()
.protocol("sqs")
.endpoint(queueArn)
.returnSubscriptionArn(true)
.topicArn(topicArn)
.build();
SubscribeResponse Qresponse = snsClient.subscribe(Qrequest);
System.out.println("\n\nCreated Subscription ARN: " + Qresponse.subscriptionArn()+ " " + " and StatusCode : " + Qresponse.sdkHttpResponse().statusCode());}
Note:
1. The "Topics.subscribeQueue"() method automatically creates a policy for the subscription to allow the topic to send messages to the queue.
2. The "SunscribeRequest.builder"() method does not automatically add a policy for the subscription (i.e SQS queue) so as to allow the SNS topic to send messages to the queue. Therefore make sure you've given SNS topic permission to publish to the SQS queue by adding the following sample policy to the SQS queue as shown below and also as described here:
{
"Statement": [{
"Effect":"Allow",
"Principal":"*",
"Action":"sqs:SendMessage",
"Resource":"arn:aws:sqs:us-east-2:123456789012:MyQueue",
"Condition":{
"ArnEquals":{
"aws:SourceArn":"arn:aws:sns:us-east-2:123456789012:MyTopic"
}
}
}]
}
You can find the complete code in github here : https://gist.github.com/syumaK/79c946ed4e618c1f871f50ecb1819a0f
Hope this helps.