Skip to content

Async awaitify code #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 24 additions & 26 deletions functions/accept-order.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
'use strict';
const kinesis = require('../lib/kinesis')
const log = require('../lib/log')
const correlationIds = require('../lib/correlation-ids')
const cloudwatch = require('../lib/cloudwatch')
const wrapper = require('../middleware/wrapper')

const co = require('co');
const kinesis = require('../lib/kinesis');
const log = require('../lib/log');
const cloudwatch = require('../lib/cloudwatch');
const wrapper = require('../middleware/wrapper');
const streamName = process.env.order_events_stream

const streamName = process.env.order_events_stream;
const handler = async (event, context) => {
let req = JSON.parse(event.body)
log.debug(`request body is valid JSON`, { requestBody: event.body })

const handler = co.wrap(function* (event, context, cb) {
let req = JSON.parse(event.body);
log.debug(`request body is valid JSON`, { requestBody: event.body });
let restaurantName = req.restaurantName
let orderId = req.orderId
let userEmail = req.userEmail

let restaurantName = req.restaurantName;
let orderId = req.orderId;
let userEmail = req.userEmail;
correlationIds.set('order-id', orderId)
correlationIds.set('restaurant-name', restaurantName)
correlationIds.set('user-email', userEmail)

correlationIds.set('order-id', orderId);
correlationIds.set('restaurant-name', restaurantName);
correlationIds.set('user-email', userEmail);

log.debug('restaurant accepted order', { orderId, restaurantName, userEmail });
log.debug('restaurant accepted order', { orderId, restaurantName, userEmail })

let data = {
orderId,
Expand All @@ -33,21 +31,21 @@ const handler = co.wrap(function* (event, context, cb) {
Data: JSON.stringify(data), // the SDK would base64 encode this for us
PartitionKey: orderId,
StreamName: streamName
};
}

yield cloudwatch.trackExecTime(
"KinesisPutRecordLatency",
await cloudwatch.trackExecTime(
'KinesisPutRecordLatency',
() => kinesis.putRecord(kinesisReq).promise()
);
)

log.debug(`published event into Kinesis`, { eventName: 'order_accepted' });
log.debug(`published event into Kinesis`, { eventName: 'order_accepted' })

let response = {
statusCode: 200,
body: JSON.stringify({ orderId })
}

cb(null, response);
});
return response
}

module.exports.handler = wrapper(handler);
module.exports.handler = wrapper(handler)
113 changes: 55 additions & 58 deletions functions/create-alarms.js
Original file line number Diff line number Diff line change
@@ -1,101 +1,98 @@
'use strict';
const _ = require('lodash')
const AWS = require('aws-sdk')
const apigateway = new AWS.APIGateway()
const cloudwatch = new AWS.CloudWatch()
const log = require('../lib/log')

const _ = require('lodash');
const co = require('co');
const AWS = require('aws-sdk');
const apigateway = new AWS.APIGateway();
const cloudwatch = new AWS.CloudWatch();
const log = require('../lib/log');
const alarmActions = (process.env.alarm_actions || '').split(',')
const okAction = (process.env.ok_actions || '').split(',')

const alarmActions = (process.env.alarm_actions || '').split(',');
const okAction = (process.env.ok_actions || '').split(',');
async function enableDetailedMetrics(restApiId, stageName) {
let getResp = await apigateway.getStage({ restApiId, stageName }).promise()
log.debug('get stage settings', getResp.methodSettings)

let enableDetailedMetrics = co.wrap(function* (restApiId, stageName) {
let getResp = yield apigateway.getStage({ restApiId, stageName }).promise();
log.debug('get stage settings', getResp.methodSettings);

let isDetailedMetricsEnabled = _.get(getResp, 'methodSettings.*/*.metricsEnabled', false);
let isDetailedMetricsEnabled = _.get(getResp, 'methodSettings.*/*.metricsEnabled', false)
if (isDetailedMetricsEnabled) {
log.debug('detailed metrics already enabled', { restApiId, stageName });
log.debug('detailed metrics already enabled', { restApiId, stageName })
} else {
let updateReq = {
restApiId,
stageName,
patchOperations: [
{
path: "/*/*/metrics/enabled",
value: "true",
op: "replace"
path: '/*/*/metrics/enabled',
value: 'true',
op: 'replace'
}
]
};
yield apigateway.updateStage(updateReq).promise();
log.debug('enabled detailed metrics', { restApiId, stageName });
}
await apigateway.updateStage(updateReq).promise()
log.debug('enabled detailed metrics', { restApiId, stageName })
}
});
}

let getRestEndpoints = co.wrap(function* (restApiId) {
let resp = yield apigateway.getResources({ restApiId }).promise();
log.debug('got REST resources', { restApiId });
async function getRestEndpoints(restApiId) {
let resp = await apigateway.getResources({ restApiId }).promise()
log.debug('got REST resources', { restApiId })

let resourceMethods = resp.items.map(x => {
let methods = _.keys(x.resourceMethods);
return methods.map(method => ({ resource: x.path, method }));
});
let methods = _.keys(x.resourceMethods)
return methods.map(method => ({ resource: x.path, method }))
})

return _.flattenDeep(resourceMethods);
});
return _.flattenDeep(resourceMethods)
}

let getRestApiName = co.wrap(function* (restApiId) {
let resp = yield apigateway.getRestApi({ restApiId }).promise();
log.debug('got REST api', { restApiId });
async function getRestApiName(restApiId) {
let resp = await apigateway.getRestApi({ restApiId }).promise()
log.debug('got REST api', { restApiId })

return resp.name;
});
return resp.name
}

