演练:为存储桶配置通知(SNS 主题或 SQS 队列) - Amazon Simple Storage Service

演练:为存储桶配置通知(SNS 主题或 SQS 队列)

您可以使用 Amazon Simple Notification Service (Amazon SNS) 或 Amazon Simple Queue Service (Amazon SQS) 接收 Amazon S3 通知。在此演练中,您将使用 Amazon SNS 主题和 Amazon SQS 队列向存储桶添加通知配置。

注意

不支持将 Amazon Simple Queue Service FIFO(先进先出)队列作为 Amazon S3 事件通知目标。要向 Amazon SQS FIFO 队列发送 Amazon S3 事件的通知,您可以使用 Amazon EventBridge。有关更多信息,请参阅 启用 Amazon EventBridge

演练摘要

此演练可以帮助您执行以下操作:

  • s3:ObjectCreated:* 类型的事件发布到 Amazon SQS 队列。

  • s3:ReducedRedundancyLostObject 类型的事件发布到 Amazon SNS 主题。

有关通知配置的信息,请参阅 使用 Amazon SQS、Amazon SNS 和 Lambda

您可以使用控制台执行这些步骤,无需编写任何代码。此外,还提供了使用适用于 Java 和 .NET 的 AWS SDK 的代码示例,以帮助您通过编程方式添加通知配置。

该过程包括以下步骤:

  1. 创建 Amazon SQS 队列。

    使用 Amazon SQS 控制台创建 SQS 队列。您可以通过编程方式访问 Amazon S3 发送到队列的所有消息。但对于此演练,您在控制台中验证通知消息。

    您可将访问策略附加到队列以授予 Amazon S3 发布消息的权限。

  2. 创建 Amazon SNS 主题。

    使用 Amazon SNS 控制台创建 SNS 主题并订阅该主题。这样,发布到此项目的所有事件都传送给您。指定电子邮件作为通信协议。创建主题后,Amazon SNS 会发送电子邮件。您可使用电子邮件中的链接确认订阅主题。

    您可将访问策略附加到主题以授予 Amazon S3 发布消息的权限。

  3. 将通知配置添加到存储桶。

第 1 步:创建 Amazon SQS 队列

按照以下步骤创建并订阅 Amazon Simple Queue Service (Amazon SQS) 队列。

  1. 使用 Amazon SQS 控制台创建队列。有关说明,请参阅 Amazon Simple Queue Service 开发人员指南中的 Amazon SQS 入门

  2. 使用以下策略替换附加到队列的访问策略。

    1. 在 Amazon SQS 控制台的 Queues (队列) 列表中,请选择队列名称。

    2. Access policy (访问策略) 选项卡上,请选择 Edit (编辑)

    3. 替换附加到队列的访问策略。在其中,提供您的 Amazon SQS ARN、源存储桶名称和存储桶拥有者账户 ID。

      { "Version": "2012-10-17", "Id": "example-ID", "Statement": [ { "Sid": "example-statement-ID", "Effect": "Allow", "Principal": { "Service": "s3.amazonaws.com" }, "Action": [ "SQS:SendMessage" ], "Resource": "SQS-queue-ARN", "Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:s3:*:*:awsexamplebucket1" }, "StringEquals": { "aws:SourceAccount": "bucket-owner-account-id" } } } ] }
    4. 请选择保存

  3. (可选)如果 Amazon SQS 队列或 Amazon SNS 主题已通过 AWS Key Management Service (AWS KMS) 启用服务器端加密,可将以下策略添加到关联的对称加密客户托管式密钥。

    必须将此策略添加到客户托管密钥中,因为您无法为 Amazon SQS 或 Amazon SNS 修改 AWS 托管密钥。

    { "Version": "2012-10-17", "Id": "example-ID", "Statement": [ { "Sid": "example-statement-ID", "Effect": "Allow", "Principal": { "Service": "s3.amazonaws.com" }, "Action": [ "kms:GenerateDataKey", "kms:Decrypt" ], "Resource": "*" } ] }

    有关将适用于 Amazon SQS 和 Amazon SNS 的 SSE 与 AWS KMS 结合使用的更多信息,请参阅以下内容:

    • mazon Simple Notification Service 开发人员指南中的密钥管理

    • Amazon Simple Queue Service 开发人员指南中的密钥管理

  4. 记录队列 ARN。

    您创建的 SQS 队列是您的 AWS 账户 中另一个资源。它有唯一的 Amazon Resource Name (ARN)。在下一步骤中,您需要用到此 ARN。ARN 的格式如下所示:

    arn:aws:sqs:aws-region:account-id:queue-name

第 2 步:创建 Amazon SNS 主题

