Skip to content

Instantly share code, notes, and snippets.

@bjclark13
Created June 6, 2019 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjclark13/d418e8f4a2b4830b209521b539875a90 to your computer and use it in GitHub Desktop.
Save bjclark13/d418e8f4a2b4830b209521b539875a90 to your computer and use it in GitHub Desktop.
'use strict';
// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set the region
AWS.config.update({region: 'us-east-1'});
// Create the DynamoDB service object
var db = new AWS.DynamoDB({apiVersion: '2012-08-10'});
var docClient = new AWS.DynamoDB.DocumentClient();
async function getFeatures() {
// Would call database, returning random, hardcoded features for now...
let features = await getAllFeatures();
let toggledFeatures = {};
features.forEach( (feature) => {
if ( feature.type === 'ab' ) {
toggledFeatures[feature.name] = setABToggle(feature.percentage);
} else if ( feature.type === 'toggle') {
toggledFeatures[feature.name] = feature.toggle;
}
})
return toggledFeatures;
}
function setABToggle(percentage) {
let random = Math.floor(Math.random() * 100);
let isVisible = random < percentage;
return isVisible;
}
function getAllFeatures() {
return new Promise( (resolve, reject) => {
var params = {
TableName: process.env.FEATURES_TABLE
};
docClient.scan(params, function(err, data) {
if (err) {
console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
reject(err);
} else {
console.log("Scan succeeded.");
resolve(data.Items);
}
});
})
}
/**
* Convert feature item into a valid dynamoDB param
*
* @todo return validation errors
* @param {Object} item
* @return {Object} dynamoDbParam
*/
function validateItem(item) {
let dynamoDbParam = { name: { S: item.name } };
if ( item.type ) {
dynamoDbParam.type = { S: item.type };
}
// Must be type of number
if ( typeof item.percentage === 'number' ) {
dynamoDbParam.percentage = { N: item.percentage.toString() };
}
// Convert to 0 or 1
if ( typeof item.toggle !== 'undefined' ) {
dynamoDbParam.toggle = { N: item.toggle ? '1' : '0' };
}
return dynamoDbParam;
}
/**
* Create or update a feature
* @param {Object} feature
* @todo Add validation
* @return Success
*/
function addFeature(feature) {
return new Promise((resolve,reject) => {
var params = {
TableName: process.env.FEATURES_TABLE,
Item: validateItem(feature)
};
// Call DynamoDB to add the item to the table
db.putItem(params, function(err, data) {
if (err) {
console.log("Error in addFeature", err);
reject(err);
} else {
console.log("Success in addFeature", data);
resolve(data);
}
});
});
}
async function featuresPost(event, context) {
if (!event.body) {
return {
statusCode: 400,
headers:{'Access-Control-Allow-Origin': '*'},
body: "No data provided"
}
} else {
let feature = JSON.parse(event.body);
if (!feature.name ) {
return {
statusCode: 400,
headers:{'Access-Control-Allow-Origin': '*'},
body: "No feature name provided"
}
} else {
console.log('adding/updating devotional');
try {
await addFeature(feature);
// We did it!
return {
statusCode: 200,
headers:{'Access-Control-Allow-Origin': '*'},
body: JSON.stringify({
message: 'Success!',
updated: [] // TODO, include what external source has been updated
})
};
} catch(err) {
console.log('hit error', err);
return {
statusCode: 500,
headers:{'Access-Control-Allow-Origin': '*'},
body: JSON.stringify(err)
}
}
}
}
// Use this code if you don't use the http event with the LAMBDA-PROXY integration
// return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
}
async function features(event) {
let features = await getFeatures(event);
return {
statusCode: 200,
headers:{'Access-Control-Allow-Origin': '*'} ,
body: JSON.stringify(features, null, 2),
};
// Use this code if you don't use the http event with the LAMBDA-PROXY integration
// return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};
function deleteFeatureItem(name) {
return new Promise( function(resolve,reject) {
var params = {
TableName: process.env.FEATURES_TABLE,
Key:{
"name": name,
},
};
docClient.delete(params, function(err, data) {
if (err) {
reject(err)
console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
} else {
resolve('Success');
console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
}
});
})
}
async function deleteFeature(event) {
let name = event.queryStringParameters.name;
try {
let message = await deleteFeatureItem(name);
console.log('success!!!!');
return {
statusCode: 200,
headers:{'Access-Control-Allow-Origin': '*'} ,
body: JSON.stringify({ message: 'Deleted.' }),
};
} catch (e) {
return {
statusCode: 500,
headers:{'Access-Control-Allow-Origin': '*'} ,
body: JSON.stringify({ message: 'Failed deleting.' }),
}
}
}
async function allFeatures(event) {
let features = await getAllFeatures(event);
return {
statusCode: 200,
headers:{'Access-Control-Allow-Origin': '*'} ,
body: JSON.stringify(features, null, 2),
};
// Use this code if you don't use the http event with the LAMBDA-PROXY integration
// return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};
module.exports = {
features,
getAllFeatures,
getFeatures,
setABToggle,
addFeature,
featuresPost,
allFeatures,
deleteFeature
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment