Configure an EventBridge OSS trigger

更新时间:
复制 MD 格式

To specify multiple object prefixes and object suffixes or associate more than 10 triggers with a single Object Storage Service (OSS) bucket, create an EventBridge-based OSS trigger to respond to events such as file uploads.

Notes

Note these differences between EventBridge-based OSS triggers and native OSS triggers:

  • You can associate a maximum of 10 native OSS triggers with a bucket. If you want to associate more OSS triggers with a bucket, you can use EventBridge-based OSS triggers.

    Note

    We recommend that you do not associate more than 10 triggers with a single bucket. If you need more triggers, create a new bucket and then create triggers for it.

  • You can create up to 50 EventBridge-based OSS triggers, which is consistent with the resource limits of EventBridge. For more information, see Limits.

  • For EventBridge-based OSS triggers, the combination of Event Type, Object Prefix, and Object Suffix does not need to be unique.

  • You can configure multiple values for Object Prefix and Object Suffix. However, fuzzy matching and regular expression matching are not supported for Object Prefix and Object Suffix.

  • An EventBridge-based OSS trigger is not active immediately. It takes about 30 seconds after creation to start triggering the associated function.

Example

You can configure an OSS trigger with a rule that specifies the prefixes source and test and the suffixes .rar and .zip. When a compressed file with a .rar or .zip suffix is uploaded to the source or test directory in a specified OSS bucket, a function is automatically triggered. After the function is executed, the decompressed file is stored in another directory in the same bucket.

Prerequisites

Step 1: Create an EventBridge OSS trigger

  1. Log on to the Function Compute console. In the left-side navigation pane, click Functions.

  2. In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.

  3. On the function details page, click the Trigger tab and then click Create Trigger.

  4. In the Trigger Type panel, set Event triggers for Alibaba Cloud services to Object Storage Service (OSS) under OK, configure the other parameters, and then click OK.

    Parameter

    Actions

    Example

    Name

    Enter a custom name for the trigger.

    oss-trigger

    Version or Alias

    The default value is LATEST. If you want to create a trigger for a different version or alias, first select the version or alias from the Version or Alias drop-down list on the function details page. For more information about versions and aliases, see Manage versions and Manage aliases.

    LATEST

    Bucket Name

    Select the OSS bucket that you created.

    bucket-zh****

    Object Prefix

    Enter the prefixes of the object names that you want to match. Function Compute recommends configuring prefixes and suffixes to prevent circular invocations and unexpected charges.

    You can click + Add Object Prefix to add multiple values for Object Prefix.

    Important

    An object prefix cannot start with a forward slash (/); otherwise, the trigger will not be triggered.

    • source

    • test

    Object Suffix

    Enter the suffixes of the object names that you want to match. Function Compute recommends configuring prefixes and suffixes to prevent circular invocations and unexpected charges.

    You can click + Add Object Suffix to add multiple values for Object Suffix.

    png

    Event Type

    Select one or more trigger events. For more information about Function Compute event types, see OSS event definitions.

    oss:ObjectCreated:PutObject, oss:ObjectCreated:PostObject, oss:ObjectCreated:CompleteMultipartUpload

    Event Pattern Content

    After you configure Object Prefix, Object Suffix, and Event Type, the system automatically populates this parameter.

    Important

    Modify the Event Pattern Content with caution. An incorrect modification can cause the trigger to fail. Before you modify an event pattern, make sure you understand the rules. For more information, see Event patterns.

    {
        "source":[
            "acs.oss"
        ]
    }

    Invocation Method

    Select the method to invoke the function. The default method is sync invocation.

    • Sync Invocation: Function Compute triggers the function and waits for the execution to complete before returning the result. This method is suitable for a wide range of use cases. For more information, see Sync invocation.

    • Async Invocation: Function Compute triggers the function and returns a response immediately. The service ensures that the function is executed at least once but does not return the execution result. This method is suitable for functions that have long execution times. For more information, see Async invocation.

    Sync Invocation

    Trigger State

    Specifies whether to enable the trigger immediately upon creation. By default, Enable Trigger is selected, which means the trigger is enabled immediately after creation.

    N/A

    Push Format

    Specifies the data format for the function's event input parameter.

    • CloudEvents: A specification for describing event data in a common format. It includes a description of the event and its payload, simplifying event declaration and delivery across services and platforms.

    • RawData: Delivers only the event payload, without the other metadata from the CloudEvents format.

    Note

    native OSS triggers are different from EventBridge-based OSS triggers. The event parameter of a native OSS trigger supports only the OSSEvents template, which is the event format generated by OSS.

    CloudEvents

    For information about advanced parameters, such as retry and dead letter settings, see Advanced trigger features.

    After the trigger is created, it is displayed on the Triggers tab. To modify or delete a trigger, see Trigger Management.