let createAlarmsForEndpoints = co.wrap(function* (restApiId, stageName) {
let apiName = yield getRestApiName(restApiId);
log.debug(`API name is ${apiName}`, { restApiId, stageName });
async function createAlarmsForEndpoints(restApiId, stageName) {
let apiName = await getRestApiName(restApiId)
log.debug(`API name is ${apiName}`, { restApiId, stageName })

let restEndpoints = yield getRestEndpoints(restApiId);
log.debug('got REST endpoints', { restApiId, stageName, restEndpoints });
let restEndpoints = await getRestEndpoints(restApiId)
log.debug('got REST endpoints', { restApiId, stageName, restEndpoints })

for (let endpoint of restEndpoints) {
let putReq = {
AlarmName: `API [${apiName}] stage [${stageName}] ${endpoint.method} ${endpoint.resource} : p99 > 1s`,
MetricName: 'Latency',
Dimensions: [
{ Name: 'ApiName', Value: apiName },
{ Name: 'ApiName', Value: apiName },
{ Name: 'Resource', Value: endpoint.resource },
{ Name: 'Method', Value: endpoint.method },
{ Name: 'Stage', Value: stageName }
{ Name: 'Method', Value: endpoint.method },
{ Name: 'Stage', Value: stageName }
],
Namespace: 'AWS/ApiGateway',
Threshold: 1000, // 1s
ComparisonOperator: 'GreaterThanThreshold',
Period: 60, // per min
EvaluationPeriods: 5,
Threshold: 1000, // 1s
ComparisonOperator: 'GreaterThanThreshold',
Period: 60, // per min
EvaluationPeriods: 5,
DatapointsToAlarm: 5, // 5 consecutive mins to trigger alarm
ExtendedStatistic: 'p99',
ActionsEnabled: true,
AlarmActions: alarmActions,
AlarmDescription: `auto-generated by Lambda [${process.env.AWS_LAMBDA_FUNCTION_NAME}]`,
OKActions: okAction,
Unit: 'Milliseconds'
};
yield cloudwatch.putMetricAlarm(putReq).promise();
}
await cloudwatch.putMetricAlarm(putReq).promise()
}

log.debug('auto-created latency ALARMS for REST endpoints', { restApiId, stageName, restEndpoints });
});
log.debug('auto-created latency ALARMS for REST endpoints', { restApiId, stageName, restEndpoints })
}

module.exports.handler = co.wrap(function* (event, context, cb) {
let restApiId = event.detail.requestParameters.restApiId;
let stageName = event.detail.requestParameters.createDeploymentInput.stageName;
module.exports.handler = async (event, context, cb) => {
let restApiId = event.detail.requestParameters.restApiId
let stageName = event.detail.requestParameters.createDeploymentInput.stageName

yield enableDetailedMetrics(restApiId, stageName);
await enableDetailedMetrics(restApiId, stageName)

yield createAlarmsForEndpoints(restApiId, stageName);
await createAlarmsForEndpoints(restApiId, stageName)

cb(null, 'ok');
});
return 'ok'
}
50 changes: 24 additions & 26 deletions functions/fulfill-order.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
'use strict';
const kinesis = require('../lib/kinesis')
const log = require('../lib/log')
const correlationIds = require('../lib/correlation-ids')
const cloudwatch = require('../lib/cloudwatch')
const wrapper = require('../middleware/wrapper')

const co = require('co');
const kinesis = require('../lib/kinesis');
const log = require('../lib/log');
const cloudwatch = require('../lib/cloudwatch');
const wrapper = require('../middleware/wrapper');
const streamName = process.env.order_events_stream

const streamName = process.env.order_events_stream;
const handler = async (event, context, cb) => {
let body = JSON.parse(event.body)
log.debug(`request body is valid JSON`, { requestBody: event.body })

const handler = co.wrap(function* (event, context, cb) {
let body = JSON.parse(event.body);
log.debug(`request body is valid JSON`, { requestBody: event.body });
let restaurantName = body.restaurantName
let orderId = body.orderId
let userEmail = body.userEmail

let restaurantName = body.restaurantName;
let orderId = body.orderId;
let userEmail = body.userEmail;
correlationIds.set('order-id', orderId)
correlationIds.set('restaurant-name', restaurantName)
correlationIds.set('user-email', userEmail)

correlationIds.set('order-id', orderId);
correlationIds.set('restaurant-name', restaurantName);
correlationIds.set('user-email', userEmail);

log.debug('restaurant has fulfilled order', { orderId, restaurantName, userEmail });
log.debug('restaurant has fulfilled order', { orderId, restaurantName, userEmail })

let data = {
orderId,
Expand All @@ -33,21 +31,21 @@ const handler = co.wrap(function* (event, context, cb) {
Data: JSON.stringify(data), // the SDK would base64 encode this for us
PartitionKey: orderId,
StreamName: streamName
};
}

yield cloudwatch.trackExecTime(
"KinesisPutRecordLatency",
await cloudwatch.trackExecTime(
'KinesisPutRecordLatency',
() => kinesis.putRecord(kinesisReq).promise()
);
)

log.debug(`published event into Kinesis`, { eventName: 'order_fulfilled' });
log.debug(`published event into Kinesis`, { eventName: 'order_fulfilled' })

let response = {
statusCode: 200,
body: JSON.stringify({ orderId })
}

cb(null, response);
});
return response
}

module.exports.handler = wrapper(handler);
module.exports.handler = wrapper(handler)
Loading