All Products
Search
Document Center

Function Compute:Configure an EventBridge-based OSS trigger

Last Updated:Mar 18, 2024

If you need to specify multiple object prefixes and suffixes for an Object Storage Service (OSS) trigger or associate more than 10 triggers with an OSS bucket, you can create an EventBridge-based OSS trigger to respond to events such as file uploads with ease.

Usage notes

EventBridge-based OSS triggers are different from native OSS triggers. Take note of the following items when you create an EventBridge-based OSS trigger:

  • 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 bucket. If you need more triggers, we recommend that you create a new bucket and create triggers based on the new bucket.

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

  • You do not need to guarantee the semantic uniqueness of EventBridge-based OSS triggers. The semantics specified by the Event Type, Object Prefix, and Object Suffix parameters do not need to be unique.

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

  • An EventBridge-based OSS trigger does not immediately take effect after it is created. You must wait about 30 seconds before an OSS event can trigger the associated function.

Sample scenario

You can configure an OSS trigger and set the prefix to source and test, and the suffix to .rar and .zip in the trigger rule. When a compressed file is stored in the source or test directory in the specified OSS bucket and the file suffix is .rar or .zip, the function is triggered. After the function is executed, the decompressed file is stored in another directory of the same bucket.

Before you begin

Step 1: Create an EventBridge-based 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 Configurations tab. In the left-side navigation pane, click Triggers. Then, click Create Trigger.

  4. In the Create Trigger panel, select Object Storage Service (OSS) in Event triggers for Alibaba Cloud Services from the Trigger Type drop-down list, configure the other parameters, and then click OK. The following table describes the parameters.

    Parameter

    Description

    Example

    Name

    Enter the trigger name.

    oss-trigger

    Version or Alias

    Select an alias or version. Default value: LATEST. If you want to create a trigger for another version or alias, select a 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 bucket that you created.

    bucket-zh****

    Object Prefix

    Enter prefixes of the object names that you want to match. We recommend that you specify Object Prefix and Object Suffix in Function Compute to avoid additional costs caused by nested loops.

    You can click + Add Object Prefix to add more entries for the Object Prefix parameter.

    Important

    The prefix cannot start with a forward slash (/). Otherwise, the OSS trigger cannot be triggered.

    • source

    • test

    Object Suffix

    Enter suffixes of the object names that you want to match. We recommend that you specify Object Prefix and Object Suffix in Function Compute to avoid additional costs caused by nested loops.

    You can click + Add Object Suffix to add more entries for the Object Suffix parameter.

    png

    Event Type

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

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

    Event Pattern Content

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

    Important

    Exercise caution when you modify the Event Pattern Content parameter. A misoperation may lead to failure of triggerring. Before you decide whether to modify an event pattern, you must understand the rules of event patterns. For more information, see Event patterns.

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

    Invocation Method

    Select the method that is used to invoke the function. Default value: Sync Invocation.

    • Sync Invocation: After an event triggers a function, Function Compute returns the execution result when the execution is complete. This method is suitable for a wide range of scenarios. For more information, see Synchronous invocations.

    • Async Invocation: After an event triggers a function, Function Compute immediately returns a response and ensures that the function is executed at least once. However, detailed execution results are not returned. This invocation method is suitable for functions that have high scheduling latency. For more information, see Overview.

    Sync Invocation

    Trigger State

    Specify whether to enable the trigger immediately after it is created. By default, Enable Trigger is selected, which indicates that the trigger is enabled immediately after it is created.

    N/A

    Push Format

    Specify the data format of input parameters of the function. The data is passed by using the event parameter of the function. Valid values:

    • CloudEvents: a specification that describes event data in a common format, including event descriptions and event payload data. This specification is used to simplify event declaration and transmission between different services and platforms.

    • RawData: a specification that delivers only event payload data and does not include other metadata information in the CloudEvents format.

    Note

    Native OSS triggers and EventBridge-based OSS triggers use different push formats. The event parameter of a native OSS trigger supports the OSSEvents template, which is the event format generated by OSS.

    CloudEvents

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

Step 2: Configure input parameters of the function

