Cloud FunctionsのCloud Storageトリガーをフォルダレベルで指定したい!!

こんにちは!SCSKの江木です。

先日、Dialogflow CXのAgentからのテストケース作成を自動化していて、「あるフォルダにファイルがアップロードされたら起動するCloud Functionsを作りたい」とふと思いました。(テストケース作成自動化について知りたい方は以下のブログを参照ください。)

そこで今回はバケットレベルで指定するCloud Storageトリガーをどうにかしてフォルダレベルで指定できないか調べてみました。

Cloud FunctionsとCloud Storage

まずはCloud FunctionsとCloud Storageについて簡単に紹介します。

Cloud Functionsとは?

Cloud Functionsは、サーバーレスコンピューティングプラットフォームであり、コードを記述してデプロイすることで、イベントに応じて自動的に実行される関数を作成することができます。サーバーの準備や管理を行う必要がなく、コードを記述してデプロイするだけで、スケーラブルかつ高可用性のインフラストラクチャ上でコードを実行することができます。

バージョンは第1世代と第2世代があります。第2世代はCloud RunとEventarcに構築されており、処理速度の向上や多くのイベントへの対応を図っています。(第2世代のCloud Functionsを作成すると、Cloud Runのリソースも作成されます。)

今回は性能がよい第2世代のCloud Functionsを扱います。

より詳しい内容は公式ドキュメントを参照ください。

Cloud Storageとは?

Cloud Storageはオブジェクトストレージサービスで、容量無制限で非構造化データを安全に保存し、世界中どこからでも高速アクセスできるサービスです。データのアーカイブ、バックアップ、コンテンツ配信、ビッグデータ分析、機械学習など、幅広いユースケースに対応できます。また、従量課金制でコストを抑え、ニーズに合わせて柔軟に拡張できます。

より詳しい内容は公式ドキュメントを参照ください。

Cloud Functions(第2世代)のCloud Storageトリガーとは?

Cloud Functionsのトリガーとは?

Cloud Functionsではトリガーを指定することで、イベントに応じて自動実行できるようになります。

このトリガーにはどのような種類があるのか、公式ドキュメントでは以下のように記述されています。

トリガーは次の 2 つのカテゴリに分類されます。

  • HTTP トリガー。HTTP(S) リクエストに応答し、HTTP 関数に対応します。
  • イベント トリガー。Google Cloud プロジェクト内のイベントに応答し、イベント ドリブン関数に対応します。

Cloud Functions(第 2 世代)では、次のタイプのトリガーがサポートされています。

  • HTTP トリガー
  • イベント トリガー:
    • Pub/Sub トリガー
    • Cloud Storage トリガー
    • Firestore トリガー
    • 汎用の Eventarc トリガー
      • Eventarc でサポートされているすべてのイベントタイプをサポート(Cloud Audit Logs を介した 90 以上のイベントソースを含む)

様々なトリガーがありますね!今回はこの中でもCloud Storageトリガーに着目します。

Cloud Storageトリガーとは?

公式ドキュメントによると、Cloud Functions(第2世代)のCloud Storageトリガーは以下のイベントタイプがサポートされています。

イベント イベントタイプ 説明
オブジェクトのファイナライズ google.cloud.storage.object.v1.finalized(Eventarc 経由) 新しいオブジェクトが作成されるか、既存のオブジェクトが上書きされ、そのオブジェクトの新しい世代が作成されると送信されます。
オブジェクトの削除 google.cloud.storage.object.v1.deleted(Eventarc 経由) オブジェクトが完全に削除された場合に発生します。
オブジェクトのアーカイブ google.cloud.storage.object.v1.archived(Eventarc 経由) オブジェクトのライブ バージョンが非現行バージョンになると送信されます。詳細については、オブジェクトのバージョニングをご覧ください。
オブジェクト メタデータの更新 google.cloud.storage.object.v1.metadataUpdated(Eventarc 経由) 既存オブジェクトのメタデータが変更された場合に送信されます。

