owned this note
owned this note
Published
Linked with GitHub
# Описание сервиса
Webhooks для S3 - возможность настраивать отправку HTTP/S запросов по событиям для бакета, используя API. Например, вы можете:
* настроить обработку и конвертирование файлов после загрузки
* интегрироваться с любыми внешними системами
* настроить логирование для объектного хранилища
# 1. Метод PutBucketNotificationConfiguration
Метод позволяет включить уведомление о некотором событии (PutObject, DeleteObject и т.д) в данном бакете.
На данный момент поддерживаем 1 тип событий - SimpleTopicConfiguration - запрос на url, предоставленный пользователем.
**Пример:** Требуется, чтобы выпонялся запрос на url **http://xxx.com** при PutObject в бакет **bucketA** объектов, имена которых подходят под маску **image/*.png**. (пример выполняемого по событию запроса на url в п.2)
Для этого нужно сделать следующий запрос (1):
```
PUT /?notification HTTP/1.1
Host: bucketA.s3.amazonaws.com
<?xml version="1.0" encoding="UTF-8"?>
<NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<SimpleTopicConfiguration>
<Id>1</Id>
<Event>s3:ObjectCreated:Put</Event>
<Url>http://xxx.com</Url>
<Filter>
<S3Key>
<FilterRule>
<Name>Prefix</Name>
<Value>image/</Value>
</FilterRule>
<FilterRule>
<Name>Suffix</Name>
<Value>.png</Value>
</FilterRule>
</S3Key>
</Filter>
</SimpleTopicConfiguration>
</NotificationConfiguration>
````
В момент выполнения этого запроса сервис mcs s3 валидирует url, выполняя на него следующий запрос (2):
```
POST http://xxx.com 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|bucketA|s3:ObjectCreated:Put",
"SignatureVersion":1,
"Token":"RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA"
}
```
для подтверждения url необходимо в ответ отправить подпись:
```
POST
content-type: application/json
{"signature":"f9da00de9874d3421897a542241cc1d667fd34d59b97f92922e7286df223c63b"}
```
Cигнатура вычисляется по формуле:
---
**signature** = **hmac_sha256**(*url*, **hmac_sha256**(*TopicArn*, **hmac_sha256**(*Timestamp*, *Token*)))
---
в нашем примере:
signature = hmac_sha256("http://xxx.com", hmac_sha256("mcs2883541269|bucketA|s3:ObjectCreated:Put", hmac_sha256("2019-12-26T19:29:12+03:00", "RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA")))
При успешном подтверждении url, в ответ на запрос (1) будет отправлен response
```
HTTP/1.1 200
```
## Правила построения запроса PutBucketNotificationConfiguration:
Схема запроса
```
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>
<Id>string</Id>
<Url>string</Url>
<Event>string</Event>
...
<Filter>
<S3Key>
<FilterRule>
<Name>string</Name>
<Value>string</Value>
</FilterRule>
...
</S3Key>
</Filter>
</SimpleTopicConfiguration>
...
</NotificationConfiguration>
```
Внутри запроса блоков SimpleTopicConfiguration (правил) может быть несколько, но не более 100.
Каждое правило определяется параметрами:
- **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
```
Events в одном правиле может быть несколько, но они **не должны** содержать одинаковых методов. То есть в одном правиле не могут быть, например, одновременно указаны events: s3:ObjectCreated:*, s3:ObjectCreated:Copy. Поскольку содержат обзий метод - PutObject.
- **Url**
Урл, на который будет осуществляться запрос при срабатывании события.
Внутри одного правило может быть указано несколько url'ов, каждый из которых необходимо подтвердить по схеме (2).
И при срабатывании данного правила будут выполняться запросы на каждый из указанных url'ов.
- **Filter**
(опциональный)
Данный параметр определяет префикс и/или суффикс. Событие срабатывает для данного объекта, только если его имя оответствует указанному префиксу и суффиксу.
Например: Filter := ( Prefix = 'src/', Suffix = '.img' )
правило будет выполнено для объекта с ключом src/images/tree.img и не будет выполнено для объекта с ключом src/images/tree.png и pic.img
---
Если в запросе PutBucketNotificationConfiguration описано несколько правил (блоков SimpleTopicConfiguration) с пересекающимися events, то фильтры не должны пересекаться.
Пример неправильного запроса:
```
<NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<SimpleTopicConfiguration>
<Event>s3:ObjectCreated:Put</Event>
<Filter>
<S3Key>
<FilterRule>
<Name>Prefix</Name>
<Value>image</Value>
</FilterRule>
</S3Key>
</Filter>
...
</SimpleTopicConfiguration>
<SimpleTopicConfiguration>
<Event>s3:ObjectCreated:Put</Event>
<Filter>
<S3Key>
<FilterRule>
<Name>Prefix</Name>
<Value>im</Value>
</FilterRule>
</S3Key>
</Filter>
...
</SimpleTopicConfiguration>
</NotificationConfiguration>
```
В данном запросе описаны 2 правила с одинаковым событием s3:ObjectCreated:Put, префиксы которых пересекаются.
---
Пример валидного запроса (3):
```
PUT /?notification HTTP/1.1
Host: bucketA.s3.amazonaws.com
<?xml version="1.0" encoding="UTF-8"?>
<NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<SimpleTopicConfiguration>
<Id>1</Id>
<Event>s3:ObjectCreated:Put</Event>
<Url>http://xxx321.com</Url>
<Filter>
<S3Key>
<FilterRule>
<Name>Prefix</Name>
<Value>image/</Value>
</FilterRule>
<FilterRule>
<Name>Suffix</Name>
<Value>.png</Value>
</FilterRule>
</S3Key>
</Filter>
</SimpleTopicConfiguration>
<SimpleTopicConfiguration>
<Id>2</Id>
<Event>s3:ObjectRemoved:Delete</Event>
<Url>http://xxx123.com</Url>
<Filter>
<S3Key>
<FilterRule>
<Name>Prefix</Name>
<Value>image/</Value>
</FilterRule>
<FilterRule>
<Name>Suffix</Name>
<Value>.png</Value>
</FilterRule>
</S3Key>
</Filter>
</SimpleTopicConfiguration>
</NotificationConfiguration>
````
После установки этого правила, при удалении объектов из бакета bucketA с именами image/\*.png будет выполняться запрос на url http://xxx123.com, а при загрузке объктов в бакет bucketA с именами image/\*.png, будет выполняться запрос на url http://xxx321.com
# 2. Срабатывание настроенных правил
При срабатывании события, описанного в одном из настроенных правил SimpleTopicConfiguration, сервисом mcs s3 выполняется запрос на указанный в правиле url:
Для примера установленных правил (3), при загрузкие объектов в бакет bucketA с именами image/\*.png, будет приходить следующий запрос:
```
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": "bucketA",
"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"
}
}
]
}
```
Тело запроса в соответствии с API amazon https://docs.aws.amazon.com/AmazonS3/latest/dev/notification-content-structure.html
# 3. Метод GetBucketNotificationConfiguration
Возвращает текущую конфигурацию правил (SimpleNotificationConfiguration) бакета. Если правила не были установлены для данного бакета, будет возращен пустой элемент NotificationConfiguration.
Request
```
GET /?notification HTTP/1.1
Host: Bucket.s3.amazonaws.com
```
Для примера (3) будет отправлен следующий ответ:
Response
```
HTTP/1.1 200
<?xml version="1.0" encoding="UTF-8"?>
<NotificationConfiguration>
<SimpleTopicConfiguration>
<Id>1</Id>
<Event>s3:ObjectCreated:Put</Event>
<Url>http://xxx321.com</Url>
<Filter>
<S3Key>
<FilterRule>
<Name>Prefix</Name>
<Value>image/</Value>
</FilterRule>
<FilterRule>
<Name>Suffix</Name>
<Value>.png</Value>
</FilterRule>
</S3Key>
</Filter>
</SimpleTopicConfiguration>
<SimpleTopicConfiguration>
<Id>2</Id>
<Event>s3:ObjectRemoved:Delete</Event>
<Url>http://xxx123.com</Url>
<Filter>
<S3Key>
<FilterRule>
<Name>Prefix</Name>
<Value>image/</Value>
</FilterRule>
<FilterRule>
<Name>Suffix</Name>
<Value>.png</Value>
</FilterRule>
</S3Key>
</Filter>
</SimpleTopicConfiguration>
</NotificationConfiguration>
```