Glide Note

glidenote's blog

S3 Event NotificasionsをAmazon SQSで受け取る

最近やっている仕事で先日発表されたS3 Event Notificationsが利用出来そうな感じがしたのでちょっと調査。 S3にファイルがアップされたらAmazon SQSで通知を受け取るようにしてみた。

S3 => SNS => SQS への通知は解説しているサイトが結構あるんですが、S3 => SQS への通知設定の 情報が見当たらなかったので、動くようになるまで、いろいろと試行錯誤を繰り返した。 特にSQSのPermission設定が恐ろしく分かりにくくに2日くらいハマったので、自分用にメモしておく。

S3 Bucketの作成

S3でBucketを作成。既存Bucketを利用する場合はここはSKIP。 今回は検証用にglidenote-sqs-testという名前でBucketを作成

SQSの設定

S3のイベント通知を受け取るQueueを作成する

Queue名をsqs-testをして作成。

Add a Permissionをクリックして通知の受信元を設定する。

下記のように設定して、Add Conditionを選択

  • Valueにはarn:aws:s3:::{S3のBucket名}を設定

Actions部分はSendMessageだけ選択して、Add Permission を選択

こんな感じの設定になっていることを確認

S3 Event Notificationsの設定

S3のイベント通知をSQSに送るように設定。下記の例ではPUTPOSTイベントのみSQSに通知するように設定

正しく設定が出来ると下記のようになる。SQSのパーミッション設定が上手くてきていないとエラーになる。

実際にS3 EventをSQSで受け取る

下記のようなrubyのスクリプトを用意してSQSでイベントを受信してみる

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

require 'aws-sdk'

AWS.config(
  :access_key_id     => 'your_access_key_id',
  :secret_access_key => 'your_secret_access_key',
  :sss_endpoint      => 'sqs.ap-northeast-1.amazonaws.com'
)

url = 'https://sqs.ap-northeast-1.amazonaws.com/xxxxxxxxxxxx/sqs-test'

sqs = AWS::SQS.new

while true
  receive = sqs.queues[url].receive_message()
  if receive
    puts receive.body
    receive.delete
    sleep 1
  end
  puts "Waiting"
  sleep 1
end

するとほぼリアルタイムで下記のような感じでイベントを受信出来る

1
{"Records":[{"eventVersion":"2.0","eventSource":"aws:s3","awsRegion":"ap-northeast-1","eventTime":"2014-11-20T06:16:39.474Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"AWLW0VGTI46AA"},"requestParameters":{"sourceIPAddress":"10.115.144.24"},"responseElements":{"x-amz-request-id":"E1C0A0C1F42CAA54","x-amz-id-2":"0p2FzYuEkiyaZn/n33XJLYjE3cmePkiqEFF5NMYy+c1PSGTNfmUf+Msou4Mejnr0"},"s3":{"s3SchemaVersion":"1.0","configurationId":"S3TestNotification","bucket":{"name":"glidenote-sqs-test","ownerIdentity":{"principalId":"AWLW0VGTI46AA"},"arn":"arn:aws:s3:::glidenote-sqs-test"},"object":{"key":"shindel.png","size":794485,"eTag":"b52627268c0e9071be00c5a38fdbc912"}}}]}

リアルタイムでS3のイベントを受信するにはSQSと常時通信しているために Supervisordなどを用いてスクリプトを動かす必要があり。

これでリアルタイムな処理に対応が出来るようになった。ちょっと現在やってるタスクに適用出来るかしばらく検証してみる。

参考

Comments