Step 2: Configure function input parameters

An EventBridge-based OSS trigger passes the event to the function as an input parameter in the CloudEvents format. You can manually pass an event to the function to simulate a trigger.

  1. On the Code tab of the function details page, click the image.png icon next Test Function and select Configure Test Parameters from the drop-down list.

  2. In the Configure Test Parameters panel, select Create New Test Event or Modify Existing Test Event. Enter an event name and the event content, and then click OK.

    The event is the input parameter for Function Compute. When a specified event occurs in the target OSS bucket, the system sends the event data to the bound function in JSON format. The following code provides an example:

    {
        "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"
    }

    The following table describes the fields in the event parameter.

    Parameter

    Type

    Example

    Description

    datacontenttype

    string

    application/json;charset=utf-8

    The content type of the data parameter. The datacontenttype parameter supports only application/json;charset=utf-8.

    aliyunaccountid

    string

    143199913****

    The ID of your Alibaba Cloud account. You can find it in the References section on the Overview page of the Function Compute console.

    data

    struct

    {}

    The OSS event content, which is a JSON object. CloudEvents contain the context that is defined by OSS when the event occurs. This information is encapsulated in the data parameter.

    subject

    string

    acs:oss:cn-hangzhou:143199913****:bucket-zh****/source/a.png

    The subject of the event.

    The format is acs:oss:<region>:<your_account_id>:<your_bucket>, where <region> is the region of the function, <your_account_id> is your Alibaba Cloud account ID, and <your_bucket> is the name of your bucket.

    aliyunoriginalaccountid

    string

    143199913****

    The ID of the Alibaba Cloud account that originated the event.

    source

    string

    acs.oss

    The event source. For OSS triggers, the value is fixed to acs.oss.

    type

    string

    oss:ObjectCreated:PutObject

    The event type.

    aliyunpublishtime

    timestamp

    2023-11-04T08:49:26.745Z

    The time when the event was received.

    specversion

    string

    1.0

    The version of the CloudEvents protocol.

    aliyuneventbusname

    string

    default

    The name of the event bus that receives the event.

    id

    string

    6364D216511B143733C5A67B

    The event ID.

    time

    timestamp

    2023-11-04T08:49:26Z

    The time when the event occurred.

    aliyunregionid

    string

    cn-hangzhou

    The region in which the event was received.

    aliyunpublishaddr

    string

    140.205.XX.XX

    The IP address of the server that receives the event.

    You must update the following fields in the data parameter to match your setup:

    • userIdentity.principalId: Replace with your Alibaba Cloud account ID.

    • region: Replace with the region where you created the function.

    • oss.bucket.name: Replace with the name of your bucket, which must be in the same region as the function.

    • oss.bucket.arn: The format is acs:oss:<region>:<your_account_id>:<your_bucket>, where <region> is the function's region, <your_account_id> is your Alibaba Cloud account ID, and <your_bucket> is the name of your bucket in the same region.

    • oss.bucket.ownerIdentity: Replace with your Alibaba Cloud account ID.

    • object.key: Replace with the object that you have uploaded to the destination bucket.

    Important

    When you simulate a trigger by configuring the event parameter, make sure the specified object, such as source/a.png in this tutorial, exists in the configured bucket. Otherwise, the function will not be triggered or its execution will fail.

Step 3: Write and test the function code

