Skip to content
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

aws-serverless-expressでlambda化 #102

Merged
merged 4 commits into from
Aug 18, 2018
Merged
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,9 @@ npm-debug.log
yarn-error.log
*.dev.js
.node-version
api-gateway-event.json
ase/*
cloudformation.yaml
packaged-sam.yaml
simple-proxy-api.yaml
scripts/*
146 changes: 101 additions & 45 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,86 +1,123 @@
const express = require('express');
const sanitize = require('validator');
const request = require ('request');
'use strict'
const express = require('express')
const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')
const sanitize = require('validator')
const request = require ('request')
const compression = require('compression')
const manifest = require('./manifest.json')
const redis = require('then-redis')
const kvs = redis.createClient(process.env.REDIS_URL)
const bodyParser = require('body-parser')
let app = express();
let server = require('http').createServer(app);

// server configure
app.set('port', (process.env.PORT || 5000));
app.set('view engine', 'jade');
app.set('views', __dirname + '/views');
app.set('views', 'views');

app.use(compression({level: 6}));
app.use(express.static(__dirname + '/public'));

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.use(function (req, res, next) {
if (process.env.NODE_ENV === 'production') {
if (req.headers['x-forwarded-proto'] !== 'https') {
return res.redirect('https://' + req.headers.host + req.url)
} else if (req.headers.host === 'lgtm-hub.herokuapp.com') {
return res.redirect('https://' + process.env.SERVER_ADDRESS + req.url)
} else {
return next()
}
} else {
return next()
const AWS = require('aws-sdk')
const dynamoConfig =
process.env.NODE_ENV === 'development' ? {
region: 'ap-northeast-1',
endpoint: "http://dynamodb:8000"
} : {
region: 'ap-northeast-1'
}
})
const dynamo = new AWS.DynamoDB.DocumentClient(dynamoConfig)

let env = process.env.NODE_ENV || 'development';
if ('development' == env) {
}
// app.use(function (req, res, next) {
// if (process.env.NODE_ENV === 'production') {
// if (req.headers['x-forwarded-proto'] !== 'https') {
// return res.redirect('https://' + req.headers.host + req.url)
// } else if (req.headers.host === 'lgtm-hub.herokuapp.com') {
// return res.redirect('https://' + process.env.SERVER_ADDRESS + req.url)
// } else {
// return next()
// }
// } else {
// return next()
// }
// })

// server listen
server.listen(app.get('port'), function () {
console.log('Server listening at port %d', app.get('port'));
});
let env = process.env.NODE_ENV
if (env === 'development') {
const server = require('http').createServer(app);
app.set('port', (process.env.PORT || 5000));
// server listen
server.listen(app.get('port'), function () {
console.log('Server listening at port %d', app.get('port'))
})
} else {
app.use(awsServerlessExpressMiddleware.eventContext())
}

const jsPath = {
vendor: `/js/dist${manifest['vendors~index.js']}`,
index: `/js/dist${manifest['index.js']}`
}

// route
app.get('/', function (req, res) {
app.get('/', (req, res) => {
res.render('index', { production: env === 'production', jsPath })
})

app.get('/js/index', (req, res) => {
res.sendFile(`${__dirname}/public${jsPath.index}`)
})

app.get('/js/vendor', (req, res) => {
res.sendFile(`${__dirname}/public/${jsPath.vendor}`)
})

app.get('/img/favicon', (req, res) => {
res.sendFile(`${__dirname}/public/img/favicon.ico`)
})

app.get('/css/style', (req, res) => {
res.sendFile(`${__dirname}/public/css/style.css`)
})

const redisKey = 'history'
app.get('/recommend', async function (req, res) {
const recommend = await kvs.lrange(redisKey, 0, -1) || []
const history = await getHistory()
res.header('Content-Type', 'application/json; charset=utf-8')
res.end(JSON.stringify(recommend))
res.send(JSON.stringify(history))
})
app.get('/random', function (req, res) {
app.get('/random', async function (req, res) {
let tasks = [
getJsonLgtmin(),
getJsonLgtmin(),
getJsonLgtmin(),
]
Promise.all(tasks).then(function(results) {
res.header('Content-Type', 'application/json; charset=utf-8')
res.end(JSON.stringify(results))
})
const results = await Promise.all(tasks)
res.header('Content-Type', 'application/json; charset=utf-8')
res.send(JSON.stringify(results))
})
app.post('/select', async function (req, res) {
const imgUrl = req.body.img

const recommend = await kvs.lrange(redisKey, 0, -1) || []
const recommend = await getHistory()
if (checkDataImg(imgUrl, recommend)) {
const filteredImgUrl = sanitize.toString(imgUrl)
await kvs.rpush(redisKey, filteredImgUrl)
if ((await kvs.llen(redisKey)) > 24) {
await kvs.lpop(redisKey)
const newHistory = recommend.concat([filteredImgUrl]).slice(-24)
const params = {
TableName: 'lgtm',
Key: {
id: 1,
},
ExpressionAttributeValues: {
':newHistory': newHistory,
},
ExpressionAttributeNames: {
'#n': 'history',
},
UpdateExpression: 'SET #n = :newHistory'
}
await kvs.expireat(redisKey, parseInt((new Date) / 1000, 10) + 60 * 60 * 24 * 10) // 10日キャッシュ
await new Promise ((resolve, reject) => {
dynamo.update(params, function(err, data) {})
})
}
res.header('Content-Type', 'application/json; charset=utf-8')
res.end()
Expand All @@ -98,16 +135,33 @@ function getJsonLgtmin() {
headers: {
"accept": "application/json, */*",
"accept-encoding": "gzip, deflate",
"user-agent": "runscope/0.1",
"connection": "keep-alive"
}
// "user-agent": "runscope/0.1",
// "connection": "keep-alive"
},
timeout: 300000,
}
, function (error, response, body) {
resolve(JSON.parse(body));
resolve(JSON.parse(body));
});
});
}