「あるフォルダにファイルがアップロードされたら起動するCloud Functionsを作りたい」という用途ですと、「google.cloud.storage.object.v1.finalized」が最適ですね。

Cloud Storageトリガーの仕様(2024年7月現在)

Cloud Storageトリガーの説明は公式ドキュメントでは以下のように記載されています。

Cloud Functions では、Cloud Storage トリガーによって、Cloud Storage の変更に応じて関数を呼び出すことができます。関数に Cloud Storage トリガーを指定するときに、イベントタイプを選択して Cloud Storage バケットを指定します。この関数は、指定されたバケット内のオブジェクト(ファイル)が変更されるたびに呼び出されます。

赤字箇所にありますように、Cloud Storageトリガーはバケットレベルでのファイルの変更にのみ対応しています。

つまり、「以下のようなバケットの構造を考えたとき、フォルダAにファイルがアップロードされたときのみ関数が実行されるトリガーを作ることができない」ということになります。困りました…

フォルダレベルでのCloud Storageトリガーを実装してみる

先ほど、フォルダレベルでのファイル変更に対応したCloud Storageトリガーはないことがわかりました。そこで、Cloud Functionでの処理を工夫することで、フォルダレベルでのCloud Storageトリガーを使っているかのように見せたいと思います。

今回実装するのは、hogehogeフォルダとfugafugaフォルダをバケットに作り、hogehogeフォルダにファイルがアップロードされたときのみ、ログにメッセージを出力する簡易的なシステムです。

バケットの作成

まず、バケットを作成します。以下のような設定でバケットを作成します。

次にフォルダを作成していきます。hogehogeフォルダとfugafugaフォルダを作成します。

これでバケットの作成は完了です。

Cloud Functionsの作成

それではCloud Functionsを作っていきます。以下のような第2世代の関数を作ります。

Cloud Storageトリガーのイベントタイプはgoogle.cloud.storage.object.v1.finalized」を設定します。

コーディングをしていきます。言語はPython3.12を使います。

hogehogeフォルダにファイルが格納されたときのみ、ログにメッセージを出力するようにします。

import functions_framework

# Triggered by a change in a storage bucket
@functions_framework.cloud_event
def hello_gcs(cloud_event):
    data = cloud_event.data
    bucket = data["bucket"]
    name = data["name"]

    folder_name = data["name"].split("/")[-2]
    file_name = data["name"].split("/")[-1]

    print("これから処理を行います")
    if folder_name == "fugafuga":
        return
    elif folder_name == "hogehoge":
        print(file_name+"が格納されました!")
コーディングが行いましたら、デプロイし、実装完了です。

実装結果

それでは実際にフォルダにファイルを格納して、動作確認をしていきます。

まず、hogehogeフォルダにtest.txtというファイルをアップロードします。

すると、以下のように「test.txtが格納されました!」というメッセージがログに出力されました。

一方で、fugafugaフォルダにtest.txtをアップロードしてみるとどうなるでしょうか?

メッセージが出力されませんでした。

うまく実装することができました!

しかし、トリガーで関数が実行されてしまっているので、あくまで疑似的なフォルダレベルのトリガーです。

おわりに

今回はフォルダレベルでのCloud Storageトリガーはないということがわかったので、疑似的なフォルダレベルのCloud Storageのトリガーを実装してみました。

フォルダレベルでのCloud Storageトリガーがない理由ですが、オブジェクトストレージであるがゆえにフラットな階層になっていることが原因であると私は考えています。

しかし!最近、Google Cloudより以下のブログが出ました!

このブログによると、Cloud Storageが階層名前空間(HNS)に対応するになるようです!

ということはフォルダレベルでのCloud Storageトリガーが実装される日が近いのかもしれません…

以上、Cloud Storageトリガーのお話でした!!

最後まで読んでいただき、ありがとうございました。

タイトルとURLをコピーしました