The event sources of EventBridge-based OSS triggers are passed to the function in the CloudEvents format, which acts as an input parameter. You can manually pass event to the function to trigger the function.

  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, click the Create New Test Event or Modify Existing Test Event tab, enter the event name and event content, and then click OK.

    When a specified event occurs in a specified OSS bucket, the event data is sent to the bound function in JSON format. The event data is passed in the event parameter to Function Compute. 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 fields in event.

    Parameter

    Type

    Example

    Description

    datacontenttype

    String

    application/json;charset=utf-8

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

    aliyunaccountid

    String

    143199913****

    The ID of the Alibaba Cloud account. You can obtain the ID of the Alibaba Cloud account in the References section on the Overview page in 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 event subject.

    Format: acs:oss:<region>:<your_account_id>:<your_bucket>. <region> indicates the region that you selected when you created the function. <your_account_id> indicates the ID of your Alibaba Cloud account. <your_bucket> indicates the name of the bucket that you created in the same region.

    aliyunoriginalaccountid

    String

    143199913****

    The ID of the Alibaba Cloud account.

    source

    String

    acs.oss

    The event source. 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 specification.

    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.

    Configure the data field of the Event parameter based on your business requirements.

    • userIdentity.principalId: the ID of your Alibaba Cloud account.

    • region: the region that you selected when you created the function.

    • oss.bucket.name: the name of the created bucket in the same region as the function.

    • oss.bucket.arn: the Alibaba Cloud Resource Name (ARN) of the bucket, which is in the acs:oss:<region>:<your_account_id>:<your_bucket> format. <region> indicates the region that you selected when you created the function. <your_account_id> indicates the ID of your Alibaba Cloud account. <your_bucket> indicates the name of the bucket that you created in the same region.

    • oss.bucket.ownerIdentity: the ID of your Alibaba Cloud account.

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

      Note

      Make sure that the specified object exists in the specified bucket. Otherwise, the function cannot be executed or the execution fails. In this example, source/a.png is used.

Step 3: Write and test the function

After you create the trigger, you can write function code and test the function to verify whether the code is correct. When an OSS event occurs, the function is automatically triggered.

Warning

You must avoid loop triggers in the code. Otherwise, unnecessary costs are incurred. For example, when objects are uploaded to an OSS bucket, the upload operation triggers a function. Then, the function generates one or more objects and writes the objects to the OSS bucket, and the write operation triggers the function again. This leads to a loop. For more information, see Triggering rules.

  1. On the Code tab of the Function Details page, write code in the code editor and click Deploy.

    The following section describes the preparations that you must make and the sample code:

    Note

    If you want to read data from and write data to OSS resources in your function, we recommend that you use an internal endpoint of OSS to access the OSS resources. If you use a public endpoint, you are charged for data transferred over the Internet. For more information about the format of OSS internal endpoints, see Regions and endpoints.

    /* Preparations:
    1. Run the following commands on the client to create the package.json file and install the jimp module. 
      a. Run the npm init command on the client to create the package.json file. 
      b. Run the npm install jimp command 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,
             /*
             The AccessKey pair of an Alibaba Cloud account can be used to access all API operations. Using these credentials to perform operations in Function Compute is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. 
             We recommend that you do not save the AccessKey ID and AccessKey secret in your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources under your account may be compromised. 
             In this example, the AccessKey ID and AccessKey secret are obtained 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 the 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 handler of the function 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
        # The AccessKey pair of an Alibaba Cloud account can be used to access all API operations. Using these credentials to perform operations in Function Compute is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. 
        # We recommend that you do not save the AccessKey ID and AccessKey secret to your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources in your account may be compromised. 
        # In this example, the AccessKey ID and AccessKey secret are obtained 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 the 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 handler of the function is index.handler. 
    */
    
    <?php
      use OSS\OssClient;
    function handler($event, $context) {
      $event           = json_decode($event, $assoc = true);
      /*
        The AccessKey pair of an Alibaba Cloud account can be used to access all API operations. Using these credentials to perform operations in Function Compute is a high-risk operation. We recommend that you use a RAM user to call API operations or perform routine O&M. 
        We recommend that you do not save the AccessKey ID and AccessKey secret to your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources in your account may be compromised. 
        In this example, the AccessKey ID and AccessKey secret are obtained 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 the pom.xml file. 
    <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 function is executed, you can view the result on the Code tab.

FAQ

Additional information

  • For more information about the OSS event types that you can configure, see OSS events.

  • If you want to modify or delete an existing trigger, see Modify the configurations of a trigger.

  • Trigger-related issues:

    • If you want to check the events that trigger a function, you can specify the system to print event type logs in your code. For more information, see Log records.

    • If you want to use a function to invoke another function, you can use an API operation to invoke the function or use function workflows to orchestrate functions. If the invoked function requires a long time to execute and involves asynchronous invocations, you can configure destination services for asynchronous invocations. For more information, see Can functions invoke each other? and Configure a destination for an asynchronous invocation.