

# 使用 Amazon SQS、Amazon SNS 和 Lambda
<a name="how-to-enable-disable-notification-intro"></a>

启用通知是存储桶级操作。您可以在与该存储桶关联的*通知*子资源中存储通知配置信息。创建或更改存储桶通知配置后，通常必须等待 5 分钟才能使更改生效。首次启用通知时会发生 `s3:TestEvent`。您可以使用以下任意方法来管理通知配置：
+ **使用 Amazon S3 控制台** – 控制台 UI 允许您在存储桶上设置通知配置，而无需编写任何代码。有关更多信息，请参阅 [使用 Amazon S3 控制台启用和配置事件通知](enable-event-notifications.md)。
+ **以编程方式使用 AWS SDK** – 在内部，控制台和 SDK 都调用 Amazon S3 REST API 来管理与存储桶关联的*通知*子资源。有关使用 AWS SDK 的通知配置示例，请参阅 [演练：为存储桶配置通知（SNS 主题或 SQS 队列）](ways-to-add-notification-config-to-bucket.md)。
**注意**  
您也可以直接从代码中调用 Amazon S3 REST API。但是，这可能会比较繁琐，因为您必须编写代码对请求进行身份验证。

无论您使用哪种方法，Amazon S3 都将通知配置作为 XML 存储在与存储桶关联的*通知*子资源中。有关存储桶子资源的信息，请参阅 [通用存储桶配置选项](UsingBucket.md#bucket-config-options-intro)。

**注意**  
如果您由于已删除的目标而收到多个失败事件通知，则在尝试删除这些通知时，您可能会收到**无法验证以下目标配置**。您可以在 S3 控制台中通过同时删除所有失败的通知来解决此问题。

**Topics**
+ [授予将事件通知消息发布到目标的权限](grant-destinations-permissions-to-s3.md)
+ [使用 Amazon S3 控制台启用和配置事件通知](enable-event-notifications.md)
+ [以编程方式配置事件通知](#event-notification-configuration)
+ [演练：为存储桶配置通知（SNS 主题或 SQS 队列）](ways-to-add-notification-config-to-bucket.md)
+ [使用对象键名筛选配置事件通知](notification-how-to-filtering.md)
+ [事件消息结构](notification-content-structure.md)

# 授予将事件通知消息发布到目标的权限
<a name="grant-destinations-permissions-to-s3"></a>

您必须向 Amazon S3 主体授予调用相关 API 的必要权限，以将消息发布到 SNS 主题、SQS 队列或 Lambda 函数。这是为了让 Amazon S3 能够将事件通知消息发布到目标。

要解决向目标发布事件通知消息的问题，请参阅[将 Amazon S3 事件通知发布到 Amazon Simple Notification Service 主题的疑难解答](https://repost.aws/knowledge-center/sns-not-receiving-s3-event-notifications)。

**Topics**
+ [授予调用 AWS Lambda 函数的权限](#grant-lambda-invoke-permission-to-s3)
+ [授予将消息发布到 SNS 主题或 SQS 队列的权限](#grant-sns-sqs-permission-for-s3)

## 授予调用 AWS Lambda 函数的权限
<a name="grant-lambda-invoke-permission-to-s3"></a>

Amazon S3 通过调用 Lambda 函数并提供事件消息作为参数来将事件消息发布到 AWS Lambda。

使用 Amazon S3 控制台在 Amazon S3 存储桶上为 Lambda 函数配置事件通知时，控制台将在 Lambda 函数上设置必要的权限。这是为了让 Amazon S3 有权从存储桶调用函数。有关更多信息，请参阅 [使用 Amazon S3 控制台启用和配置事件通知](enable-event-notifications.md)。

您还可以从 AWS Lambda 向 Amazon S3 授予调用 Lambda 函数的权限。有关更多信息，请参阅 *AWS Lambda 开发人员指南*中的[教程：将 AWS Lambda 与 Amazon S3 结合使用](https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html)。

## 授予将消息发布到 SNS 主题或 SQS 队列的权限
<a name="grant-sns-sqs-permission-for-s3"></a>

要授予 Amazon S3 权限以将消息发布到 SNS 主题或 SQS 队列，请将 AWS Identity and Access Management（IAM）策略附加到目标 SNS 主题或 SQS 队列。

有关如何将策略附加到 SNS 主题或 SQS 队列的示例，请参阅 [演练：为存储桶配置通知（SNS 主题或 SQS 队列）](ways-to-add-notification-config-to-bucket.md)。有关权限的更多信息，请参阅以下主题：
+ *Amazon Simple Notification Service 开发人员指南*中的 [Amazon SNS 访问控制示例案例](https://docs.aws.amazon.com/sns/latest/dg/AccessPolicyLanguage_UseCases_Sns.html)
+ *Amazon Simple Queue Service 开发人员指南*中的 [Amazon SQS 中的 Identity and Access Management](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/UsingIAM.html)

### 目标 SNS 主题的 IAM 策略
<a name="sns-topic-policy"></a>

以下是您附加到目标 SNS 主题的 AWS Identity and Access Management（IAM）策略示例。有关如何使用此策略为事件通知设置目标 Amazon SNS 主题的说明，请参阅 [演练：为存储桶配置通知（SNS 主题或 SQS 队列）](ways-to-add-notification-config-to-bucket.md)。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Id": "example-ID",
    "Statement": [
        {
            "Sid": "Example SNS topic policy",
            "Effect": "Allow",
            "Principal": {
                "Service": "s3.amazonaws.com"
            },
            "Action": [
                "SNS:Publish"
            ],
            "Resource": "arn:aws:sns:us-east-1:111122223333:example-sns-topic",
            "Condition": {
                "ArnEquals": {
                    "aws:SourceArn": "arn:aws:s3:::amzn-s3-demo-bucket"
                },
                "StringEquals": {
                    "aws:SourceAccount": "bucket-owner-123456789012"
                }
            }
        }
    ]
}
```

------

### 目标 SQS 队列的 IAM 策略
<a name="sqs-queue-policy"></a>

以下是您附加到目标 SQS 队列的 IAM 策略示例。有关如何使用此策略为事件通知设置目标 Amazon SQS 队列的说明，请参阅 [演练：为存储桶配置通知（SNS 主题或 SQS 队列）](ways-to-add-notification-config-to-bucket.md)。

要使用此策略，您必须更新 Amazon SQS 队列 ARN、存储桶名称和存储桶拥有者的 AWS 账户 ID。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Id": "example-ID",
    "Statement": [
        {
            "Sid": "example-statement-ID",
            "Effect": "Allow",
            "Principal": {
                "Service": "s3.amazonaws.com"
            },
            "Action": [
                "SQS:SendMessage"
            ],
            "Resource": "arn:aws:sqs:us-east-1:111122223333:queue-name",
            "Condition": {
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:s3:*:*:amzn-s3-demo-bucket"
                },
                "StringEquals": {
                    "aws:SourceAccount": "bucket-owner-123456789012"
                }
            }
        }
    ]
}
```

------

对于 Amazon SNS 和 Amazon SQS IAM 策略，您可以在策略中指定 `StringLike` 条件而不是 `ArnLike` 条件。

使用 `ArnLike` 时，ARN 的分区、服务、账户 ID、资源类型和部分资源 ID 等部分必须与请求上下文中的 ARN 完全匹配。只有区域和资源路径支持部分匹配。

 当使用 `StringLike` 而不是 `ArnLike` 时，无论哪个部分用通配符来替代，匹配都会忽略 ARN 结构并支持部分匹配。有关更多信息，请参阅《IAM 用户指南》**中的 [IAM JSON 策略元素](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html)。

```
"Condition": {         
  "StringLike": { "aws:SourceArn": "arn:aws:s3:*:*:amzn-s3-demo-bucket" }
  }
```

### AWS KMS 密钥政策
<a name="key-policy-sns-sqs"></a>

如果 SQS 队列或 SNS 主题使用 AWS Key Management Service（AWS KMS）客户托管密钥进行加密，则必须向 Amazon S3 服务主体授予处理加密主题和/或队列的权限。要向 Amazon S3 服务主体授予权限，请将以下语句添加到客户托管密钥策略中。

------
#### [ JSON ]

****  

```
{
    "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": "*"
        }
    ]
}
```

------

有关 AWS KMS 密钥策略的更多信息，请参阅 *AWS Key Management Service 开发人员指南*中的[使用 AWS KMS 中的密钥策略](https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)。

有关将服务器端加密与适用于 Amazon SQS 和 Amazon SNS 的 AWS KMS 结合使用的更多信息，请参阅以下内容：
+ *mazon Simple Notification Service 开发人员指南*中的[密钥管理](https://docs.aws.amazon.com/sns/latest/dg/sns-key-management.html)。
+ *Amazon Simple Queue Service 开发人员指南*中的[密钥管理](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html)。
+ *AWS 计算博客*中的[利用 AWS KMS 加密发布到 Amazon SNS 的消息](https://aws.amazon.com/blogs/compute/encrypting-messages-published-to-amazon-sns-with-aws-kms/)。

# 使用 Amazon S3 控制台启用和配置事件通知
<a name="enable-event-notifications"></a>

您可以启用特定的 Amazon S3 通用存储桶事件，以便在每次发生这些事件时向目标发送通知消息。本部分介绍了如何使用 Amazon S3 控制台启用事件通知。有关将事件通知与 AWS SDK 和 Amazon S3 REST API 结合使用的信息，请参阅 [以编程方式配置事件通知](how-to-enable-disable-notification-intro.md#event-notification-configuration)。

**先决条件**：您必须先设置其中一个目标类型并配置权限，然后才能为存储桶启用事件通知。有关更多信息，请参阅[受支持的事件目标](notification-how-to-event-types-and-destinations.md#supported-notification-destinations)和[授予将事件通知消息发布到目标的权限](grant-destinations-permissions-to-s3.md)。

**注意**  
不支持将 Amazon Simple Queue Service FIFO（先进先出）队列作为 Amazon S3 事件通知目标。要向 Amazon SQS FIFO 队列发送 Amazon S3 事件的通知，您可以使用 Amazon EventBridge。有关更多信息，请参阅 [启用 Amazon EventBridge](enable-event-notifications-eventbridge.md)。

**Topics**
+ [使用 Amazon S3 控制台启用 Amazon SNS、Amazon SQS 或 Lambda 通知](#enable-event-notifications-sns-sqs-lam)

## 使用 Amazon S3 控制台启用 Amazon SNS、Amazon SQS 或 Lambda 通知
<a name="enable-event-notifications-sns-sqs-lam"></a>

**为 S3 存储桶启用和配置事件通知**

1. 登录到 AWS 管理控制台，然后通过以下网址打开 Amazon S3 控制台：[https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)。

1. 在左侧导航窗格中，选择**通用存储桶**。

1. 在存储桶列表中，选择要为其启用事件的存储桶的名称。

1. 选择 **Properties (属性)**。

1. 导航到 **Event Notifications (事件通知)** 部分，然后选择 **Create event notification (创建事件通知)**。

1. 在 **General configuration (常规配置)** 部分中，为事件通知指定描述性事件名称。您还可以选择指定前缀和后缀，以将通知限制为键以指定字符结尾的对象。

   1. 为 **Event name (事件名称)** 输入描述。

      如果未输入名称，则将生成一个全局唯一标识符 (GUID) 并用作名称。

   1. （可选）要选择按前缀筛选事件通知，请输入 **Prefix (前缀)**。

      例如，可以设置前缀筛选器，使得仅在文件添加到特定文件夹（例如 `images/`）时，您才会收到通知。

   1. （可选）要选择按后缀筛选事件通知，请输入 **Suffix (后缀)**。

      有关更多信息，请参阅 [使用对象键名筛选配置事件通知](notification-how-to-filtering.md)。

1. 在 **Event types (事件类型)** 部分中，选择要接收其通知的一个或多个事件类型。

   有关不同事件类型的列表，请参阅 [SQS、SNS 和 Lambda 支持的事件类型](notification-how-to-event-types-and-destinations.md#supported-notification-event-types)。

1. 在 **Destination (目标)** 部分中，请选择事件通知目标。
**注意**  
在发布事件通知之前，您必须向 Amazon S3 主体授予调用相关 API 的必要权限。这是为了使它可以将通知发布到 Lambda 函数、SNS 主题或 SQS 队列。

   1. 选择目标类型：**Lambda Function (Lambda 函数)**、**SNS Topic (SNS 主题)** 或 **SQS Queue (SQS 队列)**。

   1. 请选择目标类型后，从列表中选择函数、主题或队列。

   1. 或者，如果您希望指定 Amazon Resource Name (ARN)，请选择**输入 ARN** 并输入 ARN。

   有关更多信息，请参阅 [受支持的事件目标](notification-how-to-event-types-and-destinations.md#supported-notification-destinations)。

1. 请选择 **Save changes (保存更改)**，Amazon S3 会向事件通知目标发送一条测试消息。

## 以编程方式配置事件通知
<a name="event-notification-configuration"></a>

默认情况下，不为任何类型的事件启用通知。因此，*通知*子资源最初存储空配置。

```
<NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 
</NotificationConfiguration>
```

要为特定类型的事件启用通知，请将 XML 替换为适当的配置，该配置可标识您希望 Amazon S3 发布的事件类型和您希望将事件发布到的目标。对于每个目标，添加相应的 XML 配置。

**将事件消息发布到 SQS 队列**  
要将 SQS 队列设置为一个或多个事件类型的通知目标，请添加 `QueueConfiguration`。

```
<NotificationConfiguration>
  <QueueConfiguration>
    <Id>optional-id-string</Id>
    <Queue>sqs-queue-arn</Queue>
    <Event>event-type</Event>
    <Event>event-type</Event>
     ...
  </QueueConfiguration>
   ...
</NotificationConfiguration>
```

**将事件消息发布到 SNS 主题**  
要将 SNS 主题设置为特定事件类型的通知目标，请添加 `TopicConfiguration`。

```
<NotificationConfiguration>
  <TopicConfiguration>
     <Id>optional-id-string</Id>
     <Topic>sns-topic-arn</Topic>
     <Event>event-type</Event>
     <Event>event-type</Event>
      ...
  </TopicConfiguration>
   ...
</NotificationConfiguration>
```

**调用 AWS Lambda 函数并提供事件消息作为参数**  
要将 Lambda 函数设置为特定事件类型的通知目标，请添加`CloudFunctionConfiguration`。

```
<NotificationConfiguration>
  <CloudFunctionConfiguration>   
     <Id>optional-id-string</Id>   
     <CloudFunction>cloud-function-arn</CloudFunction>        
     <Event>event-type</Event>      
     <Event>event-type</Event>      
      ...  
  </CloudFunctionConfiguration>
   ...
</NotificationConfiguration>
```

**删除存储桶上配置的所有通知**  
要删除存储桶上配置的所有通知，请在*通知*子资源中保存一个空 `<NotificationConfiguration/>` 元素。

当 Amazon S3 检测到特定类型的事件时，它会发布包含事件信息的消息。有关更多信息，请参阅 [事件消息结构](notification-content-structure.md)。

有关配置事件通知的详细信息，请参阅以下主题：
+ [演练：为存储桶配置通知（SNS 主题或 SQS 队列）](ways-to-add-notification-config-to-bucket.md).
+ [使用对象键名筛选配置事件通知](notification-how-to-filtering.md)

# 演练：为存储桶配置通知（SNS 主题或 SQS 队列）
<a name="ways-to-add-notification-config-to-bucket"></a>

您可以使用 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](enable-event-notifications-eventbridge.md)。

**Topics**
+ [演练摘要](#notification-walkthrough-summary)
+ [第 1 步：创建 Amazon SQS 队列](#step1-create-sqs-queue-for-notification)
+ [第 2 步：创建 Amazon SNS 主题](#step1-create-sns-topic-for-notification)
+ [步骤 3：将通知配置添加到存储桶](#step2-enable-notification)
+ [步骤 4：测试设置](#notification-walkthrough-1-test)

## 演练摘要
<a name="notification-walkthrough-summary"></a>

此演练可以帮助您执行以下操作：
+ 将 `s3:ObjectCreated:*` 类型的事件发布到 Amazon SQS 队列。
+ 将 `s3:ReducedRedundancyLostObject` 类型的事件发布到 Amazon SNS 主题。

有关通知配置的信息，请参阅 [使用 Amazon SQS、Amazon SNS 和 Lambda](how-to-enable-disable-notification-intro.md)。

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

该过程包括以下步骤：

1. 创建 Amazon SQS 队列。

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

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

1. 创建 Amazon SNS 主题。

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

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

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

## 第 1 步：创建 Amazon SQS 队列
<a name="step1-create-sqs-queue-for-notification"></a>

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

1. 使用 Amazon SQS 控制台创建队列。有关说明，请参阅 *Amazon Simple Queue Service 开发人员指南*中的 [Amazon SQS 入门](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-getting-started.html)。

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

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

   1. 在 **Access policy (访问策略)** 选项卡上，请选择 **Edit (编辑)**。

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

------
#### [ JSON ]

****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Id": "example-ID",
          "Statement": [
              {
                  "Sid": "example-statement-ID",
                  "Effect": "Allow",
                  "Principal": {
                      "Service": "s3.amazonaws.com"
                  },
                  "Action": [
                      "SQS:SendMessage"
                  ],
                  "Resource": "arn:aws:sqs:us-west-2:111122223333:s3-notification-queue",
                  "Condition": {
                      "ArnLike": {
                          "aws:SourceArn": "arn:aws:s3:*:*:awsexamplebucket1"
                      },
                      "StringEquals": {
                          "aws:SourceAccount": "bucket-owner-123456789012"
                      }
                  }
              }
          ]
      }
      ```

------

   1. 选择**保存**。

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

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

------
#### [ JSON ]

****  

   ```
   {
       "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 开发人员指南*中的[密钥管理](https://docs.aws.amazon.com/sns/latest/dg/sns-key-management.html)。
   + *Amazon Simple Queue Service 开发人员指南*中的[密钥管理](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html)。

1. 记录队列 ARN。

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

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

## 第 2 步：创建 Amazon SNS 主题
<a name="step1-create-sns-topic-for-notification"></a>

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

1. 使用 Amazon SNS 控制台创建主题。有关说明，请参阅 *Amazon Simple Notification Service 开发人员指南*中的[创建 Amazon SNS 主题](https://docs.aws.amazon.com/sns/latest/dg/CreateTopic.html)。

1. 订阅至主题。对于此练习，请使用电子邮件作为通信协议。有关说明，请参阅 *Amazon Simple Notification Service 开发人员指南*中的[订阅 Amazon SNS 主题](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html)。

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

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

1. 记录主题 ARN。

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

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

## 步骤 3：将通知配置添加到存储桶
<a name="step2-enable-notification"></a>

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

### 选项 A：使用控制台在存储桶上启用通知
<a name="step2-enable-notification-using-console"></a>

使用 Amazon S3 控制台，添加请求 Amazon S3 执行以下操作的通知配置：
+ 将**所有对象创建事件**类型的事件发布到 Amazon SQS 队列。
+ 将 **RRS 中的对象丢失**类型的事件发布到 Amazon SNS 主题。

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

有关说明，请参阅 [使用 Amazon S3 控制台启用和配置事件通知](enable-event-notifications.md)。

### 选项 B：使用 AWS SDK 在存储桶上启用通知
<a name="step2-enable-notification-using-awssdk-dotnet"></a>

------
#### [ .NET ]

下面的 C\$1 代码示例提供一个完整的代码列表，用于为存储桶添加通知配置。您必须更新该代码，提供您的存储桶名称和 SNS 主题 ARN。有关设置和运行代码示例的信息，请参阅《适用于 .NET 的 AWS SDK 开发人员指南》**中的[适用于 .NET 的 AWS SDK 入门](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-setup.html)。

```
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 ]

有关如何使用适用于 Java 的 AWS SDK 配置存储桶通知的示例，请参阅《Amazon S3 API Reference》**中的 [Process S3 event notifications](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_Scenario_ProcessS3EventNotification_section.html)。

------

## 步骤 4：测试设置
<a name="notification-walkthrough-1-test"></a>

现在，您可以通过将对象上传到存储桶来测试设置，并在 Amazon SQS 控制台中验证事件通知。有关说明，请参阅 *Amazon Simple Queue Service 开发人员指南*“入门”部分中的[接收消息](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-getting-started.htmlReceiveMessage.html)。

# 使用对象键名筛选配置事件通知
<a name="notification-how-to-filtering"></a>

配置 Amazon S3 事件通知时，您必须指定哪些受支持的 Amazon S3 事件类型会导致 Amazon S3 发送通知。如果 S3 存储桶中发生了您未指定的事件类型，Amazon S3 不会发送通知。

您可以将通知配置为按对象的键名的前缀和后缀进行筛选。例如，您可以设置一个配置，以便仅在带有 "`.jpg`" 文件扩展名的图像文件添加到存储桶时收到通知。或者，您也可以设置一个配置，该配置仅在将带有前缀“`images/`”的对象添加到存储桶时将通知发送到 Amazon SNS 主题，同时将同一存储桶中带有前缀“`logs/`”的对象的通知发送到 AWS Lambda 函数。

**注意**  
通配符（"\$1"）不能在筛选条件中用作前缀或后缀。如果您的前缀或后缀包含空格，则必须将其替换为“\$1”字符。如果您在前缀或后缀的值中使用任何其他特殊字符，您必须以 [URL 编码（百分比编码）格式](https://en.wikipedia.org/wiki/Percent-encoding)输入它们。有关在事件通知的前缀或后缀中使用时必须转换为 URL 编码格式的特殊字符的完整列表，请参阅[安全字符](object-keys.md#object-key-guidelines-safe-characters)。

您可以在 Amazon S3 控制台中设置使用对象密钥名称过滤的通知配置。您可以直接通过 AWS SDK 或 REST API 使用 Amazon S3 API 来实现该操作。有关使用控制台 UI 在存储桶上设置通知配置的信息，请参阅[使用 Amazon S3 控制台启用和配置事件通知](enable-event-notifications.md)。

Amazon S3 在与存储桶关联的*通知*子资源中以 XML 形式存储通知配置，如 [使用 Amazon SQS、Amazon SNS 和 Lambda](how-to-enable-disable-notification-intro.md) 中所述。您使用 `Filter` XML 结构定义要按对象键名的前缀和后缀进行筛选的通知的规则。有关 `Filter` XML 结构的信息，请参阅 *Amazon Simple Storage Service API 参考*中的 [PUT Bucket 通知](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTnotification.html)。

使用 `Filter` 的通知配置无法定义采用重叠前缀、重叠后缀或前缀和后缀重叠的筛选规则。以下部分提供了使用对象键名称筛选的有效通知配置的示例。它们还包含由于前缀和后缀重叠而无效的通知配置的示例。

**Topics**
+ [采用对象键名筛选的有效通知配置的示例](#notification-how-to-filtering-example-valid)
+ [采用无效前缀和后缀重叠的通知配置的示例](#notification-how-to-filtering-examples-invalid)

## 采用对象键名筛选的有效通知配置的示例
<a name="notification-how-to-filtering-example-valid"></a>

以下通知配置包含用于标识 Amazon S3 的 Amazon SQS 队列以发布 `s3:ObjectCreated:Put` 类型的事件的队列配置。每当具有前缀 `images/` 和后缀 `jpg` 的对象被放置（PUT）到存储桶时，就会发布这些事件。

```
<NotificationConfiguration>
  <QueueConfiguration>
      <Id>1</Id>
      <Filter>
          <S3Key>
              <FilterRule>
                  <Name>prefix</Name>
                  <Value>images/</Value>
              </FilterRule>
              <FilterRule>
                  <Name>suffix</Name>
                  <Value>jpg</Value>
              </FilterRule>
          </S3Key>
     </Filter>
     <Queue>arn:aws:sqs:us-west-2:444455556666:s3notificationqueue</Queue>
     <Event>s3:ObjectCreated:Put</Event>
  </QueueConfiguration>
</NotificationConfiguration>
```

以下通知配置有多个非重叠前缀。该配置作出以下定义：`images/` 文件夹中针对 PUT 请求的通知进入队列 A，`logs/` 文件夹中针对 PUT 请求的通知进入队列 B。

```
<NotificationConfiguration>
  <QueueConfiguration>
     <Id>1</Id>
     <Filter>
            <S3Key>
                <FilterRule>
                    <Name>prefix</Name>
                    <Value>images/</Value>
                </FilterRule>
            </S3Key>
     </Filter>
     <Queue>arn:aws:sqs:us-west-2:444455556666:sqs-queue-A</Queue>
     <Event>s3:ObjectCreated:Put</Event>
  </QueueConfiguration>
  <QueueConfiguration>
     <Id>2</Id>
     <Filter>
            <S3Key>
                <FilterRule>
                    <Name>prefix</Name>
                    <Value>logs/</Value>
                </FilterRule>
            </S3Key>
     </Filter>
     <Queue>arn:aws:sqs:us-west-2:444455556666:sqs-queue-B</Queue>
     <Event>s3:ObjectCreated:Put</Event>
  </QueueConfiguration>
</NotificationConfiguration>
```

以下通知配置有多个非重叠后缀。该配置作出以下定义：所有新添加到存储桶的 `.jpg` 映像都由 Lambda cloud-function-A 处理，所有新添加的 `.png` 映像都由云函数 B 处理。`.png` 和 `.jpg` 后缀不重叠，即使它们有相同的最后一个字母也是如此。如果某个给定的字符串能够以这两个后缀结尾，则将它们视为重叠。一个字符串无法同时以 `.png` 和 `.jpg` 结尾，因此示例配置中的后缀不是重叠后缀。

```
<NotificationConfiguration>
  <CloudFunctionConfiguration>
     <Id>1</Id>
     <Filter>
            <S3Key>
                <FilterRule>
                    <Name>suffix</Name>
                    <Value>.jpg</Value>
                </FilterRule>
            </S3Key>
     </Filter>
     <CloudFunction>arn:aws:lambda:us-west-2:444455556666:cloud-function-A</CloudFunction>
     <Event>s3:ObjectCreated:Put</Event>
  </CloudFunctionConfiguration>
  <CloudFunctionConfiguration>
     <Id>2</Id>
     <Filter>
            <S3Key>
                <FilterRule>
                    <Name>suffix</Name>
                    <Value>.png</Value>
                </FilterRule>
            </S3Key>
     </Filter>
     <CloudFunction>arn:aws:lambda:us-west-2:444455556666:cloud-function-B</CloudFunction>
     <Event>s3:ObjectCreated:Put</Event>
  </CloudFunctionConfiguration>
</NotificationConfiguration>
```

使用 `Filter` 的通知配置不能使用重叠前缀为相同的事件类型定义筛选规则。只有在与后缀不重叠一起使用的重叠前缀时，他们才能这样做。以下示例配置显示了如何将使用通用前缀和非重叠后缀创建的对象传递到其他目标。

```
<NotificationConfiguration>
  <CloudFunctionConfiguration>
     <Id>1</Id>
     <Filter>
            <S3Key>
                <FilterRule>
                    <Name>prefix</Name>
                    <Value>images</Value>
                </FilterRule>
                <FilterRule>
                    <Name>suffix</Name>
                    <Value>.jpg</Value>
                </FilterRule>
            </S3Key>
     </Filter>
     <CloudFunction>arn:aws:lambda:us-west-2:444455556666:cloud-function-A</CloudFunction>
     <Event>s3:ObjectCreated:Put</Event>
  </CloudFunctionConfiguration>
  <CloudFunctionConfiguration>
     <Id>2</Id>
     <Filter>
            <S3Key>
                <FilterRule>
                    <Name>prefix</Name>
                    <Value>images</Value>
                </FilterRule>
                <FilterRule>
                    <Name>suffix</Name>
                    <Value>.png</Value>
                </FilterRule>
            </S3Key>
     </Filter>
     <CloudFunction>arn:aws:lambda:us-west-2:444455556666:cloud-function-B</CloudFunction>
     <Event>s3:ObjectCreated:Put</Event>
  </CloudFunctionConfiguration>
</NotificationConfiguration>
```

## 采用无效前缀和后缀重叠的通知配置的示例
<a name="notification-how-to-filtering-examples-invalid"></a>

大多数情况下，使用 `Filter` 的通知配置无法使用重叠前缀、重叠后缀或前缀和后缀的重叠组合为相同的事件类型定义筛选规则。只要后缀不重叠，您就可以采用重叠前缀。有关示例，请参阅 [使用对象键名筛选配置事件通知](#notification-how-to-filtering)。

您可以将重叠对象键名筛选用于不同的事件类型。例如，您可以创建一个通知配置，该配置将前缀 `image/` 用于 `ObjectCreated:Put` 事件类型并将前缀 `image/` 用于 `ObjectRemoved:*` 事件类型。

在使用 Amazon S3 控制台或 API 时，如果您尝试保存具有对相同的活动类型无效的重叠名称筛选的通知配置，则会出现错误。此部分显示了因重叠名称筛选而无效的通知配置的示例。

任何现有通知配置规则都被假定为具有与任何其他前缀和后缀分别匹配的默认前缀和后缀。由于具有重叠前缀，以下通知配置无效。具体来说，根前缀与任何其他前缀重叠。（如果在此示例中使用后缀而不是前缀，则会发生同样的情况。根后缀与任何其他后缀重叠。）

```
<NotificationConfiguration>
     <TopicConfiguration>
         <Topic>arn:aws:sns:us-west-2:444455556666:sns-notification-one</Topic>
         <Event>s3:ObjectCreated:*</Event>
    </TopicConfiguration>
    <TopicConfiguration>
         <Topic>arn:aws:sns:us-west-2:444455556666:sns-notification-two</Topic>
         <Event>s3:ObjectCreated:*</Event>
         <Filter>
             <S3Key>
                 <FilterRule>
                     <Name>prefix</Name>
                     <Value>images</Value>
                 </FilterRule>
            </S3Key>
        </Filter>
    </TopicConfiguration>             
</NotificationConfiguration>
```

由于具有重叠后缀，以下通知配置无效。如果某个给定的字符串能够以这两个后缀结尾，则将它们视为重叠。字符串可以用 `jpg` 和 `pg` 结尾。因此，后缀会重叠。（前缀也是如此。如果给定字符串能够以两个前缀开头，则认为这两个前缀是重叠的。

```
 <NotificationConfiguration>
     <TopicConfiguration>
         <Topic>arn:aws:sns:us-west-2:444455556666:sns-topic-one</Topic>
         <Event>s3:ObjectCreated:*</Event>
         <Filter>
             <S3Key>
                 <FilterRule>
                     <Name>suffix</Name>
                     <Value>jpg</Value>
                 </FilterRule>
            </S3Key>
        </Filter>
    </TopicConfiguration>
    <TopicConfiguration>
         <Topic>arn:aws:sns:us-west-2:444455556666:sns-topic-two</Topic>
         <Event>s3:ObjectCreated:Put</Event>
         <Filter>
             <S3Key>
                 <FilterRule>
                     <Name>suffix</Name>
                     <Value>pg</Value>
                 </FilterRule>
            </S3Key>
        </Filter>
    </TopicConfiguration>
</NotificationConfiguration
```

由于具有重叠前缀和后缀，以下通知配置无效。

```
<NotificationConfiguration>
     <TopicConfiguration>
         <Topic>arn:aws:sns:us-west-2:444455556666:sns-topic-one</Topic>
         <Event>s3:ObjectCreated:*</Event>
         <Filter>
             <S3Key>
                 <FilterRule>
                     <Name>prefix</Name>
                     <Value>images</Value>
                 </FilterRule>
                 <FilterRule>
                     <Name>suffix</Name>
                     <Value>jpg</Value>
                 </FilterRule>
            </S3Key>
        </Filter>
    </TopicConfiguration>
    <TopicConfiguration>
         <Topic>arn:aws:sns:us-west-2:444455556666:sns-topic-two</Topic>
         <Event>s3:ObjectCreated:Put</Event>
         <Filter>
             <S3Key>
                 <FilterRule>
                     <Name>suffix</Name>
                     <Value>jpg</Value>
                 </FilterRule>
            </S3Key>
        </Filter>
    </TopicConfiguration>
</NotificationConfiguration>
```

# 事件消息结构
<a name="notification-content-structure"></a>

Amazon S3 为发布事件而发送的通知消息采用 JSON 格式。

有关配置事件通知的一般概述和说明，请参阅 [Amazon S3 事件通知](EventNotifications.md)。

此示例说明了事件通知 JSON 结构的*版本 2.1*。Amazon S3 使用了这个事件结构的*版本 2.1*、*2.2* 和 *2.3*。Amazon S3 使用版本 2.2 进行跨区域复制事件通知。它将 2.3 版本用于 S3 生命周期、S3 Intelligent-Tiering、对象 ACL、对象标记和对象恢复删除事件。这些版本包含特定于这些操作的额外信息。版本 2.2 和版本 2.3 与版本 2.1 兼容，Amazon S3 当前将该版本用于所有其他事件类型。

```
{  
   "Records":[  
      {  
         "eventVersion":"2.1",
         "eventSource":"aws:s3",
         "awsRegion":"us-west-2",
         "eventTime":"The time, in ISO-8601 format (for example, 1970-01-01T00:00:00.000Z) when Amazon S3 finished processing the request",
         "eventName":"The event type",
         "userIdentity":{  
            "principalId":"The unique ID of the IAM resource that caused the event"
         },
         "requestParameters":{  
            "sourceIPAddress":"The IP address where the request came from"
         },
         "responseElements":{  
            "x-amz-request-id":"The Amazon S3 generated request ID",
            "x-amz-id-2":"The Amazon S3 host that processed the request"
         },
         "s3":{  
            "s3SchemaVersion":"1.0",
            "configurationId":"The ID found in the bucket notification configuration",
            "bucket":{  
               "name":"The name of the bucket, for example, amzn-s3-demo-bucket",
               "ownerIdentity":{  
                  "principalId":"The Amazon retail customer ID of the bucket owner"
               },
               "arn":"The bucket Amazon Resource Name (ARN)"
            },
            "object":{  
               "key":"The object key name",
               "size":"The object size in bytes (as a number)",
               "eTag":"The object entity tag (ETag)",
               "versionId":"The object version if the bucket is versioning-enabled; null or not present if the bucket isn't versioning-enabled",
               "sequencer": "A string representation of a hexadecimal value used to determine event sequence; only used with PUT and DELETE requests"
            }
         },
         "glacierEventData": {
            "restoreEventData": {
               "lifecycleRestorationExpiryTime": "The time, in ISO-8601 format (for example, 1970-01-01T00:00:00.000Z), when the temporary copy of the restored object expires",
               "lifecycleRestoreStorageClass": "The source storage class for restored objects"
            }
         }
      }
   ]
}
```

注意，以下是关于事件消息结构：
+ `eventVersion` 键值包含 `major`.`minor` 格式的主要版本和次要版本。

  如果 Amazon S3 对不向后兼容的事件结构进行更改，则主要版本将递增。这包括删除已存在的 JSON 字段或更改字段内容的表示方式（例如，日期格式）。

  如果 Amazon S3 向事件结构添加新字段，则次要版本将递增。如果为某些或所有现有事件提供了新信息，则可能会发生这种情况 如果仅提供有关新引入的事件类型的新信息，则可能会发生这种情况。要与事件结构的新次要版本保持兼容，我们建议应用程序忽略新字段。

  如果引入了新的事件类型，但事件的结构未经修改，则事件版本不会更改。

  为确保您的应用程序可以正确解析事件结构，我们建议您对主要版本号进行相等比较。为了确保您的应用程序所期望的字段存在，我们还建议对次要版本进行大于或等于比较。
+ `eventName` 键值引用[事件通知类型](https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html)列表，但不包含 `s3:` 前缀。
+ `userIdentity` 键值引用导致事件的 AWS Identity and Access Management（IAM）资源（用户、角色、组等）的唯一 ID。有关每个 IAM 标识前缀（如 AIDA、AROA、AGPA 等）的定义和有关如何获取唯一标识符的信息，请参阅《IAM 用户指南》**中的[唯一标识符](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html##identifiers-unique-ids)。
+ 如果您希望通过联系 `responseElements` 来跟踪请求，则 AWS 支持 键值很有用。`x-amz-request-id` 和 `x-amz-id-2` 都可帮助 Amazon S3 跟踪单个请求。这些值与 Amazon S3 为响应您启动事件的请求而返回的值相同。因此，您可以使用这些值将事件与请求匹配。
+ `s3` 键值提供事件中涉及的存储桶和对象的相关信息。对象键名称值进行了 URL 编码。例如，`red flower.jpg` 改为 `red+flower.jpg`。（Amazon S3 返回“`application/x-www-form-urlencoded`”作为响应中的内容类型。）

  `ownerIdentity` 键值对应于存储桶拥有者的 Amazon 零售（Amazon.com）客户 ID。不再使用此 ID 值，保留此值仅是为了向后兼容。
+ `sequencer` 键值提供了一种用于确定事件顺序的方法。无法保证事件通知按事件发生的顺序到达。然而，来自创建对象（`PUT` 请求）和删除对象的事件的通知将包含 `sequencer`。您可以使用此值来确定给定对象键的事件的顺序。

  如果将来自同一对象键上的两个事件通知的 `sequencer` 字符串进行比较，就会发现 `sequencer` 十六进制值较大的事件通知是后发生的事件。如果您正在使用事件通知来维护 Amazon S3 对象的单独数据库或索引，我们建议您在处理每个事件通知时比较和存储 `sequencer` 值。

  请注意以下几点：
  + 您不能使用 `sequencer` 键值来确定不同对象键上事件的顺序。
  + `sequencer` 字符串可以有不同的长度。因此，为了比较这些值，首先要用零填补较短值的左侧，然后进行字母表顺序比较。
+ `glacierEventData` 键值只对 `s3:ObjectRestore:Completed` 事件可见。
+ `restoreEventData` 键值包含与还原请求相关的属性。
+ `replicationEventData` 键值只对复制事件可见。
+ `intelligentTieringEventData` 键值只对 S3 Intelligent-Tiering 可见。
+ `lifecycleEventData` 键值只对 S3 生命周期转换事件可见。

## 示例消息
<a name="notification-content-structure-examples"></a>

以下是 Amazon S3 事件通知消息的示例。

**Amazon S3 测试消息**  
当您在存储桶上配置事件通知时，Amazon S3 会发送以下测试消息。

```
1. {  
2.    "Service":"Amazon S3",
3.    "Event":"s3:TestEvent",
4.    "Time":"2014-10-13T15:57:02.089Z",
5.    "Bucket":"amzn-s3-demo-bucket",
6.    "RequestId":"5582815E1AEA5ADF",
7.    "HostId":"8cLeGAmw098X5cv4Zkwcmo8vvZa3eH3eKxsPzbB9wrR+YstdA6Knx4Ip8EXAMPLE"
8. }
```

**注意**  
`s3:TestEvent` 消息使用的格式与常规 S3 事件通知不同。与其它使用之前显示的 `Records` 数组结构的事件通知不同，测试事件使用带有直接字段的简化格式。在实施事件处理时，请确保您的代码能够区分和正确地处理这两种消息格式。

**使用 `PUT` 请求创建对象时的示例消息**  
以下是 Amazon S3 发送以发布 `s3:ObjectCreated:Put` 事件的消息示例。

```
 1. {  
 2.    "Records":[  
 3.       {  
 4.          "eventVersion":"2.1",
 5.          "eventSource":"aws:s3",
 6.          "awsRegion":"us-west-2",
 7.          "eventTime":"1970-01-01T00:00:00.000Z",
 8.          "eventName":"ObjectCreated:Put",
 9.          "userIdentity":{  
10.             "principalId":"AIDAJDPLRKLG7UEXAMPLE"
11.          },
12.          "requestParameters":{  
13.             "sourceIPAddress":"172.16.0.1"
14.          },
15.          "responseElements":{  
16.             "x-amz-request-id":"C3D13FE58DE4C810",
17.             "x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"
18.          },
19.          "s3":{  
20.             "s3SchemaVersion":"1.0",
21.             "configurationId":"testConfigRule",
22.             "bucket":{  
23.                "name":"amzn-s3-demo-bucket",
24.                "ownerIdentity":{  
25.                   "principalId":"A3NL1KOZZKExample"
26.                },
27.                "arn":"arn:aws:s3:::amzn-s3-demo-bucket"
28.             },
29.             "object":{  
30.                "key":"HappyFace.jpg",
31.                "size":1024,
32.                "eTag":"d41d8cd98f00b204e9800998ecf8427e",
33.                "versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko",
34.                "sequencer":"0055AED6DCD90281E5"
35.             }
36.          }
37.       }
38.    ]
39. }
```

