イベント駆動サービス FucntionComputeでオブジェクトストレージを操る

こんにちは。SB Cloud ソリューションアーキテクトのMIです。 皆さん、Function Computeは利用されておりますでしょうか。ドキュメントの概要やユーザーガイドなどを読んでみますと少し難しいように思えて、使ってみたいけど躊躇されている方もいらっしゃるのではないでしょうか。 今回はFunction Computeを実際に使ってみましたので、その内容についてご紹介させて頂きます。

Function Computeとは

Function Computeはイベント駆動型のフルマネージドコンピューティングサービスです。Function ComputeはサーバーレスのAPI実行環境で、サーバーを構築することなく、コードを実行することができます。Alibaba CloudのOSSやLog Serviceなどのプロダクトやタイマーのイベントを検知して、自動でコードを実行することが可能なため、イベントをトリガーとした運用やアプリケーション連携が実現できます。

検証について

今回はご要望がありそうなケースとして「OSSのイベントをトリガーにして自動でコードを実行する」というシナリオで検証を実施させて頂きました。

検証シナリオ

OSSのバケットにファイル名の接尾辞が「.zip」のファイルがアップロードされましたら、該当ファイルのunzip(解凍)を実施し、同バケット内のunzipディレクトリに解凍されたファイルを作成します。

検証シナリオの説明:
検証シナリオのFunction Compute の動作としましては、OSSに「.zip」のファイルがアップロードされたイベントをトリガーとして、アップロードされたファイルをunzip(解凍)する関数コードを実行しています。

検証手順

前提条件:

  • Log ServiceにFunction Computeのログ記録用として以下のLogstoreが作成されていること。
    リージョン Asia Pacific NE 1 (Tokyo)
    プロジェクト名 funccomputer
    Logstore名 funccomputer-logstore
  • OSSにファイルアップロード先・解凍先用に以下のバケットが作成されていること。
    バケット名 function-computer-bucket

検証手順:

1. Function Computeのコンソールにログインします。

2. [サービスの作成]をクリックします。以下の通り、「demo」サービスを作成します。必要事項を入力し、[OK]をクリックします。

サービス名 demo
リージョン 日本(東京)
詳細設定 ON
ネットワーク設定
インターネットアクセス ON
VPC設定 デフォルト値
ログ設定
ログオブジェクト funccomputer
Logstore Funccomputer-logstore
ロール設定
ロール操作 「新しいロールを作成してください」を選択し、[承認]をクリックします

ユーザー管理RAM画面でRole Nameを[fc-role]へ変更し[権限付与に同意]をクリックします。サービス作成画面に戻り、ロール設定に「fc-role(FC-post-log-to-funccomputer-funccomputer-logstore)」が表示されます。

システムポリシー デフォルト値(選択不要)

<サービスの作成画面>

3. [関数の作成]をクリックします。 関数テンプレートの選択画面でブランク関数の[選択]をクリックします。

<関数テンプレートの選択画面>

4. トリガー設定画面で以下の通り設定します。必要事項を入力し、[次へ]をクリックします。

トリガータイプ Object Storage Service(OSS)
トリガー名 tg_unzip
Bucket function-computer-bucket
イベント oss:ObjectCreated:PostObject
トリガールール
接頭辞 (入力不要)
接尾辞 .zip

<トリガー設定画面>

5. 基本管理設定画面で以下の通り設定します。必要事項を入力し、[次へ]をクリックします。

サービス名 demo
関数名 unzip
ランタイム python2.7
関数コード インライン編集※コードの内容は下記「unzip関数コード」を入力
関数ハンドラ index.handler
メモリ 512MB
タイムアウト 60秒

unzip関数コード

# -*- coding: utf-8 -*-
import os
import oss2
import zipfile
import shutil
import time
import logging
import json


def handler(event, context):
    logger = logging.getLogger()
    creds = context.credentials
    auth = oss2.StsAuth(creds.accessKeyId, creds.accessKeySecret, creds.securityToken)
    bucket = oss2.Bucket(auth, 'oss-ap-northeast-1-internal.aliyuncs.com', 'function-computer-bucket')
    evt = json.loads(event)
    obj_key = evt['events'][0]['oss']['object']['key']
    if("zip" not in obj_key):
      return "not a zip file"
    logger.info('obj key:' + obj_key)
    tmpdir = '/tmp/download/'
    unzipdirtmp='/tmp/unzipdir/'
    os.system("rm -rf /tmp/*")
    os.mkdir(tmpdir)
    zipfiledownload=tmpdir +"/"+obj_key+".zip"
    bucket.get_object_to_file(obj_key, zipfiledownload)
    un_zip(zipfiledownload,unzipdirtmp)
    uploadfilename="file list is:"
    for fpathe,dirs,fs in os.walk(unzipdirtmp):
        for f in fs:
            filepath=os.path.join(fpathe,f)
            with open(filepath, 'rb') as filedata:
                bucket.put_object('unzip/'+f, filedata)
                uploadfilename=uploadfilename+" "+f
    