function getHistory () {
const params = {
TableName: 'lgtm',
Key: {
id: 1,
}
}
return new Promise ((resolve, reject) => {
dynamo.get(params, function(err, data) {
console.log(data)
console.log(err)
resolve(data.Item.history)
})
})
}

// sanitizing
function checkDataImg (img, recommend) {
if (img.match(/"/) !== null || img.match(/'/) !== null) {
Expand All @@ -125,3 +179,5 @@ function checkDataImg (img, recommend) {

return true;
}

module.exports = app
10 changes: 5 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ services:
ports:
- 5000:5000
depends_on:
- redis
- dynamodb
links:
- redis:redis
- dynamodb:dynamodb

builder:
image: node:9.11.1
Expand All @@ -23,7 +23,7 @@ services:
- /app/node_modules
working_dir: /app

redis:
image: redis:3.2.11-alpine
dynamodb:
image: deangiberson/aws-dynamodb-local
ports:
- 16379:6379
- 8000:8000
25 changes: 23 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,26 @@
"scripts": {
"build": "webpack --mode production",
"watch": "webpack -w --mode development",
"start": "pm2-runtime app.json --env production",
"dev": "pm2-runtime app.json --watch"
"start": "NODE_ENV=production node app.js",
"dev": "pm2-runtime app.json --watch",
"config": "node ./scripts/configure.js",
"deconfig": "node ./scripts/deconfigure.js",
"local": "node scripts/local",
"invoke-lambda": "aws lambda invoke --function-name $npm_package_config_functionName --region $npm_package_config_region --payload file://api-gateway-event.json lambda-invoke-response.json && cat lambda-invoke-response.json",
"create-bucket": "aws s3 mb s3://$npm_package_config_s3BucketName --region $npm_package_config_region",
"delete-bucket": "aws s3 rb s3://$npm_package_config_s3BucketName --region $npm_package_config_region",
"package": "aws cloudformation package --template ./cloudformation.yaml --s3-bucket $npm_package_config_s3BucketName --output-template packaged-sam.yaml --region $npm_package_config_region",
"deploy": "aws cloudformation deploy --template-file packaged-sam.yaml --stack-name $npm_package_config_cloudFormationStackName --capabilities CAPABILITY_IAM --region $npm_package_config_region",
"package-deploy": "npm run package && npm run deploy",
"delete-stack": "aws cloudformation delete-stack --stack-name $npm_package_config_cloudFormationStackName --region $npm_package_config_region",
"setup": "npm install && (aws s3api get-bucket-location --bucket $npm_package_config_s3BucketName --region $npm_package_config_region || npm run create-bucket) && npm run package-deploy"
},
"config": {
"s3BucketName": "YOUR_S3BUCKET_NAME",
"region": "YOUR_REGION",
"cloudFormationStackName": "YOUR_STACK_NAME",
"functionName": "YOUR_FUNCTION_NAME",
"accountId": "YOUR_ACCOUNT_NAME"
},
"repository": "git@github.com:do7be/lgtm-hub.git",
"author": "do7be",
Expand All @@ -20,6 +38,9 @@
},
"dependencies": {
"@babel/runtime": "^7.0.0-beta.49",
"acorn-globals": "^4.1.0",
"aws-sdk": "^2.286.2",
"aws-serverless-express": "^3.2.0",
"classnames": "^2.2.5",
"clipboard": "^2.0.0",
"compression": "^1.6.1",
Expand Down
8 changes: 4 additions & 4 deletions views/index.jade
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ html
meta(property="og:url" content="https://lgtm-hub.do7be.com/")
meta(property="og:image" content="http://i.imgur.com/4gU76Y6.jpg")
title LGTM-HUB
link(rel="shortcut icon", href="/img/favicon.ico")
link(rel='stylesheet', href='/css/style.css')
link(rel="shortcut icon", href="/img/favicon")
link(rel='stylesheet', href='/css/style')

body
div#app

script(src="#{jsPath.vendor}")
script(src="#{jsPath.index}")
script(src="/js/vendor")
script(src="/js/index")
Loading