Google Cloud Platform の Cloud Storage にファイルがアップロードされたことを通知として受け取る方法を紹介します。一応、最低限の動作確認ができたのでメモっておきます。Google Cloud にも使用法のページ(Pub/Sub Notifications for Cloud Storage の使用法)があるのですが、あまり丁寧でないので一応。
目的: Cloud Storage にファイルがアップロードされたのを知りたい
Storage の変更を受け取るには?
まず、Storage に変更があったときに通知を受け取るには2つ方法があります。
- PubSub のmessage として受け取る
- 実装したCloud Function で受けとる
PubSubを使っていて、この枠組みを使うのがスマートな設計であると思ったのでこちらを利用しました。
何を通知してくれるのか?
読めば書いてあるのですが、通知のトリガーとなるイベントは下記のとおりです。
Event Type | 内容 |
---|---|
OBJECT_FINALIZE | バケットで新しいオブジェクト(または既存オブジェクトの新しい世代)が作成 |
OBJECT_METADATA_UPDATE | オブジェクトのメタデータを更新 |
OBJECT_DELETE | オブジェクトを削除 |
OBJECT_ARCHIVE | (バージョニングが有効になっている場合にのみ) |
PubSubのメッセージとして受け取るには
Storage の bucket に notification としてtopic を割り当てるだけです。bucket への変更を通知するpublisher を用意してもらう、というイメージです。
これはコマンドで設定できます。
$ gsutil notification create -t TOPIC_ID -f json gs://BUCKET_ID
くわしくはgsutil notificationの使い方を見ると「いろいろあるなー」ということが分かります。
PubSub でsubscribe していると、Storage に変更があったときメッセージが送られてきます。メッセージはDataとAttributesから構成されますが、どんな変更があったを知らせる"Event Type"に入っています。最初Dataだけを見ていて「分からねーじゃん」と思って焦りました。^^;
動作確認
まずは簡単な動作確認
環境用意(省略可)
適当な環境がある人や後で実装をしない人には不要ですが、一応。コンソール(console.google.cloud.com)でプロジェクトを作成します。プロジェクト([PROJECT_ID]
とします)で、必要な権限を付与したサービスアカウントを作成します。
Linux端末から、認証を通した後、サービスアカウントのカギを環境変数に設定します。
$ gcloud auth login
$ export GOOGLE_APPLICATION_CREDENTIALS=service_account.key
$ gcloud config set project PROJECT_ID
プロジェクトでPubSub を使えるようにしておきます。
notification を用意する
(1) コンソールでbucketを用意します。 gsutil mb gs://[BUCKET_NAME]/
でもできるはずなのですが、こちらで作成してもコンソールに現れなかったので、ここではコンソールで作成したものを利用します。
(2) topic を用意します
$ gcloud pubsub topics create TOPIC_ID
Created topic [projects/project_id/topics/topic_id].
(3) topic にbucket での変更を知らせるように設定します。
$ gsutil notification create -t TOPIC_ID -f json gs://BUCKET_ID
Created notification config projects/_/buckets/bucket_name/notificationConfigs/2
(4) topic に subscription を用意します。
$ gcloud pubsub subscriptions create SUBSCRIPTION_ID --topic=TOPIC_ID
Created subscription [projects/project_id/subscriptions/subscription_id].
Storage にファイルをアップロードしたときの反応
手抜きなので、コンソール(ブラウザ)からファイルをアップロードしてみました。しばらくたって(すぐには反応が無い)からpull してみます。
$ gcloud pubsub subscriptions pull --auto-ack SUBSCRIPTION_ID
とすると応答があります。
受け取ったメッセージのAttribute にはファイル名や変更内容(EventType)の情報が入っています。
bucketId=bucket_trigger01
eventTime=2020-08-22T13:43:31.929768Z
eventType=OBJECT_FINALIZE
notificationConfig=projects/_/buckets/bucket_id/notificationConfigs/2
objectGeneration=1598103811929971
objectId=test.txt
payloadFormat=JSON_API_V1
メッセージのdata の方は json ですが、
{
"kind": "storage#object",
"id": "bucket_trigger01/test.txt/12345678901234",
"selfLink":"https://www.googleapis.com/storage/v1/b/bucket_id/o/test.txt",
"name": "test.txt",
"bucket": "bucket_trigger01",
"generation": "12345678901234",
"metageneration": "1",
"contentType": "text/plain",
"timeCreated": "2020-08-22T13:43:31.929Z",
"updated": "2020-08-22T13:43:31.929Z",
"storageClass": "STANDARD", "timeStorageClassUpdated": "2020-08-22T13:43:31.929Z", "size": "13", "md5Hash": "ABCDEFGHIJK", "mediaLink": "https://www.googleapis.com/download/storage/v1/b/bucket_id/o/test.txt ?generation=1598103811929971&alt=media",
"crc32c": "ABCDEF==",
"etag": "abcedghijk="
}
のような形で返ってきました。ファイル名、バケット名だけでなく generation も取得できますね。どう使うのかな。
まとめ
できたことと今後の課題
Storage の変更をPubSubで知る方法を確認した。
動かすにあたっては、自分の過去のメモを見ました。
今後ですが、とりあえず思いつくTODOは
- とりあえずpython script で変更を追跡し続けるプログラムを書いてみる。
- 変更メッセージの仕様をもっと読み込む
かな。あ、日付が変わった。
(2020/08/22)
とりあえず使わなそうなので、このまま一時保留します。(2020/09/03)