def un_zip(file_name,unzipdir):
    """unzip zip file"""
    logger = logging.getLogger()
    indexnum=0
    zip_file = zipfile.ZipFile(file_name)
    if os.path.isdir(unzipdir):
        os.system("rm -rf "+unzipdir + "*")
    else:
        os.mkdir(unzipdir)
    for names in zip_file.namelist():
        indexnum+=1
        logger.info("index is:"+str(indexnum)+" filename is "+names)
        zip_file.extract(names,unzipdir)
    zip_file.close()

<基本管理設定画面>

6. サービスロール管理画面で以下の通り設定します。必要事項を入力し、[次へ]をクリックします。

アクセス許可の設定
システムポリシー
AliyunOSSFullAccess
AliyunLogFullAccess※上記を選択後、[承認]をクリックします。ユーザー管理RAM画面でRole Name[fc-role]の[権限付与に同意] をクリックします。関数の許可の設定画面に戻り、サービスロール情報でロール(fc-role)に上記権限が追加されます。
呼び出しロール管理
ロール操作
クイック承認

※上記を選択後、[承認]をクリックします。ユーザー管理RAM画面でOSSクラウドリソースにアクセスするための権限のリクエスト「AliyunOSSEventNotificationRole」の[権限付与に同意] をクリックします。関数の許可の設定画面に戻り、呼び出しロール管理で呼び出しロールに上記権限が追加されます。

<サービスロール管理画面>

7. プレビュー画面で[作成]をクリックします。

<プレビュー画面>

8. テストを実施します。
OSSのコンソールからバケットfunction-computer-bucketにzipで圧縮されたファイルをアップロードします。

今回はtg_test.zipというファイルをアップロードしています。 なお、tg_test.zipは、tg_test0001.txt、tg_test0002.txt、tg_test0003.txtの3つのファイルが圧縮されています。

tg_test.zipのアップロードが終わると同時にunzipディレクトリが作成されています。この動作は、Function Computeのトリガーで接尾辞.zipのファイルがアップロードされたことのイベントを検知し、unzip関数が実行されたことにより、unzipディレクトリが作成された結果です。

unzipディレクトリを参照すると解凍されたファイルが作成されていることが確認できます。

Log Serviceのコンソールから、LogStore 「funccomputer-logstore」を検索しますと、unzip関数コードのログを確認できます。

ログ内容

1 07-04 18:54:27 FC Invoke End RequestId: 5B3C99513996BD008DC202C8
2 07-04 18:54:27 2018-07-04T09:54:27.554Z 5B3C99513996BD008DC202C8 [INFO] index is:3 filename is tg_test/tg_test0003.txt
3 07-04 18:54:27 2018-07-04T09:54:27.553Z 5B3C99513996BD008DC202C8 [INFO] index is:2 filename is tg_test/tg_test0002.txt
4 07-04 18:54:27 2018-07-04T09:54:27.553Z 5B3C99513996BD008DC202C8 [INFO] index is:1 filename is tg_test/tg_test0001.txt
5 07-04 18:54:27 2018-07-04T09:54:27.521Z 5B3C99513996BD008DC202C8 [INFO] obj key:tg_test.zip
6 07-04 18:54:26 FC Invoke Start RequestId: 5B3C99513996BD008DC202C8
7 07-04 18:54:26 FunctionCompute python runtime inited.

おわりに

今回はFunction Computeで「OSSのイベントをトリガーにして自動でコードを実行する」検証のご紹介させて頂きました。シンプルな検証ではございますが、応用として業務アプリケーションなどの仕組みでOSSにデータが保存されたら、関数コードを自動実行して、他のプロダクトへデータを連携させるというようなことも考えられます。 また、Function Computeはサーバーレスでコードを実行することが出来ますので、運用負荷が軽減されるメリットもございます。

今回検証で使用したunzipの関数コードはスクラッチで作成をしておりますが、Function Computeには関数テンプレートが用意されておりますので、ご要件が合いましたら関数テンプレートをそのまま活用するとも可能ですし、参考にしてオリジナルの関数コードとして作成することも可能です。コードは苦手という方も挑戦してみてください!!

この記事をシェアする