After you create the OSS trigger, write and test the function code to verify its correctness. The function is then triggered automatically by real OSS events.

Warning

You must avoid loop triggers in your code. Otherwise, you may incur unexpected charges. A typical loop trigger scenario is when an object upload to an OSS bucket triggers a function. The function then generates one or more files and writes them back to the same bucket, which in turn triggers the function again. For more information, see OSS trigger rules.

  1. On the Code tab of the function details page, enter your code in the editor and click Deploy.

    The following section describes the preparations and provides sample code.

    Note

    If you need to read from or write to OSS resources in your function, we recommend using an internal OSS endpoint to avoid internet traffic and associated fees. For more information about OSS internal endpoints, see Regions and endpoints.

    /* Preparations:
    1. Run the following commands in a terminal to create the package.json file and install the jimp module.
      a. Run npm init to create the package.json file.
      b. Run npm install jimp to install the jimp module.
    2. Make sure that the function handler is 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 regions are prefixed with "oss-". Example: oss-cn-shanghai.
         var ossRegion = "oss-" + ossEvent.region;
         // Create an OSS client.
         var client = new oss({
             region: ossRegion,
             /*
             An Alibaba Cloud account's AccessKey pair grants full API access. For security, use a RAM user for API calls and routine O&M.
             Do not hard-code your AccessKey ID and secret in your code, as this can lead to leaks and compromise your account's security.
             This example retrieves credentials from the context.
             */
             accessKeyId: ctx.credentials.accessKeyId,
             accessKeySecret: ctx.credentials.accessKeySecret,
             stsToken: ctx.credentials.securityToken
         });
         // Obtain the bucket name from the event.
         client.useBucket(ossEvent.oss.bucket.name);
         // The processed image is saved to the processed/ directory.
         var newKey = ossEvent.oss.object.key.replace("source/", "processed/");
         var tmpFile = "/tmp/processed.png";
         // Obtain the OSS object.
         console.log('Getting object: ', ossEvent.oss.object.key)
         client.get(ossEvent.oss.object.key).then(function (val) {
             // Read the content of the OSS object from the cache.
             jimp.read(val.content, function (err, image) {
                 if (err) {
                     console.error("Failed to read image");
                     callback(err);
                     return;
                 }
                 // Resize the image and save it to the tmp file.
                 image.resize(128, 128).write(tmpFile, function (err) {
                     if (err) {
                         console.error("Failed to write image locally");
                         callback(err);
                         return;
                     }
                     // Upload the read OSS object to the OSS bucket and rename the object.
                     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
         });
     };
    # Preparations:
    # 1. Make sure that the role configured for the function has permissions to access OSS. You can log on to the RAM console to grant the required permissions to the role.
    # 2. Make sure that the function's request handler is index.handler.
    
    # -*- coding: utf-8 -*-
    import oss2, json
    from wand.image import Image
    def handler(event, context):
        evt = json.loads(event)
        creds = context.credentials
        # Required by OSS SDK
        # An Alibaba Cloud account's AccessKey pair grants full API access. For security, use a RAM user for API calls and routine O&M.
        # Do not hard-code your AccessKey ID and secret in your code, as this can lead to leaks and compromise your account's security.
        # This example retrieves credentials from the context.
        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 images will be saved to 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)
    /* Preparations:
    1. Make sure that the role configured for the function has permissions to access OSS. You can log on to the RAM console and grant the role permissions to access OSS.
    2. Make sure that the function's request handler is index.handler.
    */
    
    <?php
      use OSS\OssClient;
    function handler($event, $context) {
      $event           = json_decode($event, $assoc = true);
      /*
        An Alibaba Cloud account's AccessKey pair grants full API access. For security, use a RAM user for API calls and routine O&M.
        Do not hard-code your AccessKey ID and secret in your code, as this can lead to leaks and compromise your account's security.
        This example retrieves credentials from the context.
      */
      $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());
      }
    }
    /* Preparations:
    1. Add the following dependencies to 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. Make sure that the function handler is 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());
        }
    }
  2. Click Test Function.

    After the execution is complete, you can view the result above the Code tab.

FAQ

Related topics