8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

株式会社オープンストリームAdvent Calendar 2019

Day 14

Alibaba Cloud Function Computeのトリガーを全種試す

Last updated at Posted at 2019-12-13

Alibaba Cloud Function Computeのトリガーを全種試す

はじめに

本稿は株式会社オープンストリーム Advent Calendar 2019の14日目です。
図らずも二年連続で14日目だったので今年はあえてこの日を選びました。とはいえ深い意味はありません。

Alibaba CloudのFunction Computeはフルマネージ型の関数実行サービスです。AWSでいうところのLambdaですね。
さまざまなイベントトリガーをサポートしているので全種試してみたいと思います。
それぞれイベントがどのような形式で送信されるのか見ていきましょう。

トリガー一覧

Function Computeの関数の設定から指定できるトリガーの種類は下記のとおりです。

  • OSSトリガー
  • Log Serviceトリガー
  • タイムトリガー
  • CDNトリガー
  • Table Storeトリガー
  • MNSトリガー

これらに加え、作成時のみ設定可能なHTTPトリガーと、連携元の方で設定されるAPI Gatewayトリガーがあるため全部で8種類です。

関数

今回用意した関数は以下の通りです。

index.js
'use strict';

exports.dump = (event, context, callback) => {
  console.log('event:', event.toString());
  const response = {
    statusCode: 200,
    body: event.toString(),
  };
  callback(null, response);
};

イベントをログ出力するだけの単純なものです。Node.jsの場合eventはBufferで渡される場合もあるのでtoString()を呼んでいます。responseはAPI Gatewayトリガーを意識してのものです。他のトリガーでは使いません。
この関数をServerless Frameworkでデプロイしていきます。

serverless.yml
service: myproject
provider:
  name: aliyun
  runtime: nodejs10
  credentials: ~/.aliyuncli/credentials
  stage: dev
  region: ${env:ALIYUN_REGION}

plugins:
  - serverless-aliyun-function-compute

functions:
  dump:
    handler: index.dump
    events:
      - http:
          path: /dump
          method: get
      - oss:
          sourceArn: acs:oss:${env:ALIYUN_REGION}:${env:ALIYUN_ACCOUNT_ID}:${env:OSS_BUCKET_NAME}
          triggerConfig:
            events:
              - oss:ObjectCreated:*

今のところAPI GatewayトリガーとOSSトリガーのみサポートされているので他は手動で設定します。1

実践

API Gatewayトリガー

API Gatewayトリガーは当然リクエストの情報がイベントとして送信されます。

$ curl -s http://<api-gateway-id>-ap-northeast-1.alicloudapi.com/dump | jq
{
  "body": "",
  "headers": {
    "X-Ca-Api-Gateway": "01234567-89AB-CDEF-0123-456789ABCDEF",
    "X-Real-IP": "xxx.xxx.xxx.xxx",
    "X-Forwarded-Proto": "http",
    "X-Forwarded-For": "xxx.xxx.xxx.xxx",
    "User-Agent": "curl/7.29.0",
    "Accept": "*/*",
    "CA-Host": "00112233445566778899aabbccddeeff-ap-northeast-1.alicloudapi.com"
  },
  "httpMethod": "GET",
  "isBase64Encoded": true,
  "path": "/dump",
  "pathParameters": {},
  "queryParameters": {}
}

OSSトリガー

testというファイルがあると思って読んでください。

aliyun oss cp test oss://<bucket-name>/test

出力されたイベントを整形したものが以下になります。

{
  "events": [
    {
      "eventName": "ObjectCreated:PostObject",
      "eventSource": "acs:oss",
      "eventTime": "2019-12-13T07:58:49.000Z",
      "eventVersion": "1.0",
      "oss": {
        "bucket": {
          "arn": "acs:oss:ap-northeast-1:<account-id>:<bucket-name>",
          "name": "<bucket-name>",
          "ownerIdentity": "<owner-account-id>",
          "virtualBucket": ""
        },
        "object": {
          "deltaSize": 210,
          "eTag": "00112233445566778899AABBCCDDEEFF",
          "key": "test",
          "size": 10
        },
        "ossSchemaVersion": "1.0",
        "ruleId": "00112233445566778899aabbccddeeff01234567"
      },
      "region": "ap-northeast-1",
      "requestParameters": {
        "sourceIPAddress": "xxx.xxx.xxx.xxx"
      },
      "responseElements": {
        "requestId": "00112233445566778899AABB"
      },
      "userIdentity": {
        "principalId": "<principal-id>"
      }
    }
  ]
}

