java - 如何在我的 Java 应用程序中使用 Amazon Web Services 策略声明?

标签 java amazon-web-services amazon-sqs amazon-sns spring-cloud

我想从后端 Java 应用程序将 Amazon SNS 消息发送到 Amazon SQS 队列。根据 SNS 开发人员指南 ( http://docs.aws.amazon.com/sns/latest/dg/sns-dg.pdf ),在“将 Amazon SNS 消息发送到 Amazon SQS 队列” 部分的主题 - “步骤 2. 授予权限”中到 Amazon SNS 主题以将消息发送到 Amazon SQS 队列”,写为,

If you wanted to create the policy document yourself, you would create a policy like the following. The policy allows MyTopic to send messages to MyQueue.

{
  "Version":"2012-10-17",
  "Statement":[
  {
    "Sid":"MySQSPolicy001",
    "Effect":"Allow",
    "Principal":"*",
    "Action":"sqs:SendMessage",
    "Resource":"arn:aws:sqs:us-east-1:123456789012:MyQueue",
    "Condition":{
                  "ArnEquals":{
                     "aws:SourceArn":"arn:aws:sns:us-east-1:123456789012:MyTopic"
                   }
              }
         }
    ]
}

我的疑问是如何在我的java应用程序中使用这个策略文档(.json文件,如果我没记错的话)以及在哪里使用它?因为我必须在队列上设置一个策略,以允许 Amazon SNS 主题执行 sqs:SendMessage 操作。 TIA。

最佳答案

下面是一个 Java 示例,用于创建 SNS 主题和 SQS 队列、将 SQS 队列订阅到 SNS 主题、授予 SNS 向队列发送消息的权限、向 SNS 发送消息并从队列中读取消息。

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.policy.Condition;
import com.amazonaws.auth.policy.Policy;
import com.amazonaws.auth.policy.Principal;
import com.amazonaws.auth.policy.Resource;
import com.amazonaws.auth.policy.Statement;
import com.amazonaws.auth.policy.actions.SQSActions;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.RegionUtils;
import com.amazonaws.services.sns.AmazonSNS;
import com.amazonaws.services.sns.AmazonSNSClient;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClient;
import com.amazonaws.services.sqs.model.CreateQueueRequest;
import com.amazonaws.services.sqs.model.Message;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.amazonaws.services.sqs.model.ReceiveMessageResult;
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;

import java.util.Arrays;
import java.util.Optional;

public class CreateSnsAndSqs {
    private static final String SNS_TOPIC = "my-sns-topic";
    private static final String SQS_NAME = "my-sqs-queue";

    public static void main(String... argv) {
        String regionName = Optional.ofNullable(System.getenv("AWS_DEFAULT_REGION")).orElse("us-east-1");
        Region region = RegionUtils.getRegion(regionName);
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        // AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
        DefaultAWSCredentialsProviderChain credentialsChain = new DefaultAWSCredentialsProviderChain();
        AmazonSNS sns = region.createClient(AmazonSNSClient.class, credentialsChain, clientConfiguration);
        AmazonSQS sqs = region.createClient(AmazonSQSClient.class, credentialsChain, clientConfiguration);
        String sqsUrl = sqs.createQueue(new CreateQueueRequest(SQS_NAME)).getQueueUrl();
        String snsTopicArn = sns.createTopic(SNS_TOPIC).getTopicArn();
        String sqsArn = sqs.getQueueAttributes(sqsUrl, Arrays.asList("QueueArn")).getAttributes().get("QueueArn");
        String sqsSubscriptionArn = sns.subscribe(snsTopicArn, "sqs", sqsArn).getSubscriptionArn();
        Policy allowSnsToPostToSqsPolicy = new Policy("allow sns " + snsTopicArn + " to send to queue", Arrays.asList(
                new Statement(Statement.Effect.Allow)
                        .withPrincipals(Principal.All)
                        .withActions(SQSActions.SendMessage)
                        .withResources(new Resource(sqsArn))
                        .withConditions(new Condition().withType("ArnEquals").withConditionKey("aws:SourceArn").withValues(snsTopicArn))
        ));
        sqs.setQueueAttributes(new SetQueueAttributesRequest().withQueueUrl(sqsUrl).addAttributesEntry("Policy", allowSnsToPostToSqsPolicy.toJson()));
        String sqsSubscriptionArn = sns.subscribe(snsTopicArn, "sqs", sqsArn).getSubscriptionArn();
        sns.publish(snsTopicArn, "Hello world");
        ReceiveMessageResult receiveResp = sqs.receiveMessage(new ReceiveMessageRequest(sqsUrl).withWaitTimeSeconds(10));
        for (Message message: receiveResp.getMessages()) {
            System.out.println("Received message " + message.getBody());
            sqs.deleteMessage(sqsUrl, message.getReceiptHandle());
        }
        System.out.println("Deleting");
        sns.deleteTopic(snsTopicArn);
        sqs.deleteQueue(sqsUrl);
    }
}

它将消息打印到控制台,如下所示:

Received message {
  "Type" : "Notification",
  "MessageId" : "add8d56a-19e6-5806-9424-9a2a796f8f94",
  "TopicArn" : "arn:aws:sns:us-east-1:111111111111:my-sns-topic",
  "Message" : "Hello world",
  "Timestamp" : "2016-02-19T00:14:01.973Z",
  "SignatureVersion" : "1",
  "Signature" : "XXXaLONGSIGNATUREXXX",
  "SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-bb750dd426d95ee9390147a5624348ee.pem",
  "UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:111111111111:my-sns-topic:5e4d08a2-bcdb-4943-afef-5b7b02e30d5a"
}
Deleting

关于java - 如何在我的 Java 应用程序中使用 Amazon Web Services 策略声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30724999/

相关文章:

java - Spring Cloud SQS 轮询

amazon-sqs - 在达到可见性超时并且消息已重新排队后删除

java - 连接到远程服务器时,SocketException 默认 SSL 上下文为空

amazon-web-services - 无法查看/接收来自 AWS SQS 的所有消息

java - 一台机器上有多少个Spring Boot应用

amazon-web-services - AWS cron 作业在两个小时的时间内每分钟运行一次?

json - 在 AWS Cloudformation 中传递资源名称的标签键和值

amazon-web-services - 为什么我的 EC2 实例没有注册到 ECS 集群

java - 在 Eclipse 内的新窗口中打开文件进行编辑

java - 在 Java 中,如何根据特定的正则表达式创建所有可能数字的列表?