1. inukai-norio
Changes in body
Source | HTML | Preview

はじめに

yaml が S3 に置かれた時それをトリガにSQSにエンキューする必要がありました。
一般的には、S3 Event Notificasions によりエンキューをすれば良いのですが、エンキュー先が複数に必要になりました。

用途別で分けるだけなら、S3のプレフィックスで制御することもできますが、時間帯により分ける必要があったので、lambda を使って実装しました。

エンキュー先

  1. 夜間用SQS(process.env.sqsUriNight)
  2. 昼の低速処理用SQS(process.env.sqsUriNormal)
  3. 昼の高速処理用SQS(process.env.sqsUriFast)

使ったコード

低速高速の分岐はコードを見ての通り、 yaml 内にある photos の数により判断します。
同様のソースを書く場合の参考にしてください。

index.js(node8)
'use strict';

const aws = require('aws-sdk');
const yaml = require('yaml');
require('date-utils');

const s3 = new aws.S3({apiVersion: '2006-03-01'});
const sqs = new aws.SQS({apiVersion: '2012-11-05'});
let sqsUriNormal = process.env.sqsUriNormal;
let sqsUriFast = process.env.sqsUriFast;
let sqsUriNight = process.env.sqsUriNight;
let threshold = process.env.threshold;
let nightStart = process.env.nightStart;
let nightEnd = process.env.nightEnd;

let enqueueSQS = (uri, key) => {
  let params = {
    MessageBody: key,
    QueueUrl: uri,
  };

  return sqs.sendMessage(params).promise();
};

let getYaml = (bucket, key) => {
  let yamlParam = {
    Bucket: bucket,
    Key: key,
  };

  return s3.getObject(yamlParam).promise();
};

let isNight = () => {
  let now = Number(new Date().toFormat('HH24MISS'));
  return nightStart <= now && now < nightEnd;
};

let parseYaml = (data) => yaml.parse(data.Body.toString());

let getPutSqs = (data) => {
  if (isNight()) {
    return sqsUriNight;
  }
  if (data.photos.length > threshold) {
    return sqsUriNormal;
  }
  return sqsUriFast;
};

let retmsg = (msg) => {
  console.log(msg);
  return msg;
};

exports.handler = async (event, context) => {
  let bucket = event.Records[0].s3.bucket.name;
  let key = decodeURIComponent(event.Records[0].s3.object.key);

  try {
    let sqsName = getPutSqs(parseYaml(await getYaml(bucket, key)));
    let ret = await enqueueSQS(sqsName, key);
    return retmsg(ret);
  } catch (err) {
    throw new Error(retmsg(err));
  }
};

index.js(node8)
'use strict';

const aws = require('aws-sdk');
const yaml = require('yaml');
require('date-utils');

const s3 = new aws.S3({apiVersion: '2006-03-01'});
const sqs = new aws.SQS({apiVersion: '2012-11-05'});
let sqsUriNormal = process.env.sqsUriNormal;
let sqsUriFast = process.env.sqsUriFast;
let sqsUriNight = process.env.sqsUriNight;
let threshold = process.env.threshold;
let nightStart = process.env.nightStart;
let nightEnd = process.env.nightEnd;

let enqueueSQS = (uri, key) => {
  let params = {
    MessageBody: key,
    QueueUrl: uri,
  };

  return sqs.sendMessage(params).promise();
};

let getYaml = (bucket, key) => {
  let yamlParam = {
    Bucket: bucket,
    Key: key,
  };

  return s3.getObject(yamlParam).promise();
};

let isNight = () => {
  let now = Number(new Date().toFormat('HH24MISS'));
  return nightStart <= now && now < nightEnd;
};

let parseYaml = (data) => yaml.parse(data.Body.toString());

let getPutSqs = (data) => {
  if (isNight()) {
    return sqsUriNight;
  }
  if (data.photos.length > threshold) {
    return sqsUriNormal;
  }
  return sqsUriFast;
};

exports.handler = async (event, context) => {
  let bucket = event.Records[0].s3.bucket.name;
  let key = decodeURIComponent(event.Records[0].s3.object.key);
  try {
  let sqsName = getPutSqs(parseYaml(await getYaml(bucket, key)));
  let ret = await enqueueSQS(sqsName, key);
  console.log(msg);
  return msg;
};