法人営業課でOJT中の鎌田です。近頃アイスブレイクの鉄板は「身近にあるけど気にしたことがないもの」だとおもっています。例えば、弊社は毎年社員旅行に行っていますが、そもそものきっかけはなんだったのだろう、とか。
さて、AWSでよく行う作業のうち面倒なことの一つに、Lambdaの動作確認があります。例えば、S3に操作が行われたことをトリガーにLambdaを起動すると、どのバケットに対して、どんな動作がいつ行われたか、といったイベント情報がLambdaに渡されます。このイベント情報を前提としたアプリケーションの動作確認時には、以下の一連の作業を繰り返し行うこととなります。
1.コードを修正する
2.ライブラリとソースコードをzipファイルにまとめる
3.zipファイルをアップロードする
4.Lambda関数のテストを定義して実行する or 実際にトリガーとなる操作を行う
今回はソースコードに対してイベント情報が渡される動作をローカルで再現することで、この1~4の手順を省力化しました。下記がその動作を再現するコードになります。
コード
var event = { "Records": [ { "awsRegion": "ap-northeast-1", "sequenceNumber": "196800000000000000000374", "partitionKey": "khohohoihoihohoihoihohohohohoh", "eventSource": "aws:s3", "s3":{ "bucket":{ "name":"chicken-bucket", "arn":"bucket-ARN" }, "object":{ "key":"tekito.jpg" } } } ] }; var context = { invokeid: 'invokeid', done: function(err,message){ return; } }; var lambda = require("./index"); lambda.handler(event,context);
上記コードはS3にファイルのputが行われたことをトリガーとしてLambdaファンクションが呼び出され、ソースコードにイベント情報を渡す動作を再現しています。
var eventの部分で、どの種類のイベントか、どんな情報が渡されたかの定義をしています。
これを「driver.js」として保存します。このdriver.jsと同一ディレクトリにテスト対象となるnode.jsのコードを置き(今回はindex.js)、driver.jsを実行すると動作確認ができます。実行方法は、コマンドラインでnode driver.jsと入力してください。
※node.jsをインストールしている必要があるのでご注意ください。
ちなみに今回テスト対象としたコードは以下です。おためしになる際には、「index.js」と名前をつけてdriver.jsと同じディレクトリに保存してください。これを実行するとtekito.jpgという名前のテキストファイルが生成されます。テキトーですね。
const aws = require('aws-sdk'); const s3 = new aws.S3(); const exec = require('child_process').exec; const fs = require('fs'); exports.handler = function(event, context) { //downloadしてファイルを書き込む var bucket = event.Records[0].s3.bucket.name; var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' ')); var params = { Bucket: bucket, Key: key, }; s3.getObject(params, (err, data) => { if (err) { console.log(err); const message = `Error getting object ${key} rom bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`; console.log(message); callback(message); } else { fs.writeFile('/tmp/' + key, key, function (err) { if (err) { console.log('error occured when writing file:' +err); } } ); }});
上記コードは基本的にはAWS公式のコードを引用しています。「export.handler」がdriver.jsによって呼び出される部分となります。
event以下は配列や辞書がネストしていて、例えばバケット名を取得するためには
var bucket = event.Records[0].s3.bucket.name;
と書きます。AWSのドキュメントにS3イベント通知の構造が載っていますので是非ご参照ください。
http://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/notification-content-structure.html
s3.getObjectにてdriver.jsが渡してきたパラメーターを読み込んでいます。このコードではもしも正常にダウンロードができなかった場合、渡されたkey名でテキストファイルを作成し保存します。
まとめ
今回はS3のイベント通知をローカルで再現しました。kinesisなど他のサービスに置き換えて利用することも可能です。都度デプロイを行い、実際にイベントを起こす、という動作確認作業を行っていた場合は、これを使うととても楽ができるようになります。ぜひおためしください。
参考にした記事:
http://qiita.com/imaifactory/items/092e32b4fc0f69a94061