2012年12月2日日曜日

Node.jsってなんじゃ?(knox:S3にアクセス)


AWS界隈でもAdvent Calendarが流行っているようで、CloudpackでもAdvent Calendarが始まりました。

cloudpack Advent Calendar 2012

社内でやると、ただのブログの催促のような気もしますが、1日目のsuz-labさんに続いて、2日目を担当します。

最近node.jsを実案件で利用することがいくつかあり、AWSサービスをnodeから利用したいケースが結構あります。そこで今回はnodeからS3へファイルをアップロードしてみたいと思います。

nodeでS3アクセスするには、knoxというモジュールがあります。
他にもs3-clientというknoxをもとにした簡易機能のモジュールがありますが、簡単さと引換にヘッダーを付けられないなどの制限があるので、いろいろやりたい場合はknoxがよいかと思います。

今回は、redisからのpublishをトリガーにしてメッセージ内容をS3へJSONファイルとしてアップロードしてみたいと思います。

まず、S3にはアップロード用のバケットを用意しておきます。
ここではmemocra-jsonというバケットにしました。
内容を確認しやすいように、webサイト設定をしておきます。




そしてEC2側では、既にnode, redis本体はインストールされている前提で、
knox, redisのnodeモジュールを追加でインストールします。
# npm install -g knox
# npm install -g redis


次にコードを書きます。
knox.createClientでアクセスキー、シークレットキーと対象バケットを指定し、クライアントオブジェクトを作成します。
var knox = require('knox');var s3Client = knox.createClient({
    key:'xxxxxxxxxxxxxx',
    secret:'yyyyyyyyyyyyyyyyyyyyyyyyyyyy',
    bucket:'memocra-json'
});


また、redisサーバーのjson_createというチャンネルをsubscribeするようにします。
var redis = require('redis');
var sub = redis.createClient({host:'10.0.0.200', port:6379});
sub.subscribe('json_create');


受信時には、受信内容と日時をjson化して、その文字列をknoxクライアントのputメソッドでS3へアップロードします。
この際、ヘッダーにpublic-readをつけることで、WEBアクセスが可能になります。
sub.on('message', function(channel, message){
    var json = JSON.stringify({msg:message, datetime:(new Date())});
    var s3_path = 'json/'+message+'.json';
    var headers = {'Content-Length': json.length,
                    'Content-Type': 'application/json',
                    'x-amz-acl': 'public-read'};
    var req = s3Client.put(s3_path, headers);
    req.on('response', function(res){
        if(res.statusCode != 200){
            console.log("Error! code="+res.statusCode);
        }
        else{
            console.log("Done!");
        }
    });
    req.on('error', function(err){
        console.log('Error='+err);
    });
    req.end(json);
});


ここまで書けたら、起動します。
$ node sample.js


次にredis-cliを起動し、json_createチャンネルでpublishします。
# redis-cli
redis 127.0.0.1:6379> publish json_create hello
(integer) 1
redis 127.0.0.1:6379> publish json_create konnichiwa
(integer) 1


すると、node側では完了メッセージが2つ表示され、2件の処理が終わったことがわかります。
$ node sample.js
Done!
Done!


バケットを見ると、ちゃんと2つファイルができています。





ブラウザで中身を見てみます。




内容も正しいようです。


もちろんこれ以外にも、ファイルをそのままアップロード、ダウンロード、削除する機能などもあり、
nodeでもS3のファイルを操作することができます。

以上です。