按照以下步骤创建并订阅 Amazon SNS 主题。

  1. 使用 Amazon SNS 控制台创建主题。有关说明,请参阅 Amazon Simple Notification Service 开发人员指南中的创建 Amazon SNS 主题

  2. 订阅至主题。对于此练习,请使用电子邮件作为通信协议。有关说明,请参阅 Amazon Simple Notification Service 开发人员指南中的订阅 Amazon SNS 主题

    您将收到电子邮件要求您确认订阅该主题。确认订阅。

  3. 使用以下策略替换附加到主题的访问策略。在其中,提供您的 SNS 主题 ARN、存储桶名称和存储桶拥有者账户 ID。

    { "Version": "2012-10-17", "Id": "example-ID", "Statement": [ { "Sid": "Example SNS topic policy", "Effect": "Allow", "Principal": { "Service": "s3.amazonaws.com" }, "Action": [ "SNS:Publish" ], "Resource": "SNS-topic-ARN", "Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:s3:*:*:amzn-s3-demo-bucket" }, "StringEquals": { "aws:SourceAccount": "bucket-owner-account-id" } } } ] }
  4. 记录主题 ARN。

    您创建的 SNS 主题是您的 AWS 账户中的另一项资源,它有唯一的 ARN。在下一步骤中,您需要用到此 ARN。ARN 格式如下:

    arn:aws:sns:aws-region:account-id:topic-name

步骤 3:将通知配置添加到存储桶

您可以使用 Amazon S3 控制台或以编程方式使用 AWS SDK 启用存储桶通知。请选择任何一个选项以配置存储桶通知。此部分提供使用适用于 Java 和 .NET 的 AWS SDK 的代码示例。

选项 A:使用控制台在存储桶上启用通知

使用 Amazon S3 控制台,添加请求 Amazon S3 执行以下操作的通知配置:

  • 所有对象创建事件类型的事件发布到 Amazon SQS 队列。

  • RRS 中的对象丢失类型的事件发布到 Amazon SNS 主题。

在您保存通知配置后,Amazon S3 会发布测试消息,您将通过电子邮件收到该消息。

有关说明,请参阅 使用 Amazon S3 控制台启用和配置事件通知

选项 B:使用 AWS SDK 在存储桶上启用通知

.NET

下面的 C# 代码示例提供一个完整的代码列表,用于为存储桶添加通知配置。您必须更新该代码,提供您的存储桶名称和 SNS 主题 ARN。有关设置和运行代码示例的信息,请参阅《适用于 .NET 的 AWS SDK 开发人员指南》中的适用于 .NET 的 AWS SDK 入门

using Amazon; using Amazon.S3; using Amazon.S3.Model; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace Amazon.DocSamples.S3 { class EnableNotificationsTest { private const string bucketName = "*** bucket name ***"; private const string snsTopic = "*** SNS topic ARN ***"; private const string sqsQueue = "*** SQS topic ARN ***"; // Specify your bucket region (an example region is shown). private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; private static IAmazonS3 client; public static void Main() { client = new AmazonS3Client(bucketRegion); EnableNotificationAsync().Wait(); } static async Task EnableNotificationAsync() { try { PutBucketNotificationRequest request = new PutBucketNotificationRequest { BucketName = bucketName }; TopicConfiguration c = new TopicConfiguration { Events = new List<EventType> { EventType.ObjectCreatedCopy }, Topic = snsTopic }; request.TopicConfigurations = new List<TopicConfiguration>(); request.TopicConfigurations.Add(c); request.QueueConfigurations = new List<QueueConfiguration>(); request.QueueConfigurations.Add(new QueueConfiguration() { Events = new List<EventType> { EventType.ObjectCreatedPut }, Queue = sqsQueue }); PutBucketNotificationResponse response = await client.PutBucketNotificationAsync(request); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' ", e.Message); } catch (Exception e) { Console.WriteLine("Unknown error encountered on server. Message:'{0}' ", e.Message); } } } }
Java

以下示例说明如何将通知配置添加到存储桶。有关如何创建和测试有效示例的说明,请参阅《AWS SDK for Java 开发人员指南》中的入门

import com.amazonaws.AmazonServiceException; import com.amazonaws.SdkClientException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.*; import java.io.IOException; import java.util.EnumSet; public class EnableNotificationOnABucket { public static void main(String[] args) throws IOException { String bucketName = "*** Bucket name ***"; Regions clientRegion = Regions.DEFAULT_REGION; String snsTopicARN = "*** SNS Topic ARN ***"; String sqsQueueARN = "*** SQS Queue ARN ***"; try { AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new ProfileCredentialsProvider()) .withRegion(clientRegion) .build(); BucketNotificationConfiguration notificationConfiguration = new BucketNotificationConfiguration(); // Add an SNS topic notification. notificationConfiguration.addConfiguration("snsTopicConfig", new TopicConfiguration(snsTopicARN, EnumSet.of(S3Event.ObjectCreated))); // Add an SQS queue notification. notificationConfiguration.addConfiguration("sqsQueueConfig", new QueueConfiguration(sqsQueueARN, EnumSet.of(S3Event.ObjectCreated))); // Create the notification configuration request and set the bucket notification // configuration. SetBucketNotificationConfigurationRequest request = new SetBucketNotificationConfigurationRequest( bucketName, notificationConfiguration); s3Client.setBucketNotificationConfiguration(request); } catch (AmazonServiceException e) { // The call was transmitted successfully, but Amazon S3 couldn't process // it, so it returned an error response. e.printStackTrace(); } catch (SdkClientException e) { // Amazon S3 couldn't be contacted for a response, or the client // couldn't parse the response from Amazon S3. e.printStackTrace(); } } }

步骤 4:测试设置

现在,您可以通过将对象上传到存储桶来测试设置,并在 Amazon SQS 控制台中验证事件通知。有关说明,请参阅 Amazon Simple Queue Service 开发人员指南“入门”部分中的接收消息