5

When I create a new queue and subscribe it to a topic in Java, no message comes. The same via the AWS web console works fine.

I guess I have to confirm the subscription somehow, but the sns.confirmSubscription method needs a token - where shall I get it?

This is my Java code:

String queueURL = sqs.createQueue("my-queue").getQueueUrl();

sns.subscribe(myTopicARN, "sqs", queueURL);

sns.publish(myTopicARN, "{\"payload\":\"test\"}");

sqs.receiveMessage(queueURL).getMessages()
        .forEach(System.out::println);  // nothing

What am I doing wrong?

Barney
  • 797
  • 1
  • 11
  • 20
  • Your IAM user may have required permission when doing it from console. You may need to check credentials used by the SDK have correct permissions. – A.Khan Feb 08 '19 at 11:25
  • 1
    @A.Khan I actually created an admin user and using its credentials by setting `AWS_PROFILE=user-from-credentials` – Barney Feb 08 '19 at 11:33
  • @A.Khan anyway, in this case I would expect an exception... – Barney Feb 08 '19 at 11:35
  • true. have you enabled long polling in the queue? – A.Khan Feb 08 '19 at 11:37
  • No, I wrote just the actual code you can see above. Do I need this when the message is sent and received immediately? – Barney Feb 08 '19 at 11:43
  • by default SQS uses short polling and message published to SNS topic may not be available in the queue immediately when you call receiveMessage api. Try enabling [long-polling](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/examples-sqs-long-polling.html) – A.Khan Feb 08 '19 at 11:47

2 Answers2

6

Check this out: https://aws.amazon.com/blogs/developer/subscribing-queues-to-topics/

You should subscribe like this:

Topics.subscribeQueue(sns, sqs, myTopicARN, queueURL);

This convinient method creates a policy for the subscription to allow the topic to send messages to the queue.

ttulka
  • 10,309
  • 7
  • 41
  • 52
0

subscribing the queue to sns does not automatically create a policy to allow sns to send messages to the queue (based on my experience with sns/sqs) so you need to create the policy yourself and give permission to sns to send messages to your queue this is an example on how to do it using queue url , queue arn and topic arn

import static com.amazonaws.auth.policy.Principal.All;
import static com.amazonaws.auth.policy.Statement.Effect.Allow;
import static com.amazonaws.auth.policy.actions.SQSActions.SendMessage;
import static com.amazonaws.auth.policy.conditions.ArnCondition.ArnComparisonType.ArnEquals;

final Statement mainQueueStatements = new Statement(Allow) //imported above
        .withActions(SendMessage) //imported above
            .withPrincipals(All) //imported above
            .withResources(new Resource(queueArn)) // your queue arn
            .withConditions(
                    new Condition()
                            .withType(ArnEquals.name()) //imported above
                            .withConditionKey(SOURCE_ARN_CONDITION_KEY) //imported above
                            .withValues(topicArn) // your topic arn
            );
    final Policy mainQueuePolicy = ()
            .withId("MainQueuePolicy")
            .withStatements(mainQueueStatements);
    final HashMap<QueueAttributeName, String> attributes = new HashMap<>();
     attributes.put(QueueAttributeName.Policy.toString(), mainQueuePolicy.toJson());
    amazonSQS.setQueueAttributes(new SetQueueAttributesRequest().withAttributes(attributes).withQueueUrl(queueUrl)); // your queue url
Bilel BM
  • 21
  • 4