---
# System prepended metadata

title: API SNS

---

# API SNS

## 1. Метод PutBucketNotificationConfiguration

Метод включает уведомление о некотором событии (PutObject,  DeleteObject и т.д) в данном бакете.

Придерживаемся api Амазона:
https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketNotificationConfiguration.html.

Поддерживаем на данный момент только правила:
 - **CloudFunctionConfiguration** - (полностью совпадает с api aws)
 - **SimpleTopicConfiguration** - (исключительно наша реализация)

Правило CloudFunctionConfiguration описывает функцию, которую нужно вызвать, и события, на которые ее нужно вызывать.

Правило SimpleTopicConfiguration описывает url, на который делается запрос и события, на которые этот запрос выполняется.

Пример запроса:

```
PUT /?notification HTTP/1.1
Host: Bucket.s3.amazonaws.com

<?xml version="1.0" encoding="UTF-8"?>
<NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
   <SimpleTopicConfiguration>
      <Event>string</Event>
      ...
      <Filter>
         <S3Key>
            <FilterRule>
               <Name>string</Name>
               <Value>string</Value>
            </FilterRule>
            ...
         </S3Key>
      </Filter>
      <Id>string</Id>
      <Url>string</Url>
   </SimpleTopicConfiguration>
   ...
   <CloudFunctionConfiguration>
      <Event>string</Event>
      ...
      <Filter>
         <S3Key>
            <FilterRule>
               <Name>string</Name>
               <Value>string</Value>
            </FilterRule>
            ...
         </S3Key>
      </Filter>
      <Id>string</Id>
      <CloudFunction>string</CloudFunction>
   </CloudFunctionConfiguration>
   ...
</NotificationConfiguration>
````

### Общая концепция NotificationConfiguration:

Конфигурация привязывается на бакет и определяет на какие объекты этого бакета и какие события с этими объектами какое уведомление будет выполняться

```
NotificationConfiguration := { (filter, events), notification }
filter := prefix or/and suffix
notification := lambda/url
```

Конфигурация, навешенная на бакет, может содержать не более 100 правил SimpleTopicConfiguration, CloudFunctionConfiguration.

Каждое правило (SimpleTopicConfiguration или CloudFunctionConfiguration) определяется следующими параметрами:

    
- **Id**

    Опциональный параметр, уникален в рамках конфигурации. Строка < 256 символов.

- **Event**

    Событие над объектом бакета, при котором будет срабатывать правило.

    Поддерживаемые события: s3:ObjectCreated:* s3:ObjectCreated:Put s3:ObjectCreated:Copy s3:ObjectCreated:CompleteMultipartUpload s3:ObjectRemoved:* s3:ObjectRemoved:Delete.

    Соответствие методам:

    ```
    s3:ObjectCreated:* - PutObject, PutObjectCopy, CompleteMultipartUpload
    s3:ObjectCreated:Put - PutObject
    s3:ObjectCreated:Copy - PutObjectCopy
    s3:ObjectCreated:CompleteMultipartUpload - CompleteMultipartUpload
    s3:ObjectRemoved:* - DeleteObject
    s3:ObjectRemoved:Delete - DeleteObject
    ```

    Синтаксис:

    ```
    <Event>s3:ObjectCreated:Put</Event>
    <Event>s3:ObjectRemoved:Delete</Event>
    ```

    Обязательный параметр. Событий может быть несколько, но события не должны пересекаться (относительно методов).

- **Filter**

    Фильтр определяется префиксом и/или суффиксом. Действует на имя объекта.

    Например: Filter := ( Prefix = 'src/', Suffix = '.img' )
    
    правило будет выполнено для объекта с ключом src/images/tree.img, не будет выполнено для объекта с ключом src/images/tree.png и pic.img

    Синтаксис:

    ```
      <Filter>
          <S3Key>
          <FilterRule>
              <Name>Prefix</Name>
              <Value>src/</Value>
          </FilterRule>
          <FilterRule>
              <Name>Suffix</Name>
              <Value>.img</Value>
          </FilterRule>
          </S3Key>
      </Filter>
    ```
    Фильтр является опциональным параметром и может состоять из 1-2 х правил соответственно с различными FilterRule.Name - Prefix, Suffix

- **CloudFunction** (для CloudFunctionConfiguration)

    Имя функции, созданной в mcs lambda, в ARN формате (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) :

    arn:aws:lambda:\${Region}:\${Account}:function:${FunctionName}
        
    Пример: **arn:aws:lambda:ru-msk:mcs15291412:function:my-new-function**

    Синтаксис:

    ```    
    <CloudFunction>arn:aws:lambda:ru-msk:mcs15291412:function:my-new-function</CloudFunction> 
    ```

- **Url** (для SimpleTopiconfiguration)

    Урл, на который будет осуществляться request по событию.

    Синтаксис:

    ```
    <Url>https://some_url.com/things/do</Url>
    ```
    
    Для проверки проедоставленного url, осуществляется request до указанного урла:

    ```
    POST <url> HTTP/1.1
    x-amz-sns-messages-type: SubscriptionConfirmation
    content-type: application/json

    {
        "Timestamp":"2019-12-26T19:29:12+03:00",
        "Type":"SubscriptionConfirmation",
        "Message":"You have chosen to subscribe to the topic $topic. To confirm the subscription you need to response with calculated signature",
        "TopicArn":"mcs2883541269|monday-mcs|s3:ObjectCreated:Put",
        "SignatureVersion":1,
        "Token":"RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA"
    }
    ```
        

    Для подтверждения url необходимо отправить следующий Response

    ```
    POST
    content-type: application/json

    {"signature":"f9da00de9874d3421897a542241cc1d667fd34d59b97f92922e7286df223c63b"}
    ```

    Сигнатура вычисляется по следующему правилу:
    ```
    signature = hmac_sha256(url, hmac_sha256(TopicArn, hmac_sha256(Timestamp, Token)))
    
    hmac_sha256(data, key)
    ```


Для одного и того же события, определенного в правилах конфигурации, фильтры не должны пересекаться

### Response

```
HTTP/1.1 200

