Object Storage Service (OSS) トリガーに複数のオブジェクトプレフィックスとサフィックスを設定する必要がある場合、または単一の OSS バケットに 10 を超えるトリガーを関連付ける必要がある場合は、EventBridge ベースの OSS トリガーを作成して、ファイルのアップロードなどのイベントに応答できます。
注意事項
EventBridge の OSS トリガーは、ネイティブ OSS トリガーとは異なります。次の考慮事項にご注意ください。
1 つのバケットは、最大 10 個のネイティブ OSS トリガーをサポートします。1 つのバケットに 10 個を超えるトリガーを関連付ける必要がある場合は、EventBridge ベースの OSS トリガーを作成してください。
説明ベストプラクティスとして、1 つのバケットに 10 個を超えるトリガーを関連付けることは避けてください。さらに多くのトリガーが必要な場合は、新しいバケットとそれに対応するトリガーを作成することを検討してください。
最大 50 個の EventBridge ベースの OSS トリガーを作成できます。これは EventBridge のリソース制限に準拠しています。詳細については、「制限事項」をご参照ください。
EventBridge ベースの OSS トリガーの場合、[イベントタイプ]、[オブジェクトプレフィックス]、[オブジェクトサフィックス] の組み合わせは一意である必要はありません。
EventBridge ベースの OSS トリガーでは、複数の [オブジェクトプレフィックス] と [オブジェクトサフィックス] を設定できます。ただし、[オブジェクトプレフィックス] と [オブジェクトサフィックス] では、ワイルドカードマッチングと正規表現マッチングはサポートされていません。
トリガーがアクティブになるまで約 30 秒かかります。この遅延の後、OSS 操作によって関数がトリガーされるようになります。
利用シーン
OSS トリガーを設定し、トリガールールでプレフィックスを source および test に、オブジェクトサフィックスを .rar および .zip に設定できます。指定された OSS バケットの source または test ディレクトリに圧縮ファイルがアップロードされ、オブジェクトサフィックスが .rar または .zip である場合、関数が自動的にトリガーされます。関数が実行されると、解凍されたファイルは同じバケットの別のディレクトリに保存されます。
前提条件
EventBridge
Function Compute
OSS
手順 1: EventBridge ベースの OSS トリガーの作成
Function Compute コンソールにログインします。左側のナビゲーションウィンドウで、 を選択します。
上部のナビゲーションバーでリージョンを選択します。[関数] ページで、対象の関数をクリックします。
関数詳細ページで、トリガー タブをクリックし、トリガーの作成 をクリックします。
トリガータイプ パネルの トリガータイプ パラメーターで、[Alibaba Cloud サービスイベントトリガー] の下にある [Object Storage Service (OSS)] を選択します。他のパラメーターを設定し、OK をクリックします。
パラメーター
操作
例
名前
トリガーのカスタム名を入力します。
oss-trigger
バージョンまたはエイリアス
デフォルト値は [LATEST] です。特定のバージョンまたはエイリアスのトリガーを作成する場合は、まず関数詳細ページの バージョンまたはエイリアス ドロップダウンリストからバージョンまたはエイリアスを選択する必要があります。バージョンとエイリアスの詳細については、「バージョンの管理」および「エイリアスの管理」をご参照ください。
LATEST
バケット名
既存の OSS バケットを選択します。
bucket-zh****
[オブジェクトプレフィックス]
一致させるオブジェクトプレフィックスを入力します。Function Compute では、追加料金が発生する可能性のある再帰的なトリガー呼び出しを防ぐために、プレフィックスとサフィックスを設定することを推奨します。
コンソールで [+ オブジェクトプレフィックスの追加] をクリックして、複数の [オブジェクトプレフィックス] を追加できます。
重要オブジェクトプレフィックスを
/で始めることはできません。そうしないと、OSS トリガーがトリガーされません。source
test
オブジェクトサフィックス
一致させるオブジェクトサフィックスを入力します。Function Compute では、追加料金が発生する可能性のある再帰的なトリガー呼び出しを防ぐために、プレフィックスとサフィックスを設定することを推奨します。
コンソールで、[+オブジェクトサフィックスの追加] をクリックして、複数の [オブジェクトサフィックス] を追加できます。
png
[イベントタイプ]
1 つ以上のトリガーイベントを選択します。Function Compute のイベントタイプの詳細については、「OSS イベントの定義」をご参照ください。
oss:ObjectCreated:PutObject、oss:ObjectCreated:PostObject、oss:ObjectCreated:CompleteMultipartUploadイベントパターンコンテンツ
このパラメーターは、[オブジェクトプレフィックス]、[オブジェクトサフィックス]、[イベントタイプ] を指定した後に自動的に入力されます。
重要重要:[イベントパターンコンテンツ] は慎重に変更してください。誤った変更はトリガーの失敗につながる可能性があります。パターンを変更する前に、そのルールを理解していることを確認してください。詳細については、「イベントパターン」をご参照ください。
{ "source":[ "acs.oss" ] }呼び出しメソッド
関数の呼び出し方法を選択します。デフォルトは同期呼び出しです。
同期呼び出し
トリガーの有効化のステータス
トリガー作成後すぐに有効にするかどうかを指定します。デフォルトでは、[トリガーを有効にする] が選択されています。
N/A
プッシュフォーマット
関数の入力パラメーターとして渡されるイベントのデータ形式を指定します。
[CloudEvents]:イベントの説明とペイロードを含む、共通の形式でイベントデータを記述する仕様です。サービスやプラットフォーム間でのイベントの宣言と配信を簡素化するように設計されています。
[Raw データ]:イベントペイロードのみを配信し、CloudEvents 形式の他のメタデータは含みません。
説明EventBridge ベースの OSS トリガーとは異なり、ネイティブ OSS トリガー のイベントパラメーターは、Alibaba Cloud OSS によって生成されるイベント形式である [OSS イベント] テンプレートのみをサポートします。
CloudEvents
リトライポリシーやデッドレターキューなどの高度な設定については、「高度なトリガー機能」をご参照ください。
トリガーが作成されると、[トリガー名] リストに表示されます。トリガーを変更または削除するには、「トリガーの管理」をご参照ください。
手順 2: 関数の入力パラメーターの設定
EventBridge ベースの OSS トリガーは、CloudEvents テンプレートを使用して、イベントデータを入力パラメーターとして関数に渡します。手動でイベントを関数に渡して、トリガーイベントをシミュレートできます。
関数の詳細ページの [コード] タブで、[テスト関数] の横にある
アイコンをクリックし、ドロップダウンリストから [テストパラメーターの設定] を選択します。テストパラメーターの設定 パネルの 新規テストイベントの作成 または 既存のテストイベントの変更 タブで、イベント名とイベントコンテンツを入力し、[OK] をクリックします。
eventは Function Compute の入力パラメーターです。対象の OSS バケットで指定されたイベントが発生すると、そのデータが JSON 形式で関数に渡されます。次のコードは、イベント形式の例を示しています。{ "datacontenttype": "application/json;charset=utf-8", "aliyunaccountid": "143199913****", "data": { "eventVersion": "1.0", "responseElements": { "requestId": "6364D216511B143733C5A67B" }, "eventSource": "acs:oss", "eventTime": "2023-11-04T08:49:26.000Z", "requestParameters": { "sourceIPAddress": "140.205.XX.XX" }, "eventName": "ObjectCreated:PutObject", "userIdentity": { "principalId": "143199913****" }, "region": "cn-hangzhou", "oss": { "bucket": { "name": "bucket-zh***", "arn": "acs:oss:cn-hangzhou:143199913****:bucket-zh***", "virtualBucket": "", "ownerIdentity": "143199913****" }, "ossSchemaVersion": "1.0", "object": { "size": 13, "objectMeta": { "mimeType": "text/plain" }, "deltaSize": 13, "eTag": "59CA0EFA9F5633CB0371BBC0355478D8", "key": "source/a.png" } } }, "subject": "acs:oss:cn-hangzhou:143199913****:bucket-zh***/source/a.png", "aliyunoriginalaccountid": "143199913****", "source": "acs.oss", "type": "oss:ObjectCreated:PutObject", "aliyunpublishtime": "203-11-04T08:49:26.745Z", "specversion": "1.0", "aliyuneventbusname": "default", "id": "6364D216511B143733C5A67B", "time": "2023-11-04T08:49:26Z", "aliyunregionid": "cn-hangzhou" }次の表に、
eventパラメーターのフィールドを示します。パラメーター
タイプ
値の例
説明
datacontenttype
String
application/json;charset=utf-8
data パラメーターのコンテンツタイプです。datacontenttype パラメーターは application/json;charset=utf-8 形式のみをサポートします。
aliyunaccountid
String
143199913****
ご利用の Alibaba Cloud アカウントの ID です。アカウント ID は、Function Compute コンソールの [概要] ページの [参照] セクションから取得できます。
data
{}
OSS イベントのコンテンツで、JSON オブジェクトです。CloudEvents は、元の OSS イベントコンテキストを data オブジェクト内にカプセル化します。
subject
String
acs:oss:cn-hangzhou:143199913****:bucket-zh****/source/a.png
イベントの件名です。
形式は
acs:oss:<region>:<your_account_id>:<your_bucket>です。<region>を関数を作成したときに選択したリージョンに、<your_account_id>をご利用の Alibaba Cloud アカウント ID に、<your_bucket>を同じリージョンに作成したバケットの名前に置き換えてください。aliyunoriginalaccountid
String
143199913****
イベントソースを所有する Alibaba Cloud アカウントの ID です。
source
String
acs.oss
イベントソース。OSS トリガーの場合、これは
acs.ossに固定されます。type
String
oss:ObjectCreated:PutObject
イベントタイプです。
aliyunpublishtime
Timestamp
2023-11-04T08:49:26.745Z
EventBridge がイベントを受信した時刻です。
specversion
String
1.0
CloudEvents 仕様のバージョンです。
aliyuneventbusname
String
default
イベントを受信するイベントバスの名前です。
id
String
6364D216511B143733C5A67B
イベント ID です。
time
Timestamp
2023-11-04T08:49:26Z
ソースでイベントが発生した時刻です。
aliyunregionid
String
cn-hangzhou
EventBridge がイベントを受信したリージョンです。
aliyunpublishaddr
String
140.205.XX.XX
イベントを受信したサーバーの IP アドレスです。
実際の構成に基づいて、
eventパラメーターのdataオブジェクト内の次のフィールドを変更する必要があります。userIdentity.principalId:ご利用の Alibaba Cloud アカウント ID に設定します。region:関数を作成したときに選択したリージョンに設定します。oss.bucket.name:関数と同じリージョンに作成したバケットの名前に設定します。oss.bucket.arn:形式はacs:oss:<region>:<your_account_id>:<your_bucket>です。<region>を関数を作成したリージョンに、<your_account_id>をご利用の Alibaba Cloud アカウント ID に、<your_bucket>を同じリージョン内の既存のバケットの名前に置き換える必要があります。oss.bucket.ownerIdentity:ご利用の Alibaba Cloud アカウント ID に設定します。object.keyを対象バケット内の既存のファイルのパスに設定します。
重要eventパラメーターを設定してトリガーイベントをシミュレートする場合、指定したオブジェクト (例:source/a.png) がバケットに存在することを確認してください。そうしないと、関数の呼び出しは失敗します。
手順 3: 関数コードの記述とテスト
OSS トリガーを作成した後、関数コードを記述してテストし、その正当性を検証できます。実際の OSS イベントが発生すると、関数は自動的にトリガーされます。
警告:不要な料金を避けるため、コード内で再帰的な呼び出しを作成しないでください。再帰は、OSS バケットへのファイルアップロードによってトリガーされた関数が、同じバケットにファイルを書き戻すときに発生します。この書き込み操作が関数を再トリガーし、ループが作成されます。詳細については、「OSS トリガールール」をご参照ください。
関数詳細ページで、コード タブをクリックします。コードエディタでコードを記述し、デプロイメントコード をクリックします。
以下のセクションでは、準備とサンプルコードを提供します。
説明関数が OSS リソースからの読み取りまたは書き込みを行う必要がある場合は、内部 OSS エンドポイントを使用して、パブリックネットワークのトラフィック料金を回避してください。OSS エンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
/* 準備: 1. ターミナルで次のコマンドを実行して、package.json ファイルと画像処理用の jimp モジュールをインストールします。 a. 'npm init' を実行して package.json ファイルを作成します。 b. 'npm install jimp' を実行して jimp モジュールをインストールします。 2. 関数ハンドラーが index.handler に設定されていることを確認します。 */ 'use strict'; console.log('Loading function ...'); var oss = require('ali-oss'); var fs = require('fs'); var jimp = require("jimp"); module.exports.handler = function (eventBuf, ctx, callback) { console.log('Received event:', eventBuf.toString()); var event = JSON.parse(eventBuf); var ossEvent = event.data; // OSS リージョンには「oss-」というプレフィックスが付きます (例: 「oss-cn-shanghai」)。 var ossRegion = "oss-" + ossEvent.region; // OSS クライアントを作成します。 var client = new oss({ region: ossRegion, /* Alibaba Cloud アカウントの AccessKey ペアは、すべての API にアクセスする権限を持っています。API 呼び出しや日常の O&M には RAM ユーザーを使用することを推奨します。 プロジェクトコードに AccessKey ID と AccessKey Secret をハードコーディングしないでください。ハードコーディングすると、AccessKey ペアが漏洩し、すべてのリソースのセキュリティが危険にさらされる可能性があります。 この例では、コンテキストから AccessKey ID と AccessKey Secret を取得する方法を示します。 */ accessKeyId: ctx.credentials.accessKeyId, accessKeySecret: ctx.credentials.accessKeySecret, stsToken: ctx.credentials.securityToken }); // イベントからバケット名を取得します。 client.useBucket(ossEvent.oss.bucket.name); // 処理されたイメージは processed/ ディレクトリに保存されます。 var newKey = ossEvent.oss.object.key.replace("source/", "processed/"); var tmpFile = "/tmp/processed.png"; // OSS オブジェクトを取得します。 console.log('Getting object: ', ossEvent.oss.object.key) client.get(ossEvent.oss.object.key).then(function (val) { // バッファーから OSS オブジェクトのコンテンツを読み取ります。 jimp.read(val.content, function (err, image) { if (err) { console.error("Failed to read image"); callback(err); return; } // イメージのサイズを変更し、一時ファイルに保存します。 image.resize(128, 128).write(tmpFile, function (err) { if (err) { console.error("Failed to write image locally"); callback(err); return; } // 処理されたファイルを新しいキーで OSS バケットにアップロードします。 console.log('Putting object: ', newKey); client.put(newKey, tmpFile).then(function (val) { console.log('Put object:', val); callback(null, val); return; }).catch(function (err) { console.error('Failed to put object: %j', err); callback(err); return }); }); }); }).catch(function (err) { console.error('Failed to get object: %j', err); callback(err); return }); };# 準備: # 1. 関数に設定されたロールに OSS へのアクセス権限があることを確認します。RAM コンソールにログインして、ロールに必要な権限を付与できます。 # 2. 関数ハンドラーが index.handler に設定されていることを確認します。 # -*- coding: utf-8 -*- import oss2, json from wand.image import Image def handler(event, context): evt = json.loads(event) creds = context.credentials # OSS SDK に必要です。 # Alibaba Cloud アカウントの AccessKey ペアは、すべての API にアクセスする権限を持っています。API 呼び出しや日常の O&M には RAM ユーザーを使用することを推奨します。 # プロジェクトコードに AccessKey ID と AccessKey Secret をハードコーディングしないでください。ハードコーディングすると、AccessKey ペアが漏洩し、すべてのリソースのセキュリティが危険にさらされる可能性があります。 # この例では、コンテキストから AccessKey ID と AccessKey Secret を取得する方法を示します。 auth=oss2.StsAuth( creds.access_key_id, creds.access_key_secret, creds.security_token) evt = evt['data'] bucket_name = evt['oss']['bucket']['name'] endpoint = 'oss-' + evt['region'] + '-internal.aliyuncs.com' bucket = oss2.Bucket(auth, endpoint, bucket_name) objectName = evt['oss']['object']['key'] # 処理されたイメージは processed/ ディレクトリに保存されます。 newKey = objectName.replace("source/", "processed/") remote_stream = bucket.get_object(objectName) if not remote_stream: return remote_stream = remote_stream.read() with Image(blob=remote_stream) as img: with img.clone() as i: i.resize(128, 128) new_blob = i.make_blob() bucket.put_object(newKey, new_blob)/* 準備: 1. 関数に設定されたロールに OSS へのアクセス権限があることを確認します。RAM コンソールにログインして、ロールに必要な権限を付与できます。 2. 関数ハンドラーが index.handler に設定されていることを確認します。 */ <?php use OSS\OssClient; function handler($event, $context) { $event = json_decode($event, $assoc = true); /* Alibaba Cloud アカウントの AccessKey ペアは、すべての API にアクセスする権限を持っています。API 呼び出しや日常の O&M には RAM ユーザーを使用することを推奨します。 プロジェクトコードに AccessKey ID と AccessKey Secret をハードコーディングしないでください。ハードコーディングすると、AccessKey ペアが漏洩し、すべてのリソースのセキュリティが危険にさらされる可能性があります。 この例では、コンテキストから AccessKey ペアを取得する方法を示します。 */ $accessKeyId = $context["credentials"]["accessKeyId"]; $accessKeySecret = $context["credentials"]["accessKeySecret"]; $securityToken = $context["credentials"]["securityToken"]; $evt = $event['data']; $bucketName = $evt['oss']['bucket']['name']; $endpoint = 'oss-' . $evt['region'] . '-internal.aliyuncs.com'; $objectName = $evt['oss']['object']['key']; $newKey = str_replace("source/", "processed/", $objectName); try { $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false, $securityToken); $content = $ossClient->getObject($bucketName , $objectName); if ($content == null || $content == "") { return; } $imagick = new Imagick(); $imagick->readImageBlob($content); $imagick->resizeImage(128, 128, Imagick::FILTER_LANCZOS, 1); $ossClient->putObject($bucketName, $newKey, $imagick->getImageBlob()); } catch (OssException $e) { print($e->getMessage()); } }/* 準備: 1. pom.xml ファイルに次の依存関係を追加します。 <dependencies> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.4.1</version> </dependency> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-event</artifactId> <version>1.2.0</version> </dependency> </dependencies> 2. 関数ハンドラーが example.App::handleRequest に設定されていることを確認します。 */ package example; import java.io.*; import java.util.Map; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.fc.runtime.event.OSSEvent.Event; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; public class App implements StreamRequestHandler { private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); public static final class CloudEvent { public final String id; public final String source; public final String specversion; public final String type; public final String datacontenttype; public final String dataschema; public final String subject; public final String time; public final Map<String, ?> extensions; public final Event data; @JsonCreator public CloudEvent(@JsonProperty("id") String id, @JsonProperty("source") String source, @JsonProperty("specversion") String specversion, @JsonProperty("type") String type, @JsonProperty("datacontenttype") String datacontenttype, @JsonProperty("dataschema") String dataschema, @JsonProperty("subject") String subject, @JsonProperty("time") String time, @JsonProperty("extensions") Map<String, ?> extensions, @JsonProperty("data") Event data) { this.id = id; this.source = source; this.specversion = specversion; this.type = type; this.datacontenttype = datacontenttype; this.dataschema = dataschema; this.subject = subject; this.time = time; this.extensions = extensions; this.data = data; } public String getId() { return this.id; } public String getSource() { return this.source; } public String getSpecversion() { return this.specversion; } public String getType() { return this.type; } public String getDatacontenttype() { return this.datacontenttype; } public String getDataschema() { return this.dataschema; } public String getSubject() { return this.subject; } public String getTime() { return this.time; } public Map<String, ?> getExtensions() { return this.extensions; } public Event getData() { return this.data; } } @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { CloudEvent cloudEvents = mapper.readValue(inputStream, new TypeReference<CloudEvent>() {}); Event ossEvent = cloudEvents.getData(); context.getLogger().info(String.format("received %s from %s @ %s", ossEvent.eventName, ossEvent.eventSource, ossEvent.region)); outputStream.write(String.format("received %s from %s @ %s", ossEvent.eventName, ossEvent.eventSource, ossEvent.region).getBytes()); outputStream.write(String.format("received bucket %s", ossEvent.oss.bucket.arn).getBytes()); outputStream.write(String.format("received object %s and it's size is %s", ossEvent.oss.object.key, ossEvent.oss.object.size).getBytes()); } }関数のテスト をクリックします。
実行が完了すると、コード タブの上部に結果が表示されます。
よくある質問
参照情報
設定可能な OSS イベントタイプの一覧については、「OSS イベントの定義」をご参照ください。
トリガーを変更または削除するには、「トリガー設定の更新」をご参照ください。
トリガーの問題:
どのイベントが関数の実行をトリガーしたかを判断するには、コード内でイベントタイプのログを出力します。詳細については、「ログレコード」をご参照ください。
関数内から別の関数を呼び出すには、API を使用して指定された関数を呼び出すか、CloudFlow を使用して関数をオーケストレーションします。呼び出された関数が時間のかかる操作を実行する必要があり、すべての呼び出しが非同期である場合は、非同期呼び出しの送信先サービスを設定できます。詳細については、「関数は互いに呼び出し可能ですか?」および「非同期呼び出しの送信先の設定」をご参照ください。