Log Serviceトリガー

出力されたイベントを整形したものが以下になります。ログの内容は届かないので改めてSDKで取得する必要があるようです。

{
  "parameter": {
    "source": {
      "endpoint": "http://ap-northeast-1.log.aliyuncs.com"
    },
    "target": {
      "endpoint": "http://ap-northeast-1.log.aliyuncs.com",
      "logstoreName": "<log-store-name>",
      "projectName": "<log-project-name>"
    }
  },
  "source": {
    "endpoint": "http://ap-northeast-1.log.aliyuncs.com",
    "projectName": "<log-project-name>",
    "logstoreName": "<log-store-name>",
    "shardId": 0,
    "beginCursor": "MTU3NjIyNjEzOTEyNTAwMjE2NA==",
    "endCursor": "MTU3NjIyNjEzOTEyNTAwMjE2NQ=="
  },
  "jobName": "00112233445566778899aabbccddeeff01234567",
  "taskId": "00112233-4455-6677-8899-aabbccddeeff",
  "cursorTime": 1576228992
}

タイムトリガー

出力されたイベントを整形したものが以下になります。payloadはトリガーに設定した文字列がそのまま届きます。

{
  "triggerTime": "2019-12-13T09:50:00Z",
  "triggerName": "<trigger-name>",
  "payload": "<paylod>"
}

CDNトリガー

出力されたイベントを整形したものが以下になります。CDNのイベントで何か処理をしたいというシチュエーションが想像できませんでした。

{
  "events": [
    {
      "eventName": "CachedObjectsRefreshed",
      "eventSource": "cdn",
      "region": "cn-hangzhou",
      "eventVersion": "1.0.0",
      "eventTime": "2019-12-13T18:21:40+08:00",
      "userIdentity": {
        "aliUid": "<account-id>"
      },
      "eventParameter": {
        "completeTime": 1576232499,
        "createTime": 1576232492,
        "domain": "cdn.example.com",
        "objectPath": [
          "/index.html"
        ],
        "objectType": "File",
        "taskId": 1234567890
      },
      "traceId": "00112233-4455-6677-8899-aabbccddeeff"
    }
  ]
}

Table Storeトリガー

トリガーは発動したのですが何故かJSONではありませんでした。
どうやらTable StoreトリガーのイベントはCBORという形式らしいです。2
ちょっと調査が追いつかないので後回しにします。

 \ufffdgVersiongSync-v1gRecords\ufffd\ufffdgColumns\ufffd\ufffdjColumnNamednameiTimestamp\u001b

MNSトリガー

出力されたイベントを整形したものが以下になります。

{
  "TopicOwner": "<owner-account-id>",
  "Message": "<message-payload>",
  "Subscriber": "<subscriber-account-id>",
  "PublishTime": 1576235089696,
  "SubscriptionName": "<subscription-name>",
  "MessageMD5": "00112233445566778899AABBCCDDEEFF",
  "TopicName": "<topic-name>",
  "MessageId": "00112233445566778899AABBCCDDEEFF"
}

HTTPトリガー

HTTPトリガーは他のトリガーと異なり関数の作成時にしか設定できません。また、呼び出される関数の引数も独特です。以下は関数作成時に生成されたソースコードから不要な箇所を取り除いたものですが、引数がどのようなものかは把握できるかと思われます。

 var getRawBody = require('raw-body');

 module.exports.handler = function(req, resp, context) {
    console.log('hello world');

    var params = {
        path: req.path,
        queries: req.queries,
        headers: req.headers,
        method : req.method,
        requestURI : req.url,
        clientIP : req.clientIP,
    }

    getRawBody(req, function(err, body) {
        for (var key in req.queries) {
          var value = req.queries[key];
          resp.setHeader(key, value);
        }
        params.body = body.toString();
        resp.send(JSON.stringify(params, null, '    '));
    });
}

まとめ

AWS Lambdaと同様にさまざまなイベントを起点に関数を実行できるFunction Computeの各種イベントの形式を見てきました。いつかトリガーを利用する際に参照できるようにイベント形式を並べておきましたが、皆様の参考にもなれば幸いです。

余談

試す上で詰まったのがトリガーの権限でした。ロールを選択または作成するのですが、難しいことは考えずに「クイック承認」を使用するのが最も無難な選択だということに気づくまでに多くの時間がかかってしまいました。

  1. https://serverless.com/framework/docs/providers/aliyun/events/

  2. https://jp.alibabacloud.com/help/doc-detail/100092.htm

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?