------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "ID length exceeded allowed limit of 255",
    "ArgumentName" : "Id",  
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Same ID used for multiple configurations. IDs must be unique.",
    "ArgumentName" : "Id",  
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Configuration is ambiguously defined. Cannot have overlapping suffixes in two rules if the prefixes are overlapping for the same event type.",
    "ArgumentName" : "FilterRule",  
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "The event is not supported for notifications",
    "ArgumentName" : "Event",  
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Configurations overlap. Configurations on the same bucket cannot share a common event type.",
    "ArgumentName" : "Event",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidRequest",
    "Message" : "Too many configurations submitted. The maximum number of configurations is 100",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidRequest",
    "Message" : "Bad format url",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Unable to validate the following destination configurations",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "The ARN is not well formed",
    "ArgumentName" : "CloudFunction",  
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Failed to confirm simple topic because of bad response content-type",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Failed to confirm simple topic because of bad response status",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Failed to confirm simple topic because of bad response body",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Failed to confirm simple topic because of bad response body. No signature",
}
------------

HTTP/1.1 400
{
    "Code" : "InvalidArgument",
    "Message" : "Failed to confirm simple topic because of signature mismatch",
}
------------
```

### Вызов url в SimpleTopicConfiguration

При срабатывании одного из правил SimpleTopicConfiguration будет выполнен следующий request:

```
POST <url> HTTP/1.1
x-amz-sns-messages-type: SubscriptionConfirmation

{ "Records":
    [
        {
            "s3": {
                "object": {
                    "eTag":"aed563ecafb4bcc5654c597a421547b2,
                    "sequencer":1577453615,
                    "key":"some-file-to-bucket",
                    "size":100
                },
            "configurationId":"1",
            "bucket": {
                "name": "monday-mcs",
                "ownerIdentity": {
                    "principalId":"mcs2883541269"}
                },
                "s3SchemaVersion":"1.0"
            },
            "eventVersion":"1.0",
            "requestParameters":{
                "sourceIPAddress":"185.6.245.156"
            },
            "userIdentity": {
                "principalId":"2407013e-cbc1-415f-9102-16fb9bd6946b"
            },
            "eventName":"s3:ObjectCreated:Put",
            "awsRegion":"ru-msk",
            "eventSource":"aws:s3",
            "responseElements": {
                "x-amz-request-id":"VGJR5rtJ"
            }
        }
    ]
}
```

## 2. Метод GetBucketNotificationConfiguration

Возвращает текущую конфигурацию (NotificationConfiguration) бакета. Если конфигурация еще не была привязана к бакету, будет возращен пустой элемент NotificationConfiguration.

Придерживаемся api: https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketNotificationConfiguration.html.

Request

```
GET /?notification HTTP/1.1
Host: Bucket.s3.amazonaws.com
```

Response

```
HTTP/1.1 200
<?xml version="1.0" encoding="UTF-8"?>
<NotificationConfiguration>
   <SimpleTopicConfiguration>
      <Event>string</Event>
      ...
      <Filter>
         <S3Key>
            <FilterRule>
               <Name>string</Name>
               <Value>string</Value>
            </FilterRule>
            ...
         </S3Key>
      </Filter>
      <Id>string</Id>
      <Url>string</Url>
   </SimpleTopicConfiguration>
   ...
   <CloudFunctionConfiguration>
      <Event>string</Event>
      ...
      <Filter>
         <S3Key>
            <FilterRule>
               <Name>string</Name>
               <Value>string</Value>
            </FilterRule>
            ...
         </S3Key>
      </Filter>
      <Id>string</Id>
      <CloudFunction>string</CloudFunction>
   </CloudFunctionConfiguration>
   ...
</NotificationConfiguration>
```