From fe0dc3e66e40527ec8a5e355b4652089826bdb6d Mon Sep 17 00:00:00 2001 From: Tomas Date: Thu, 28 Sep 2017 15:26:45 -0400 Subject: [PATCH 01/28] v3.0.3 open for development --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5e8f76..c7481fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,3 +23,5 @@ API Server for CogniCity * Card IDs generated as UUID by Postgres * Added schema version to / endpoint * Image upload changed to use AWS S3 signed links + +### v3.0.3 diff --git a/package.json b/package.json index 5c39c0c..633402f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cognicity-server", - "version": "3.0.2", + "version": "3.0.3", "description": "Data Server for CogniCity", "main": "dist", "engines": { From 7371ad848c6fe99d7b5a823b2ea692c2e7da403f Mon Sep 17 00:00:00 2001 From: abrahamq Date: Sat, 14 Oct 2017 18:55:09 -0400 Subject: [PATCH 02/28] deploy all build artifacts to s3 --- .travis.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1107b00..cded660 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ branches: only: - master - dev + - jsdocsToS3 - server-object-refactor - report-archive @@ -25,3 +26,14 @@ install: - npm install after_success: npm run coverage + +deploy: #build the docs for dev branch only? + provider: s3 + bucket: dev-cognicity-server-docs + access_key_id: $AWS_S3_ACCESS_KEY_ID + secret_access_key: $AWS_S3_SECRET_ACCESS_KEY + region: "us-east-1" + skip_cleanup: true + on: + branch: dev + From 192e3b3c70b28aeaf848c129ad6d4cc37812f7de Mon Sep 17 00:00:00 2001 From: abrahamq Date: Sat, 14 Oct 2017 19:21:13 -0400 Subject: [PATCH 03/28] change deploy branch for testing --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cded660..7c0f989 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,5 +35,4 @@ deploy: #build the docs for dev branch only? region: "us-east-1" skip_cleanup: true on: - branch: dev - + branch: jsdocsToS3 From 5f27817d069665a670181e2cc103c680384bc40d Mon Sep 17 00:00:00 2001 From: abrahamq Date: Sat, 14 Oct 2017 19:30:30 -0400 Subject: [PATCH 04/28] bucket name needs to be quoted --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4c28974..fa1aa68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,10 +33,10 @@ after_success: npm run coverage deploy: #build the docs for dev branch only? provider: s3 - bucket: dev-cognicity-server-docs + bucket: "dev-cognicity-server-docs" + region: "us-east-1" access_key_id: $AWS_S3_ACCESS_KEY_ID secret_access_key: $AWS_S3_SECRET_ACCESS_KEY - region: "us-east-1" skip_cleanup: true on: branch: jsdocsToS3 From 894d1ad11a953f58802f3e05b22085285c704df4 Mon Sep 17 00:00:00 2001 From: abrahamq Date: Sat, 14 Oct 2017 19:31:55 -0400 Subject: [PATCH 05/28] remove testing for faster deployment of docs (temporarily) --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fa1aa68..d0cdf37 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,12 +24,12 @@ branches: before_install: - npm i -g npm@5.0.3 - if [[ $TRAVIS_BRANCH != 'master' ]]; then BRANCH='dev'; else BRANCH='master'; fi; - - export PGDATABASE=cognicity_server_testing ; git clone -b $BRANCH https://github.com/urbanriskmap/cognicity-schema.git urbanriskmap/cognicity-schema && cd urbanriskmap/cognicity-schema && bash build/run.sh && cd - + # - export PGDATABASE=cognicity_server_testing ; git clone -b $BRANCH https://github.com/urbanriskmap/cognicity-schema.git urbanriskmap/cognicity-schema && cd urbanriskmap/cognicity-schema && bash build/run.sh && cd - install: - npm install -after_success: npm run coverage +after_success: npm run coverage && npm run jsdocs deploy: #build the docs for dev branch only? provider: s3 From 27e69eead272cd22acc10b4702e2cb52724872b4 Mon Sep 17 00:00:00 2001 From: abrahamq Date: Sat, 14 Oct 2017 19:35:52 -0400 Subject: [PATCH 06/28] nvm too hard to turn off tests :) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d0cdf37..24c9c23 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ branches: before_install: - npm i -g npm@5.0.3 - if [[ $TRAVIS_BRANCH != 'master' ]]; then BRANCH='dev'; else BRANCH='master'; fi; - # - export PGDATABASE=cognicity_server_testing ; git clone -b $BRANCH https://github.com/urbanriskmap/cognicity-schema.git urbanriskmap/cognicity-schema && cd urbanriskmap/cognicity-schema && bash build/run.sh && cd - + - export PGDATABASE=cognicity_server_testing ; git clone -b $BRANCH https://github.com/urbanriskmap/cognicity-schema.git urbanriskmap/cognicity-schema && cd urbanriskmap/cognicity-schema && bash build/run.sh && cd - install: - npm install From 76d123bce5995e7abd8d08471a18a6f9b3212491 Mon Sep 17 00:00:00 2001 From: abrahamq Date: Sat, 14 Oct 2017 20:43:12 -0400 Subject: [PATCH 07/28] only upload jsdocs --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 24c9c23..c506701 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,6 +31,9 @@ install: after_success: npm run coverage && npm run jsdocs +before_deploy: + - cd jsdoc + deploy: #build the docs for dev branch only? provider: s3 bucket: "dev-cognicity-server-docs" From 2e8ec6c0b77fdef54c0de8faaa5f310f43364c0c Mon Sep 17 00:00:00 2001 From: abrahamq Date: Sat, 14 Oct 2017 21:04:52 -0400 Subject: [PATCH 08/28] typo --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c506701..3a62ab9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,10 +29,10 @@ before_install: install: - npm install -after_success: npm run coverage && npm run jsdocs +after_success: npm run coverage before_deploy: - - cd jsdoc + - npm run jsdoc && cd jsdoc deploy: #build the docs for dev branch only? provider: s3 From bac8ba6047ed2817e2dba7acae61e4b9094b3f43 Mon Sep 17 00:00:00 2001 From: abrahamq Date: Tue, 17 Oct 2017 12:41:37 -0400 Subject: [PATCH 09/28] changed to build dev branch --- .travis.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a62ab9..0600126 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,6 @@ branches: only: - master - dev - - jsdocsToS3 - server-object-refactor - report-archive @@ -34,7 +33,7 @@ after_success: npm run coverage before_deploy: - npm run jsdoc && cd jsdoc -deploy: #build the docs for dev branch only? +deploy: #build the docs for dev branch only provider: s3 bucket: "dev-cognicity-server-docs" region: "us-east-1" @@ -42,4 +41,4 @@ deploy: #build the docs for dev branch only? secret_access_key: $AWS_S3_SECRET_ACCESS_KEY skip_cleanup: true on: - branch: jsdocsToS3 + branch: dev From 9e1e88d4f7fe376353c0ad25be9885f6f0eef395 Mon Sep 17 00:00:00 2001 From: Matthew Berryman Date: Wed, 1 Nov 2017 18:23:00 +1100 Subject: [PATCH 10/28] use auth0 issuer in jwt check --- src/lib/util.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/util.js b/src/lib/util.js index 1c61b0a..6c44e7e 100755 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -25,6 +25,7 @@ const cacheResponse = (duration) => cache(duration, config.CACHE); const jwtCheck = jwt({ secret: new Buffer(config.AUTH0_SECRET), audience: config.AUTH0_CLIENT_ID, + issuer: config.AUTH0_ISSUER }); // TODO: Move to single auth0 mechanism once they support SPA auth using API /* const jwtCheck = jwt({ From 5f8387a424490d92d72a0e10ad5cc9af83415056 Mon Sep 17 00:00:00 2001 From: Matthew Berryman Date: Wed, 1 Nov 2017 18:30:14 +1100 Subject: [PATCH 11/28] fix jwt for testing --- src/test/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/index.js b/src/test/index.js index 3cb382f..d82f934 100644 --- a/src/test/index.js +++ b/src/test/index.js @@ -59,7 +59,8 @@ let createdAt = new Date().toISOString(); const jwt = require('jsonwebtoken'); let token = jwt.sign({}, new Buffer(config.AUTH0_SECRET), - {audience: config.AUTH0_CLIENT_ID}); + {audience: config.AUTH0_CLIENT_ID, + issuer: config.AUTH0_ISSUER}); it('Server starts', function(done) { // Test optional server params From 3902ceaf67e791030821591f34cf6adc3aba3a88 Mon Sep 17 00:00:00 2001 From: Matthew Berryman Date: Sat, 4 Nov 2017 09:45:56 +1100 Subject: [PATCH 12/28] Revert "fix jwt for testing" This reverts commit 5f8387a424490d92d72a0e10ad5cc9af83415056. --- src/test/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/index.js b/src/test/index.js index d82f934..3cb382f 100644 --- a/src/test/index.js +++ b/src/test/index.js @@ -59,8 +59,7 @@ let createdAt = new Date().toISOString(); const jwt = require('jsonwebtoken'); let token = jwt.sign({}, new Buffer(config.AUTH0_SECRET), - {audience: config.AUTH0_CLIENT_ID, - issuer: config.AUTH0_ISSUER}); + {audience: config.AUTH0_CLIENT_ID}); it('Server starts', function(done) { // Test optional server params From 7272e680da831eb46b70d67ba06732d9292eda76 Mon Sep 17 00:00:00 2001 From: Matthew Berryman Date: Sat, 4 Nov 2017 09:46:15 +1100 Subject: [PATCH 13/28] Revert "use auth0 issuer in jwt check" This reverts commit 9e1e88d4f7fe376353c0ad25be9885f6f0eef395. --- src/lib/util.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/util.js b/src/lib/util.js index 6c44e7e..1c61b0a 100755 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -25,7 +25,6 @@ const cacheResponse = (duration) => cache(duration, config.CACHE); const jwtCheck = jwt({ secret: new Buffer(config.AUTH0_SECRET), audience: config.AUTH0_CLIENT_ID, - issuer: config.AUTH0_ISSUER }); // TODO: Move to single auth0 mechanism once they support SPA auth using API /* const jwtCheck = jwt({ From 0df36b3dcfefe55e286f176c4b32941eaf6f0979 Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 20 Nov 2017 11:25:41 -0500 Subject: [PATCH 14/28] Fix #63 - add expire value to CAP output --- CHANGELOG.md | 1 + README.md | 2 ++ package-lock.json | 2 +- src/api/routes/floods/index.js | 2 +- src/config.js | 2 ++ src/lib/cap.js | 11 ++++++++--- src/test/index.js | 2 +- src/test/testCAP.js | 5 +++-- 8 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7481fd..1164ea8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,3 +25,4 @@ API Server for CogniCity * Image upload changed to use AWS S3 signed links ### v3.0.3 +* Added a default expire time to CAP output diff --git a/README.md b/README.md index ef8788e..e35ebea 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,8 @@ Server configuration parameters are stored in a configuration file which is pars * `CACHE_DURATION_FLOODS`: How long should floods be cached for? (default: '1 hour') * `CACHE_DURATION_FLOODS_STATES`: How long should flood states be cached for? (default: '1 hour') * `CACHE_DURATION_INFRASTRUCTURE`: How long should infrastructure be cached for? (default: '1 hour') +* `CAP_DEFAULT_EXPIRE_SECONDS`: Default expire value for CAP output in seconds +* `CAP_TIMEZONE`: Timezone for CAP output * `COMPRESS`: Should the server gzip compress results? Only works if CACHE is disabled. (default: `false`) * `CORS`: Should Cross Object Resource Sharing (CORS) be enabled (default: `false`) * `CORS_HEADERS`: CORS headers to use (default: `[Link]`) diff --git a/package-lock.json b/package-lock.json index 6cdd350..9d649d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cognicity-server", - "version": "3.0.1", + "version": "3.0.3", "lockfileVersion": 1, "dependencies": { "@types/express": { diff --git a/src/api/routes/floods/index.js b/src/api/routes/floods/index.js index b50f6cc..eea1f00 100644 --- a/src/api/routes/floods/index.js +++ b/src/api/routes/floods/index.js @@ -58,7 +58,7 @@ const clearCache = () => { */ export default ({config, db, logger}) => { let api = Router(); // eslint-disable-line new-cap - const cap = new Cap(logger); // Setup our cap formatter + const cap = new Cap(config, logger); // Setup our cap formatter // Get a list of all floods api.get('/', cacheResponse(config.CACHE_DURATION_FLOODS), diff --git a/src/config.js b/src/config.js index df5ded0..e07778f 100644 --- a/src/config.js +++ b/src/config.js @@ -30,6 +30,8 @@ export default { CACHE_DURATION_FLOODS: process.env.CACHE_DURATION_FLOODS || '1 hour', CACHE_DURATION_FLOODS_STATES: process.env.CACHE_DURATION_FLOODS_STATES || '1 hour', CACHE_DURATION_INFRASTRUCTURE: process.env.CACHE_DURATION_INFRASTRUCTURE || '1 hour', + CAP_DEFAULT_EXPIRE_SECONDS: process.env.CAP_DEFAULT_EXPIRE_SECONDS || 21600, + CAP_TIMEZONE: process.env.CAP_TIMEZONE || 'Asia/Jakarta', COMPRESS: process.env.COMPRESS === 'true' || false, CORS: process.env.CORS === 'true' || false, CORS_HEADERS: process.env.CORS_HEADERS || ['Link'], diff --git a/src/lib/cap.js b/src/lib/cap.js index f8a1786..fe8c8d6 100644 --- a/src/lib/cap.js +++ b/src/lib/cap.js @@ -14,9 +14,11 @@ module.exports = class Cap { /** * Setup the CAP object to user specified logger * @alias module:lib/cap + * @param {Object} config Server configuration * @param {Object} logger Configured Winston logger instance */ - constructor(logger) { + constructor(config, logger) { + this.config = config; this.logger = logger; } /** @@ -94,8 +96,11 @@ module.exports = class Cap { alert.identifier = encodeURI(identifier); alert.sender = 'BPBD.JAKARTA.GOV.ID'; - alert.sent = moment.tz(feature.properties.last_updated, 'Asia/Jakarta' - ).format('YYYY-MM-DDTHH:mm:ssZ'); + alert.sent = moment.tz(feature.properties.last_updated, + self.config.CAP_TIMEZONE).format('YYYY-MM-DDTHH:mm:ssZ'); + alert.expires = moment.tz(new Date().getTime() + + self.config.CAP_DEFAULT_EXPIRE_SECONDS * 1000, + self.config.CAP_TIMEZONE).format('YYYY-MM-DDTHH:mm:ssZ'); alert.status = 'Actual'; alert.msgType = 'Alert'; alert.scope = 'Public'; diff --git a/src/test/index.js b/src/test/index.js index 3cb382f..ab98dfb 100644 --- a/src/test/index.js +++ b/src/test/index.js @@ -78,7 +78,7 @@ let token = jwt.sign({}, testFloods(app, token); testReports(app, reportid, createdAt); testReportsArchive(app, createdAt); - testCAP(logger); + testCAP(config, logger); testDB(); // Removes dummy data diff --git a/src/test/testCAP.js b/src/test/testCAP.js index 3c9b1a4..e043215 100644 --- a/src/test/testCAP.js +++ b/src/test/testCAP.js @@ -11,11 +11,12 @@ import Cap from '../lib/cap'; // Cap formatter helper /** * Test CAP data format utility * @function testCAP + * @param {Object} config - Server configuration * @param {Object} logger - CogniCity Server logger object */ -export default function(logger) { +export default function(config, logger) { describe('CAP Utility', function() { - const cap = new Cap(logger); // Setup our cap formatter + const cap = new Cap(config, logger); // Setup our cap formatter // dummy data (polygon) let feature = {'type': 'Feature', From 8c5f3464f414e35d8f4aa004a922a08e9552e42c Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 20 Nov 2017 15:23:50 -0500 Subject: [PATCH 15/28] Add new archive for floods endpoint --- src/api/routes/floods/archive/index.js | 51 +++++++++++ src/api/routes/floods/archive/model.js | 37 ++++++++ src/api/routes/floods/index.js | 6 ++ src/test/index.js | 4 +- src/test/testFloodsArchive.js | 113 +++++++++++++++++++++++++ src/test/testReportsArchive.js | 3 +- 6 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 src/api/routes/floods/archive/index.js create mode 100644 src/api/routes/floods/archive/model.js create mode 100644 src/test/testFloodsArchive.js diff --git a/src/api/routes/floods/archive/index.js b/src/api/routes/floods/archive/index.js new file mode 100644 index 0000000..d06970b --- /dev/null +++ b/src/api/routes/floods/archive/index.js @@ -0,0 +1,51 @@ +/** + * CogniCity Server /floods archive endpoint + * @module src/api/floods/archive/index + **/ +import {Router} from 'express'; + +// Import our data model +import archive from './model'; + +// Import any required utility functions +import {cacheResponse} from '../../../../lib/util'; + +// Import validation dependencies +import BaseJoi from 'joi'; +import Extension from 'joi-date-extensions'; +const Joi = BaseJoi.extend(Extension); +import validate from 'celebrate'; + +/** + * Endpoint specification for floods data + * @alias module:src/api/floods/archive/index + * @param {Object} config Server configuration + * @param {Object} db PG Promise database instance + * @param {Object} logger Configured Winston logger instance + * @return {Object} api Express router object for route + */ +export default ({config, db, logger}) => { + let api = Router(); // eslint-disable-line new-cap + + // Just get the states without the geographic boundaries + api.get('/', cacheResponse('1 minute'), + validate({ + query: { + start: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ').required(), + end: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ') + .min(Joi.ref('start')).required(), + }, + }), + (req, res, next) => { + archive(config, db, logger).maxstate(req.query.start, req.query.end) + .then((data) => res.status(200).json({statusCode: 200, result: data})) + .catch((err) => { + /* istanbul ignore next */ + logger.error(err); + /* istanbul ignore next */ + next(err); + }); + } + ); + return api; +}; diff --git a/src/api/routes/floods/archive/model.js b/src/api/routes/floods/archive/model.js new file mode 100644 index 0000000..d698796 --- /dev/null +++ b/src/api/routes/floods/archive/model.js @@ -0,0 +1,37 @@ +/** + * CogniCity Server /floods data model + * @module src/api/floods/model + **/ + import Promise from 'bluebird'; + + /** + * Methods to interact with flood layers in database + * @alias module:src/api/floods/model + * @param {Object} config Server configuration + * @param {Object} db PG Promise database instance + * @param {Object} logger Configured Winston logger instance + * @return {Object} Query methods + */ +export default (config, db, logger) => ({ + + // Get all flood reports for a given city + maxstate: (start, end) => new Promise((resolve, reject) => { + // Setup query + let query = `SELECT local_area as area_id, changed as last_updated, + max_state FROM cognicity.rem_get_max_flood($1, $2)`; + + // Setup values + let values = [start, end]; + + // Execute + logger.debug(query, values); + db.any(query, values).timeout(config.PGTIMEOUT) + .then((data) => { + resolve(data); + }) + .catch((err) => { + /* istanbul ignore next */ + reject(err); + }); + }), +}); diff --git a/src/api/routes/floods/index.js b/src/api/routes/floods/index.js index eea1f00..5d67e5f 100644 --- a/src/api/routes/floods/index.js +++ b/src/api/routes/floods/index.js @@ -7,6 +7,9 @@ import {Router} from 'express'; // Import our data model import floods from './model'; +// Import archive +import archive from './archive'; + // Import any required utility functions import {cacheResponse, formatGeo, jwtCheck} from '../../../lib/util'; @@ -185,5 +188,8 @@ floods(config, db, logger).allGeo(req.query.city, req.query.minimum_state) }) ); + // to get max flood states between two dates + api.use('/archive', archive({config, db, logger})); + return api; }; diff --git a/src/test/index.js b/src/test/index.js index ab98dfb..40b43e9 100644 --- a/src/test/index.js +++ b/src/test/index.js @@ -35,6 +35,7 @@ import testFeeds from './testFeeds.js'; import testFloodgauges from './testFloodgauges.js'; import testInfrastructure from './testInfrastructure.js'; import testFloods from './testFloods.js'; +import testFloodsArchive from './testFloodsArchive'; import testReports from './testReports.js'; import testReportsArchive from './testReportsArchive'; import testCAP from './testCAP.js'; @@ -76,8 +77,9 @@ let token = jwt.sign({}, testFloodgauges(app); testInfrastructure(app); testFloods(app, token); + testFloodsArchive(app); testReports(app, reportid, createdAt); - testReportsArchive(app, createdAt); + testReportsArchive(app); testCAP(config, logger); testDB(); diff --git a/src/test/testFloodsArchive.js b/src/test/testFloodsArchive.js new file mode 100644 index 0000000..3487c1c --- /dev/null +++ b/src/test/testFloodsArchive.js @@ -0,0 +1,113 @@ +/* eslint-disable max-len */ +/** + * testReportsArchive module + * @module test/testFloodsArchive + * A module to test the /reports/archive endpoint + */ + +import * as test from 'unit.js'; + +// TODO +// - test against an actual time in the database +// - Entered through cards.js (or add a new call to cards here) + +/** + * Test reports archive endpoint + * @function testFloodsArchive + * @param {Object} app - CogniCity server app object + * @param {String} createdAt - Sample ISO 8601 timestamp of report to test + */ +export default function(app) { + // Reports endpoint + describe('Reports Archive Endpoint', function() { + // Can get reports between given timestamps + it('Can get floods between given timestamps', function(done) { + test.httpAgent(app) + .get('/floods/archive?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700') + .expect(200) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no start parameter + it('Required start parameter by default', function(done) { + test.httpAgent(app) + .get('/reports/archive?end=2017-02-22T07:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no end parameter + it('Required end parameter by default', function(done) { + test.httpAgent(app) + .get('/reports/archive?start=2017-02-22T07:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Catch end time before start time + it('Required end time to be after start time', function(done) { + test.httpAgent(app) + .get('/reports/archive?start=2017-02-21T07:00:00%2B0700&end=2017-02-20T07:00:00') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no UTC offset in start parameter + it('Required start parameter to have a UTC offset', function(done) { + test.httpAgent(app) + .get('/reports/archive?start=2017-02-21T07:00:00') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no UTC offset in start parameter + it('Catches badly formed time stamp', function(done) { + test.httpAgent(app) + .get('/reports/archive?start=2017-02-21') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + }); +} diff --git a/src/test/testReportsArchive.js b/src/test/testReportsArchive.js index 4de52c3..9b6bd7e 100644 --- a/src/test/testReportsArchive.js +++ b/src/test/testReportsArchive.js @@ -15,9 +15,8 @@ import * as test from 'unit.js'; * Test reports archive endpoint * @function testReportsArchive * @param {Object} app - CogniCity server app object - * @param {String} createdAt - Sample ISO 8601 timestamp of report to test */ -export default function(app, createdAt) { +export default function(app) { // Reports endpoint describe('Reports Archive Endpoint', function() { // Can get reports between given timestamps From 274c06503b8dd20a22bbae16a753db17c259e3f2 Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 20 Nov 2017 15:24:18 -0500 Subject: [PATCH 16/28] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1164ea8..70f8b61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,3 +26,4 @@ API Server for CogniCity ### v3.0.3 * Added a default expire time to CAP output +* Add /floods/archive endpoint From 68a7d4d6b09065af48d9d6f3a19a98f39cdbd0fe Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 20 Nov 2017 16:43:20 -0500 Subject: [PATCH 17/28] Fix #60 more logging for cards --- src/api/routes/cards/model.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/api/routes/cards/model.js b/src/api/routes/cards/model.js index a8a1ff3..3af2ed9 100644 --- a/src/api/routes/cards/model.js +++ b/src/api/routes/cards/model.js @@ -26,12 +26,24 @@ export default (config, db, logger) => ({ // Execute logger.debug(query, values); db.oneOrNone(query, values).timeout(config.PGTIMEOUT) - .then((data) => resolve(data)) + .then((data) => { + // Card created, update database log + let query = `INSERT INTO ${config.TABLE_GRASP_LOG} + (card_id, event_type) VALUES ($1, $2)`; + let values = [data.card_id, 'CARD CREATED']; + db.oneOrNone(query, values).timeout(config.PGTIMEOUT) + .then(() => { + resolve(data); + }) + .catch((err) => { + reject(err); + }); + }) /* istanbul ignore next */ .catch((err) => { /* istanbul ignore next */ reject(err); -} + } ); }), From 8bea48c54ae57461594afda4f3703be3c7471ce6 Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 20 Nov 2017 16:43:51 -0500 Subject: [PATCH 18/28] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70f8b61..19c78b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,3 +27,4 @@ API Server for CogniCity ### v3.0.3 * Added a default expire time to CAP output * Add /floods/archive endpoint +* Added database log entry for card creation From f9137955377536b2bbb21da86dabf41f15909a8d Mon Sep 17 00:00:00 2001 From: Tomas Date: Wed, 22 Nov 2017 10:50:49 -0500 Subject: [PATCH 19/28] fixed comments --- src/api/routes/floods/archive/index.js | 4 ++-- src/api/routes/floods/archive/model.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/api/routes/floods/archive/index.js b/src/api/routes/floods/archive/index.js index d06970b..0daa381 100644 --- a/src/api/routes/floods/archive/index.js +++ b/src/api/routes/floods/archive/index.js @@ -1,5 +1,5 @@ /** - * CogniCity Server /floods archive endpoint + * CogniCity Server /floods/archive archive endpoint * @module src/api/floods/archive/index **/ import {Router} from 'express'; @@ -17,7 +17,7 @@ const Joi = BaseJoi.extend(Extension); import validate from 'celebrate'; /** - * Endpoint specification for floods data + * Endpoint specification for floods archive * @alias module:src/api/floods/archive/index * @param {Object} config Server configuration * @param {Object} db PG Promise database instance diff --git a/src/api/routes/floods/archive/model.js b/src/api/routes/floods/archive/model.js index d698796..bf0c369 100644 --- a/src/api/routes/floods/archive/model.js +++ b/src/api/routes/floods/archive/model.js @@ -1,6 +1,6 @@ /** - * CogniCity Server /floods data model - * @module src/api/floods/model + * CogniCity Server /floods/archive data model + * @module src/api/floods/archive model **/ import Promise from 'bluebird'; @@ -14,7 +14,7 @@ */ export default (config, db, logger) => ({ - // Get all flood reports for a given city + // Get max state of all flood reports over time maxstate: (start, end) => new Promise((resolve, reject) => { // Setup query let query = `SELECT local_area as area_id, changed as last_updated, From 479d2ce0da4d0fc34b3f40c6db217aeed0334f03 Mon Sep 17 00:00:00 2001 From: Tomas Date: Wed, 22 Nov 2017 13:25:53 -0500 Subject: [PATCH 20/28] Added flood timeseries endpoint --- CHANGELOG.md | 1 + src/api/routes/floods/index.js | 4 +- src/api/routes/floods/timeseries/index.js | 52 +++++++++++++++++++++++ src/api/routes/floods/timeseries/model.js | 44 +++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/api/routes/floods/timeseries/index.js create mode 100644 src/api/routes/floods/timeseries/model.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 19c78b1..0f72c79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,3 +28,4 @@ API Server for CogniCity * Added a default expire time to CAP output * Add /floods/archive endpoint * Added database log entry for card creation +* Added /floods/timeseries endpoint diff --git a/src/api/routes/floods/index.js b/src/api/routes/floods/index.js index 5d67e5f..d36bb58 100644 --- a/src/api/routes/floods/index.js +++ b/src/api/routes/floods/index.js @@ -7,8 +7,9 @@ import {Router} from 'express'; // Import our data model import floods from './model'; -// Import archive +// Import child routes import archive from './archive'; +import timeseries from './timeseries'; // Import any required utility functions import {cacheResponse, formatGeo, jwtCheck} from '../../../lib/util'; @@ -190,6 +191,7 @@ floods(config, db, logger).allGeo(req.query.city, req.query.minimum_state) // to get max flood states between two dates api.use('/archive', archive({config, db, logger})); + api.use('/timeseries', timeseries({config, db, logger})); return api; }; diff --git a/src/api/routes/floods/timeseries/index.js b/src/api/routes/floods/timeseries/index.js new file mode 100644 index 0000000..7fde972 --- /dev/null +++ b/src/api/routes/floods/timeseries/index.js @@ -0,0 +1,52 @@ +/** + * CogniCity Server /floods timeseries endpoint + * @module src/api/floods/timeseries/index + **/ +import {Router} from 'express'; + +// Import our data model +import timeseries from './model'; + +// Import any required utility functions +import {cacheResponse} from '../../../../lib/util'; + +// Import validation dependencies +import BaseJoi from 'joi'; +import Extension from 'joi-date-extensions'; +const Joi = BaseJoi.extend(Extension); +import validate from 'celebrate'; +import Moment from 'moment'; + +/** + * Endpoint specification for floods timeseries data + * @alias module:src/api/floods/timeseries/index + * @param {Object} config Server configuration + * @param {Object} db PG Promise database instance + * @param {Object} logger Configured Winston logger instance + * @return {Object} api Express router object for route + */ +export default ({config, db, logger}) => { + let api = Router(); // eslint-disable-line new-cap + + // Just get the states without the geographic boundaries + api.get('/', cacheResponse('1 minute'), + validate({ + query: { + start: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ').required(), + end: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ') + .min(Joi.ref('start')).required(), + }, + }), + (req, res, next) => { + timeseries(config, db, logger).count(req.query.start, req.query.end) + .then((data) => res.status(200).json({statusCode: 200, result: data})) + .catch((err) => { + /* istanbul ignore next */ + logger.error(err); + /* istanbul ignore next */ + next(err); + }); + } + ); + return api; +}; diff --git a/src/api/routes/floods/timeseries/model.js b/src/api/routes/floods/timeseries/model.js new file mode 100644 index 0000000..2e97ad9 --- /dev/null +++ b/src/api/routes/floods/timeseries/model.js @@ -0,0 +1,44 @@ +/** + * CogniCity Server /floods/timeseries data model + * @module src/api/floods/timeseries/model + **/ + import Promise from 'bluebird'; + + /** + * Methods to interact with flood layers in database + * @alias module:src/api/floods/timeseries/model + * @param {Object} config Server configuration + * @param {Object} db PG Promise database instance + * @param {Object} logger Configured Winston logger instance + * @return {Object} Query methods + */ +export default (config, db, logger) => ({ + + // Get all flood reports for a given city + count: (start, end) => new Promise((resolve, reject) => { + // Setup query + let query = `SELECT ts, count(local_area) FROM + (SELECT (cognicity.rem_get_flood(ts)).local_area, ts + FROM generate_series($1::timestamp with time zone, + $2::timestamp with time zone,'1 hour') + as series(ts)) output + GROUP BY ts ORDER BY ts`; + + // Setup values + let values = [start, end]; + + // Execute + logger.debug(query, values); + db.any(query, values).timeout(config.PGTIMEOUT) + .then((data) => { + resolve(data); + }) + .catch((err) => { + /* istanbul ignore next */ + reject(err); + }); + }), +}); + + +/**/ From 717a10c452e4571b572741111b86a754e2dcbb50 Mon Sep 17 00:00:00 2001 From: Tomas Date: Wed, 22 Nov 2017 13:53:26 -0500 Subject: [PATCH 21/28] added timeseries endpoints --- CHANGELOG.md | 1 + src/api/routes/floods/archive/index.js | 2 +- src/api/routes/floods/timeseries/index.js | 3 +- src/api/routes/floods/timeseries/model.js | 3 - src/api/routes/reports/index.js | 6 +- src/api/routes/reports/timeseries/index.js | 51 ++++++++++ src/api/routes/reports/timeseries/model.js | 40 ++++++++ src/test/index.js | 4 + src/test/testFloodsArchive.js | 9 +- src/test/testFloodsTimeseries.js | 112 +++++++++++++++++++++ src/test/testReportsTimeseries.js | 112 +++++++++++++++++++++ 11 files changed, 330 insertions(+), 13 deletions(-) create mode 100644 src/api/routes/reports/timeseries/index.js create mode 100644 src/api/routes/reports/timeseries/model.js create mode 100644 src/test/testFloodsTimeseries.js create mode 100644 src/test/testReportsTimeseries.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f72c79..895dd84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,3 +29,4 @@ API Server for CogniCity * Add /floods/archive endpoint * Added database log entry for card creation * Added /floods/timeseries endpoint +* Added /reports/timeseries endpoint diff --git a/src/api/routes/floods/archive/index.js b/src/api/routes/floods/archive/index.js index 0daa381..b5ea22b 100644 --- a/src/api/routes/floods/archive/index.js +++ b/src/api/routes/floods/archive/index.js @@ -26,7 +26,7 @@ import validate from 'celebrate'; */ export default ({config, db, logger}) => { let api = Router(); // eslint-disable-line new-cap - + // TODO add support for multiple cities // Just get the states without the geographic boundaries api.get('/', cacheResponse('1 minute'), validate({ diff --git a/src/api/routes/floods/timeseries/index.js b/src/api/routes/floods/timeseries/index.js index 7fde972..5b23e38 100644 --- a/src/api/routes/floods/timeseries/index.js +++ b/src/api/routes/floods/timeseries/index.js @@ -15,7 +15,6 @@ import BaseJoi from 'joi'; import Extension from 'joi-date-extensions'; const Joi = BaseJoi.extend(Extension); import validate from 'celebrate'; -import Moment from 'moment'; /** * Endpoint specification for floods timeseries data @@ -27,7 +26,7 @@ import Moment from 'moment'; */ export default ({config, db, logger}) => { let api = Router(); // eslint-disable-line new-cap - + // TODO add support for multiple cities // Just get the states without the geographic boundaries api.get('/', cacheResponse('1 minute'), validate({ diff --git a/src/api/routes/floods/timeseries/model.js b/src/api/routes/floods/timeseries/model.js index 2e97ad9..7a981c6 100644 --- a/src/api/routes/floods/timeseries/model.js +++ b/src/api/routes/floods/timeseries/model.js @@ -39,6 +39,3 @@ export default (config, db, logger) => ({ }); }), }); - - -/**/ diff --git a/src/api/routes/reports/index.js b/src/api/routes/reports/index.js index b2f82cf..c7c0013 100644 --- a/src/api/routes/reports/index.js +++ b/src/api/routes/reports/index.js @@ -7,7 +7,9 @@ // Import our data model import reports from './model'; +// Import child routes import archive from './archive'; +import timeseries from './timeseries'; // Import any required utility functions import {cacheResponse, handleGeoResponse} from '../../../lib/util'; @@ -51,8 +53,9 @@ export default ({config, db, logger}) => { }) ); - // to get all reports between two dates + // child routes before /:id api.use('/archive', archive({config, db, logger})); + api.use('/timeseries', timeseries({config, db, logger})); // Get a single report api.get('/:id', cacheResponse('1 minute'), @@ -75,6 +78,5 @@ export default ({config, db, logger}) => { }) ); - return api; }; diff --git a/src/api/routes/reports/timeseries/index.js b/src/api/routes/reports/timeseries/index.js new file mode 100644 index 0000000..787be81 --- /dev/null +++ b/src/api/routes/reports/timeseries/index.js @@ -0,0 +1,51 @@ +/** + * CogniCity Server /reports timeseries endpoint + * @module src/api/reports/timeseries/index + **/ +import {Router} from 'express'; + +// Import our data model +import timeseries from './model'; + +// Import any required utility functions +import {cacheResponse} from '../../../../lib/util'; + +// Import validation dependencies +import BaseJoi from 'joi'; +import Extension from 'joi-date-extensions'; +const Joi = BaseJoi.extend(Extension); +import validate from 'celebrate'; + +/** + * Endpoint specification for reports timeseries data + * @alias module:src/api/reports/timeseries/index + * @param {Object} config Server configuration + * @param {Object} db PG Promise database instance + * @param {Object} logger Configured Winston logger instance + * @return {Object} api Express router object for route + */ +export default ({config, db, logger}) => { + let api = Router(); // eslint-disable-line new-cap + // TODO add support for multiple cities + // Just get the states without the geographic boundaries + api.get('/', cacheResponse('1 minute'), + validate({ + query: { + start: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ').required(), + end: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ') + .min(Joi.ref('start')).required(), + }, + }), + (req, res, next) => { + timeseries(config, db, logger).count(req.query.start, req.query.end) + .then((data) => res.status(200).json({statusCode: 200, result: data})) + .catch((err) => { + /* istanbul ignore next */ + logger.error(err); + /* istanbul ignore next */ + next(err); + }); + } + ); + return api; +}; diff --git a/src/api/routes/reports/timeseries/model.js b/src/api/routes/reports/timeseries/model.js new file mode 100644 index 0000000..a50d07c --- /dev/null +++ b/src/api/routes/reports/timeseries/model.js @@ -0,0 +1,40 @@ +/** + * CogniCity Server /reports/timeseries data model + * @module src/api/reports/timeseries/model + **/ + import Promise from 'bluebird'; + + /** + * Methods to interact with report layer in database + * @alias module:src/api/reports/timeseries/model + * @param {Object} config Server configuration + * @param {Object} db PG Promise database instance + * @param {Object} logger Configured Winston logger instance + * @return {Object} Query methods + */ +export default (config, db, logger) => ({ + + // Get all flood reports for a given city + count: (start, end) => new Promise((resolve, reject) => { + // Setup query + let query = `SELECT ts, count(r.pkey) + FROM generate_series($1::timestamp with time zone, + $2::timestamp with time zone, '1 hour') ts + LEFT JOIN cognicity.all_reports r + ON date_trunc('hour', r.created_at) = ts GROUP BY ts ORDER BY ts`; + + // Setup values + let values = [start, end]; + + // Execute + logger.debug(query, values); + db.any(query, values).timeout(config.PGTIMEOUT) + .then((data) => { + resolve(data); + }) + .catch((err) => { + /* istanbul ignore next */ + reject(err); + }); + }), +}); diff --git a/src/test/index.js b/src/test/index.js index 40b43e9..68139f1 100644 --- a/src/test/index.js +++ b/src/test/index.js @@ -36,8 +36,10 @@ import testFloodgauges from './testFloodgauges.js'; import testInfrastructure from './testInfrastructure.js'; import testFloods from './testFloods.js'; import testFloodsArchive from './testFloodsArchive'; +import testFloodsTimeseries from './testFloodsTimeseries'; import testReports from './testReports.js'; import testReportsArchive from './testReportsArchive'; +import testReportsTimeseries from './testReportsTimeseries'; import testCAP from './testCAP.js'; import testDB from './testDB.js'; @@ -78,8 +80,10 @@ let token = jwt.sign({}, testInfrastructure(app); testFloods(app, token); testFloodsArchive(app); + testFloodsTimeseries(app); testReports(app, reportid, createdAt); testReportsArchive(app); + testReportsTimeseries(app); testCAP(config, logger); testDB(); diff --git a/src/test/testFloodsArchive.js b/src/test/testFloodsArchive.js index 3487c1c..dcc3959 100644 --- a/src/test/testFloodsArchive.js +++ b/src/test/testFloodsArchive.js @@ -2,7 +2,7 @@ /** * testReportsArchive module * @module test/testFloodsArchive - * A module to test the /reports/archive endpoint + * A module to test the /floods/archive endpoint */ import * as test from 'unit.js'; @@ -12,10 +12,9 @@ import * as test from 'unit.js'; // - Entered through cards.js (or add a new call to cards here) /** - * Test reports archive endpoint + * Test floods archive endpoint * @function testFloodsArchive * @param {Object} app - CogniCity server app object - * @param {String} createdAt - Sample ISO 8601 timestamp of report to test */ export default function(app) { // Reports endpoint @@ -38,7 +37,7 @@ export default function(app) { // Can catch no start parameter it('Required start parameter by default', function(done) { test.httpAgent(app) - .get('/reports/archive?end=2017-02-22T07:00:00%2B0700') + .get('/floods/archive?end=2017-02-22T07:00:00%2B0700') .expect(400) .expect('Content-Type', /json/) .end(function(err, res) { @@ -53,7 +52,7 @@ export default function(app) { // Can catch no end parameter it('Required end parameter by default', function(done) { test.httpAgent(app) - .get('/reports/archive?start=2017-02-22T07:00:00%2B0700') + .get('/floods/archive?start=2017-02-22T07:00:00%2B0700') .expect(400) .expect('Content-Type', /json/) .end(function(err, res) { diff --git a/src/test/testFloodsTimeseries.js b/src/test/testFloodsTimeseries.js new file mode 100644 index 0000000..4868e99 --- /dev/null +++ b/src/test/testFloodsTimeseries.js @@ -0,0 +1,112 @@ +/* eslint-disable max-len */ +/** + * testFloodsArchive module + * @module test/testFloodsTimeseries + * A module to test the /floods/timeseries endpoint + */ + +import * as test from 'unit.js'; + +// TODO +// - test against an actual time in the database +// - Entered through cards.js (or add a new call to cards here) + +/** + * Test floods timeseries endpoint + * @function testFloodsTimeseries + * @param {Object} app - CogniCity server app object + */ +export default function(app) { + // Floods endpoint + describe('Floods Archive Endpoint', function() { + // Can get floods between given timestamps + it('Can get floods timeseries given timestamps', function(done) { + test.httpAgent(app) + .get('/floods/timeseries?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700') + .expect(200) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no start parameter + it('Required start parameter by default', function(done) { + test.httpAgent(app) + .get('/floods/timeseries?end=2017-02-22T07:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no end parameter + it('Required end parameter by default', function(done) { + test.httpAgent(app) + .get('/floods/timeseries?start=2017-02-22T07:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Catch end time before start time + it('Required end time to be after start time', function(done) { + test.httpAgent(app) + .get('/floods/timeseries?start=2017-02-21T07:00:00%2B0700&end=2017-02-20T07:00:00') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no UTC offset in start parameter + it('Required start parameter to have a UTC offset', function(done) { + test.httpAgent(app) + .get('/floods/timeseries?start=2017-02-21T07:00:00') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no UTC offset in start parameter + it('Catches badly formed time stamp', function(done) { + test.httpAgent(app) + .get('/floods/timeseries?start=2017-02-21') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + }); +} diff --git a/src/test/testReportsTimeseries.js b/src/test/testReportsTimeseries.js new file mode 100644 index 0000000..141070a --- /dev/null +++ b/src/test/testReportsTimeseries.js @@ -0,0 +1,112 @@ +/* eslint-disable max-len */ +/** + * testReportsArchive module + * @module test/testReportsTimeseries + * A module to test the /reports/timeseries endpoint + */ + +import * as test from 'unit.js'; + +// TODO +// - test against an actual time in the database +// - Entered through cards.js (or add a new call to cards here) + +/** + * Test floods timeseries endpoint + * @function testReportsTimeseries + * @param {Object} app - CogniCity server app object + */ +export default function(app) { + // Reports endpoint + describe('Reports Archive Endpoint', function() { + // Can get floods between given timestamps + it('Can get floods timeseries given timestamps', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700') + .expect(200) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no start parameter + it('Required start parameter by default', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?end=2017-02-22T07:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no end parameter + it('Required end parameter by default', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?start=2017-02-22T07:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Catch end time before start time + it('Required end time to be after start time', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?start=2017-02-21T07:00:00%2B0700&end=2017-02-20T07:00:00') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no UTC offset in start parameter + it('Required start parameter to have a UTC offset', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?start=2017-02-21T07:00:00') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Can catch no UTC offset in start parameter + it('Catches badly formed time stamp', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?start=2017-02-21') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + }); +} From 018bfd74722e5b133861ba890c1bc1ba63781345 Mon Sep 17 00:00:00 2001 From: Tomas Date: Wed, 22 Nov 2017 17:01:04 -0500 Subject: [PATCH 22/28] Fix #64 time series limits --- CHANGELOG.md | 1 + src/api/routes/floods/archive/index.js | 16 ++++++++++++++++ src/api/routes/floods/timeseries/index.js | 17 +++++++++++++++++ src/api/routes/reports/archive/index.js | 22 ++++++++++++++++++++-- src/api/routes/reports/timeseries/index.js | 16 ++++++++++++++++ src/test/testFloodsArchive.js | 15 +++++++++++++++ src/test/testFloodsTimeseries.js | 15 +++++++++++++++ src/test/testReportsArchive.js | 19 +++++++++++++++++-- src/test/testReportsTimeseries.js | 14 ++++++++++++++ 9 files changed, 131 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 895dd84..dad86a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,3 +30,4 @@ API Server for CogniCity * Added database log entry for card creation * Added /floods/timeseries endpoint * Added /reports/timeseries endpoint +* Added time window check on archive and time series endpoints diff --git a/src/api/routes/floods/archive/index.js b/src/api/routes/floods/archive/index.js index b5ea22b..67fed71 100644 --- a/src/api/routes/floods/archive/index.js +++ b/src/api/routes/floods/archive/index.js @@ -37,6 +37,22 @@ export default ({config, db, logger}) => { }, }), (req, res, next) => { + // validate the time window, if fails send 400 error + let maxWindow = new Date(req.query.start).getTime() + + (config.API_REPORTS_TIME_WINDOW_MAX * 1000); + let end = new Date(req.query.end); + if (end > maxWindow) { + res.status(400).json({'statusCode': 400, 'error': 'Bad Request', + 'message': 'child \'end\' fails because [end is more than ' + + config.API_REPORTS_TIME_WINDOW_MAX + + ' seconds greater than \'start\']', + 'validation': { + 'source': 'query', + 'keys': [ + 'end', + ]}}); + return; + } archive(config, db, logger).maxstate(req.query.start, req.query.end) .then((data) => res.status(200).json({statusCode: 200, result: data})) .catch((err) => { diff --git a/src/api/routes/floods/timeseries/index.js b/src/api/routes/floods/timeseries/index.js index 5b23e38..0c1da00 100644 --- a/src/api/routes/floods/timeseries/index.js +++ b/src/api/routes/floods/timeseries/index.js @@ -37,6 +37,23 @@ export default ({config, db, logger}) => { }, }), (req, res, next) => { + // validate the time window, if fails send 400 error + let maxWindow = new Date(req.query.start).getTime() + + (config.API_REPORTS_TIME_WINDOW_MAX * 1000); + let end = new Date(req.query.end); + if (end > maxWindow) { + res.status(400).json({'statusCode': 400, 'error': 'Bad Request', + 'message': 'child \'end\' fails because [end is more than ' + + config.API_REPORTS_TIME_WINDOW_MAX + + ' seconds greater than \'start\']', + 'validation': { + 'source': 'query', + 'keys': [ + 'end', + ]}}); + return; + } + timeseries(config, db, logger).count(req.query.start, req.query.end) .then((data) => res.status(200).json({statusCode: 200, result: data})) .catch((err) => { diff --git a/src/api/routes/reports/archive/index.js b/src/api/routes/reports/archive/index.js index fc522ab..5faf7a9 100644 --- a/src/api/routes/reports/archive/index.js +++ b/src/api/routes/reports/archive/index.js @@ -41,7 +41,24 @@ export default ({config, db, logger}) => { .default(config.GEO_FORMAT_DEFAULT), }, }), - (req, res, next) => archive(config, db, logger) + (req, res, next) => { + // validate the time window, if fails send 400 error + let maxWindow = new Date(req.query.start).getTime() + + (config.API_REPORTS_TIME_WINDOW_MAX * 1000); + let end = new Date(req.query.end); + if (end > maxWindow) { + res.status(400).json({'statusCode': 400, 'error': 'Bad Request', + 'message': 'child \'end\' fails because [end is more than ' + + config.API_REPORTS_TIME_WINDOW_MAX + + ' seconds greater than \'start\']', + 'validation': { + 'source': 'query', + 'keys': [ + 'end', + ]}}); + return; + } + archive(config, db, logger) .all(req.query.start, req.query.end, req.query.city) .then((data) => handleGeoResponse(data, req, res, next)) .catch((err) => { @@ -49,7 +66,8 @@ export default ({config, db, logger}) => { logger.error(err); /* istanbul ignore next */ next(err); - }) + }); + } ); return api; diff --git a/src/api/routes/reports/timeseries/index.js b/src/api/routes/reports/timeseries/index.js index 787be81..3d32edd 100644 --- a/src/api/routes/reports/timeseries/index.js +++ b/src/api/routes/reports/timeseries/index.js @@ -37,6 +37,22 @@ export default ({config, db, logger}) => { }, }), (req, res, next) => { + // validate the time window, if fails send 400 error + let maxWindow = new Date(req.query.start).getTime() + + (config.API_REPORTS_TIME_WINDOW_MAX * 1000); + let end = new Date(req.query.end); + if (end > maxWindow) { + res.status(400).json({'statusCode': 400, 'error': 'Bad Request', + 'message': 'child \'end\' fails because [end is more than ' + + config.API_REPORTS_TIME_WINDOW_MAX + + ' seconds greater than \'start\']', + 'validation': { + 'source': 'query', + 'keys': [ + 'end', + ]}}); + return; + } timeseries(config, db, logger).count(req.query.start, req.query.end) .then((data) => res.status(200).json({statusCode: 200, result: data})) .catch((err) => { diff --git a/src/test/testFloodsArchive.js b/src/test/testFloodsArchive.js index dcc3959..806c2ca 100644 --- a/src/test/testFloodsArchive.js +++ b/src/test/testFloodsArchive.js @@ -108,5 +108,20 @@ export default function(app) { } }); }); + + // Catches start - end time window greater than one week + it('Catch large time windows', function(done) { + test.httpAgent(app) + .get('/floods/archive?start=2017-06-07T00:00:00%2B0700&end=2017-06-15T23:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); }); } diff --git a/src/test/testFloodsTimeseries.js b/src/test/testFloodsTimeseries.js index 4868e99..d282672 100644 --- a/src/test/testFloodsTimeseries.js +++ b/src/test/testFloodsTimeseries.js @@ -108,5 +108,20 @@ export default function(app) { } }); }); + + // Catches start - end time window greater than one week + it('Catch large time windows', function(done) { + test.httpAgent(app) + .get('/floods/timeseries?start=2017-06-07T00:00:00%2B0700&end=2017-06-15T23:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); }); } diff --git a/src/test/testReportsArchive.js b/src/test/testReportsArchive.js index 9b6bd7e..5cd21d4 100644 --- a/src/test/testReportsArchive.js +++ b/src/test/testReportsArchive.js @@ -20,8 +20,9 @@ export default function(app) { // Reports endpoint describe('Reports Archive Endpoint', function() { // Can get reports between given timestamps - - let end = new Date().toISOString().slice(0, -5)+'Z'; + let end = new Date('2017-06-07T00:00:00+0700'); + end.setHours(end.getHours() + 72); + end = end.toISOString().slice(0, -5)+'Z'; it('Can get reports between given timestamps', function(done) { test.httpAgent(app) @@ -145,5 +146,19 @@ export default function(app) { } }); }); + // Catches start - end time window greater than one week + it('Catch large time windows', function(done) { + test.httpAgent(app) + .get('/floods/archive?start=2017-06-07T00:00:00%2B0700&end=2017-06-15T23:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); }); } diff --git a/src/test/testReportsTimeseries.js b/src/test/testReportsTimeseries.js index 141070a..e135725 100644 --- a/src/test/testReportsTimeseries.js +++ b/src/test/testReportsTimeseries.js @@ -108,5 +108,19 @@ export default function(app) { } }); }); + // Catches start - end time window greater than one week + it('Catch large time windows', function(done) { + test.httpAgent(app) + .get('/floods/archive?start=2017-06-07T00:00:00%2B0700&end=2017-06-15T23:00:00%2B0700') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); }); } From a331fec125e437f33b63601f50e6f19d26106c0b Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 4 Dec 2017 14:51:30 -0500 Subject: [PATCH 23/28] updated api gw swagger --- swagger-api.json | 855 ++++++++--------------------------------------- 1 file changed, 133 insertions(+), 722 deletions(-) diff --git a/swagger-api.json b/swagger-api.json index 8fd2049..b6ccf71 100644 --- a/swagger-api.json +++ b/swagger-api.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "version": "2017-06-29T01:04:57Z", + "version": "2017-12-04T19:34:16Z", "title": "cognicity" }, "host": "data-dev.petabencana.id", @@ -21,17 +21,6 @@ "$ref": "#/definitions/Empty" } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "https://${stageVariables.env}.petabencana.id", - "passthroughBehavior": "when_no_match", - "httpMethod": "GET", - "type": "http_proxy" } } }, @@ -52,18 +41,7 @@ { "api_key": [] } - ], - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/cards", - "passthroughBehavior": "when_no_match", - "httpMethod": "POST", - "type": "http_proxy" - } + ] }, "options": { "consumes": [ @@ -90,23 +68,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -136,23 +97,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -211,47 +155,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "400": { - "statusCode": "400", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - }, - "404": { - "statusCode": "404", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - }, - "409": { - "statusCode": "409", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - }, - "500": { - "statusCode": "500", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - }, - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/cards/{cardId}", - "requestParameters": { - "integration.request.path.cardId": "method.request.path.cardId" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "ANY", - "type": "http" } } }, @@ -261,6 +164,12 @@ "application/json" ], "parameters": [ + { + "name": "content-type", + "in": "header", + "required": true, + "type": "string" + }, { "name": "cardId", "in": "path", @@ -280,23 +189,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/cards/{cardId}/images", - "requestParameters": { - "integration.request.path.cardId": "method.request.path.cardId" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "GET", - "type": "http" } }, "options": { @@ -306,6 +198,14 @@ "produces": [ "application/json" ], + "parameters": [ + { + "name": "content-type", + "in": "header", + "required": true, + "type": "string" + } + ], "responses": { "200": { "description": "200 response", @@ -324,23 +224,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -370,22 +253,6 @@ "$ref": "#/definitions/Empty" } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/cities", - "passthroughBehavior": "when_no_match", - "httpMethod": "GET", - "cacheNamespace": "h1la88", - "cacheKeyParameters": [ - "method.request.querystring.format", - "method.request.querystring.geoformat" - ], - "type": "http_proxy" } }, "options": { @@ -413,23 +280,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -459,23 +309,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -501,21 +334,7 @@ { "api_key": [] } - ], - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/feeds/qlue", - "passthroughBehavior": "when_no_match", - "httpMethod": "POST", - "type": "http" - } + ] }, "options": { "consumes": [ @@ -542,23 +361,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -599,31 +401,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/floodgauges", - "requestParameters": { - "integration.request.querystring.city": "method.request.querystring.city", - "integration.request.querystring.geoformat": "method.request.querystring.geoformat", - "integration.request.querystring.format": "method.request.querystring.format" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "GET", - "cacheNamespace": "so358j", - "cacheKeyParameters": [ - "method.request.querystring.city", - "method.request.querystring.format", - "method.request.querystring.geoformat" - ], - "type": "http" } }, "options": { @@ -651,23 +428,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -697,23 +457,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -734,26 +477,7 @@ "type": "string" } ], - "responses": {}, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/floodgauges/{id}", - "requestParameters": { - "integration.request.path.id": "method.request.path.id" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "ANY", - "cacheNamespace": "p829iq", - "cacheKeyParameters": [ - "method.request.path.id", - "method.request.querystring.format" - ], - "type": "http_proxy" - } + "responses": {} } }, "/floods": { @@ -803,34 +527,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Content-Type": "integration.response.header.Content-Type", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/floods/", - "requestParameters": { - "integration.request.querystring.city": "method.request.querystring.city", - "integration.request.querystring.geoformat": "method.request.querystring.geoformat", - "integration.request.querystring.minimum_state": "method.request.querystring.minimum_state", - "integration.request.querystring.format": "method.request.querystring.format" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "GET", - "cacheNamespace": "nvy9s5", - "cacheKeyParameters": [ - "method.request.querystring.city", - "method.request.querystring.format", - "method.request.querystring.geoformat", - "method.request.querystring.minimum_state" - ], - "type": "http" } }, "head": { @@ -847,18 +543,6 @@ "$ref": "#/definitions/Empty" } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } }, "options": { @@ -886,23 +570,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -943,31 +610,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/floods/states", - "requestParameters": { - "integration.request.querystring.city": "method.request.querystring.city", - "integration.request.querystring.minimum_state": "method.request.querystring.minimum_state", - "integration.request.querystring.format": "method.request.querystring.format" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "GET", - "cacheNamespace": "cxp4qo", - "cacheKeyParameters": [ - "method.request.querystring.city", - "method.request.querystring.format", - "method.request.querystring.minimum_state" - ], - "type": "http" } }, "options": { @@ -995,23 +637,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -1041,23 +666,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -1078,26 +686,7 @@ "type": "string" } ], - "responses": {}, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/floods/{id}", - "requestParameters": { - "integration.request.path.id": "method.request.path.id" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "ANY", - "cacheNamespace": "8q9uet", - "cacheKeyParameters": [ - "method.request.path.id", - "method.request.querystring.format" - ], - "type": "http_proxy" - } + "responses": {} } }, "/infrastructure": { @@ -1126,23 +715,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -1172,23 +744,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -1221,28 +776,7 @@ "type": "string" } ], - "responses": {}, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/infrastructure/{type}", - "requestParameters": { - "integration.request.path.type": "method.request.path.type" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "ANY", - "cacheNamespace": "qtdnlp", - "cacheKeyParameters": [ - "method.request.path.type", - "method.request.querystring.city", - "method.request.querystring.format", - "method.request.querystring.geoformat" - ], - "type": "http_proxy" - } + "responses": {} } }, "/reports": { @@ -1288,33 +822,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/reports", - "requestParameters": { - "integration.request.querystring.city": "method.request.querystring.city", - "integration.request.querystring.geoformat": "method.request.querystring.geoformat", - "integration.request.querystring.timeperiod": "method.request.querystring.timeperiod", - "integration.request.querystring.format": "method.request.querystring.format" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "GET", - "cacheNamespace": "8vxlp8", - "cacheKeyParameters": [ - "method.request.querystring.city", - "method.request.querystring.geoformat", - "method.request.querystring.timeperiod", - "method.request.querystring.format" - ], - "type": "http" } }, "options": { @@ -1342,23 +849,119 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } + } + } + }, + "/reports/archive": { + "get": { + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "city", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "format", + "in": "query", + "required": false, + "type": "string" }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" + { + "name": "geoformat", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + } + } + } + }, + "options": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + } + } + } + } + }, + "/reports/timeseries": { + "get": { + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" }, - "passthroughBehavior": "when_no_match", - "type": "mock" + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + }, + "headers": { + "Access-Control-Allow-Origin": { + "type": "string" + } + } + } + } + }, + "options": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + } + } } } }, @@ -1388,23 +991,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -1425,26 +1011,7 @@ "type": "string" } ], - "responses": {}, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "https://${stageVariables.env}.petabencana.id/reports/{id}", - "requestParameters": { - "integration.request.path.id": "method.request.path.id" - }, - "passthroughBehavior": "when_no_match", - "httpMethod": "ANY", - "cacheNamespace": "5tep32", - "cacheKeyParameters": [ - "method.request.path.id", - "method.request.querystring.format" - ], - "type": "http_proxy" - } + "responses": {} } }, "/stats": { @@ -1473,23 +1040,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -1510,21 +1060,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:cognicity-statistics-${stageVariables.stage}-floodedRWsSummary/invocations", - "passthroughBehavior": "when_no_match", - "httpMethod": "POST", - "contentHandling": "CONVERT_TO_TEXT", - "type": "aws_proxy" } }, "options": { @@ -1552,23 +1087,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -1589,21 +1107,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:cognicity-statistics-${stageVariables.stage}-floodedRegionsSummary/invocations", - "passthroughBehavior": "when_no_match", - "httpMethod": "POST", - "contentHandling": "CONVERT_TO_TEXT", - "type": "aws_proxy" } }, "options": { @@ -1631,23 +1134,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -1663,18 +1149,6 @@ "$ref": "#/definitions/Empty" } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200" - } - }, - "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:cognicity-statistics-${stageVariables.stage}-reportsSummary/invocations", - "passthroughBehavior": "when_no_match", - "httpMethod": "POST", - "contentHandling": "CONVERT_TO_TEXT", - "type": "aws_proxy" } }, "options": { @@ -1702,23 +1176,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } }, @@ -1742,27 +1199,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - ".*": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Origin": "'*'" - }, - "responseTemplates": { - "text/xml": "#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))\n$errorMessageObj.message\n" - } - } - }, - "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:twilio/invocations", - "requestTemplates": { - "application/x-www-form-urlencoded": "{\n \"reqbody\":\"$input.path('$')\"\n}" - }, - "passthroughBehavior": "when_no_templates", - "httpMethod": "POST", - "contentHandling": "CONVERT_TO_TEXT", - "type": "aws" } }, "options": { @@ -1790,23 +1226,6 @@ } } } - }, - "x-amazon-apigateway-integration": { - "responses": { - "default": { - "statusCode": "200", - "responseParameters": { - "method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS'", - "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", - "method.response.header.Access-Control-Allow-Origin": "'*'" - } - } - }, - "requestTemplates": { - "application/json": "{\"statusCode\": 200}" - }, - "passthroughBehavior": "when_no_match", - "type": "mock" } } } @@ -1823,13 +1242,5 @@ "type": "object", "title": "Empty Schema" } - }, - "x-amazon-apigateway-binary-media-types": [ - "application/gzip", - "application/x-gzip", - "application/x-compressed", - "image/png", - "image/jpeg", - "image/gif" - ] + } } \ No newline at end of file From a1ed68528b88d1f456e969860ace19af848b3daf Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 4 Dec 2017 15:21:06 -0500 Subject: [PATCH 24/28] added new child endpoints to /floods --- swagger-api.json | 92 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/swagger-api.json b/swagger-api.json index b6ccf71..2222581 100644 --- a/swagger-api.json +++ b/swagger-api.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "version": "2017-12-04T19:34:16Z", + "version": "2017-12-04T20:19:23Z", "title": "cognicity" }, "host": "data-dev.petabencana.id", @@ -573,6 +573,51 @@ } } }, + "/floods/archive": { + "get": { + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + } + } + } + }, + "options": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + } + } + } + } + }, "/floods/states": { "get": { "produces": [ @@ -640,6 +685,51 @@ } } }, + "/floods/timeseries": { + "get": { + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "start", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "end", + "in": "query", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + } + } + } + }, + "options": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "200 response", + "schema": { + "$ref": "#/definitions/Empty" + } + } + } + } + }, "/floods/{id+}": { "options": { "consumes": [ From 43566186334567cc60a85923ec48c4e5d3ba7496 Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 4 Dec 2017 15:39:03 -0500 Subject: [PATCH 25/28] added tests for city param --- src/api/routes/reports/timeseries/index.js | 1 + src/api/routes/reports/timeseries/model.js | 8 ++++-- src/test/testReportsArchive.js | 28 +++++++++++++++++++ src/test/testReportsTimeseries.js | 32 +++++++++++++++++++++- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/api/routes/reports/timeseries/index.js b/src/api/routes/reports/timeseries/index.js index 3d32edd..92c8954 100644 --- a/src/api/routes/reports/timeseries/index.js +++ b/src/api/routes/reports/timeseries/index.js @@ -34,6 +34,7 @@ export default ({config, db, logger}) => { start: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ').required(), end: Joi.date().format('YYYY-MM-DDTHH:mm:ssZ') .min(Joi.ref('start')).required(), + city: Joi.any().valid(config.REGION_CODES), }, }), (req, res, next) => { diff --git a/src/api/routes/reports/timeseries/model.js b/src/api/routes/reports/timeseries/model.js index a50d07c..72fffdd 100644 --- a/src/api/routes/reports/timeseries/model.js +++ b/src/api/routes/reports/timeseries/model.js @@ -15,16 +15,18 @@ export default (config, db, logger) => ({ // Get all flood reports for a given city - count: (start, end) => new Promise((resolve, reject) => { + count: (start, end, city) => new Promise((resolve, reject) => { // Setup query let query = `SELECT ts, count(r.pkey) FROM generate_series($1::timestamp with time zone, $2::timestamp with time zone, '1 hour') ts LEFT JOIN cognicity.all_reports r - ON date_trunc('hour', r.created_at) = ts GROUP BY ts ORDER BY ts`; + ON date_trunc('hour', r.created_at) = ts + AND ($3 IS NULL OR tags->>'instance_region_code'=$3) + GROUP BY ts ORDER BY ts`; // Setup values - let values = [start, end]; + let values = [start, end, city]; // Execute logger.debug(query, values); diff --git a/src/test/testReportsArchive.js b/src/test/testReportsArchive.js index 5cd21d4..f4dd5f6 100644 --- a/src/test/testReportsArchive.js +++ b/src/test/testReportsArchive.js @@ -38,6 +38,34 @@ export default function(app) { }); }); + it('Can get reports in given city', function(done) { + test.httpAgent(app) + .get('/reports/archive?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700&city=jbd') + .expect(200) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + it('Catches bad city name', function(done) { + test.httpAgent(app) + .get('/reports/archive?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700&city=123') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + it('Can get reports between given timestamps as geojson', function(done) { test.httpAgent(app) .get('/reports/archive?start=2017-06-07T00:00:00%2B0700&end='+end+'&format=json&geoformat=geojson') diff --git a/src/test/testReportsTimeseries.js b/src/test/testReportsTimeseries.js index e135725..a7b1c97 100644 --- a/src/test/testReportsTimeseries.js +++ b/src/test/testReportsTimeseries.js @@ -19,7 +19,7 @@ import * as test from 'unit.js'; export default function(app) { // Reports endpoint describe('Reports Archive Endpoint', function() { - // Can get floods between given timestamps + // Can get reports between given timestamps it('Can get floods timeseries given timestamps', function(done) { test.httpAgent(app) .get('/reports/timeseries?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700') @@ -34,6 +34,36 @@ export default function(app) { }); }); + // Can get reports between given timestamps with city + it('Can get floods timeseries given timestamps', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700&city=jbd') + .expect(200) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + + // Catches bad city name + it('Catches bad city name', function(done) { + test.httpAgent(app) + .get('/reports/timeseries?start=2017-06-07T00:00:00%2B0700&end=2017-06-08T23:00:00%2B0700&city=123') + .expect(400) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) { + test.fail(err.message + ' ' + JSON.stringify(res)); + } else { + done(); + } + }); + }); + // Can catch no start parameter it('Required start parameter by default', function(done) { test.httpAgent(app) From cf691a8fd7c99fe16a0d29d27e10ed1c0572da50 Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 4 Dec 2017 15:41:48 -0500 Subject: [PATCH 26/28] added city param to /reports child endpoints --- swagger-api.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/swagger-api.json b/swagger-api.json index 2222581..9d42561 100644 --- a/swagger-api.json +++ b/swagger-api.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "version": "2017-12-04T20:19:23Z", + "version": "2017-12-04T20:41:17Z", "title": "cognicity" }, "host": "data-dev.petabencana.id", @@ -1017,6 +1017,12 @@ "required": false, "type": "string" }, + { + "name": "city", + "in": "query", + "required": false, + "type": "string" + }, { "name": "end", "in": "query", From c56214589be4d1fe6727ae187370f26d108cc7fc Mon Sep 17 00:00:00 2001 From: Matthew Berryman Date: Tue, 5 Dec 2017 11:57:32 +1100 Subject: [PATCH 27/28] swagger-api.json update --- swagger-api.json | 867 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 860 insertions(+), 7 deletions(-) diff --git a/swagger-api.json b/swagger-api.json index 9d42561..3bef6f4 100644 --- a/swagger-api.json +++ b/swagger-api.json @@ -21,6 +21,17 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "uri": "https://${stageVariables.env}.petabencana.id", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "type": "http_proxy" } } }, @@ -41,7 +52,18 @@ { "api_key": [] } - ] + ], + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "uri": "https://${stageVariables.env}.petabencana.id/cards", + "passthroughBehavior": "when_no_match", + "httpMethod": "POST", + "type": "http_proxy" + } }, "options": { "consumes": [ @@ -68,6 +90,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -97,6 +136,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -155,6 +211,47 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "400": { + "statusCode": "400", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + }, + "404": { + "statusCode": "404", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + }, + "409": { + "statusCode": "409", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + }, + "500": { + "statusCode": "500", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + }, + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "requestParameters": { + "integration.request.path.cardId": "method.request.path.cardId" + }, + "uri": "https://${stageVariables.env}.petabencana.id/cards/{cardId}", + "passthroughBehavior": "when_no_match", + "httpMethod": "ANY", + "type": "http" } } }, @@ -189,6 +286,24 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "requestParameters": { + "integration.request.path.cardId": "method.request.path.cardId", + "integration.request.header.content-type": "method.request.header.content-type" + }, + "uri": "https://${stageVariables.env}.petabencana.id/cards/{cardId}/images", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "type": "http" } }, "options": { @@ -224,6 +339,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -253,6 +385,22 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "uri": "https://${stageVariables.env}.petabencana.id/cities", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "h1la88", + "cacheKeyParameters": [ + "method.request.querystring.format", + "method.request.querystring.geoformat" + ], + "type": "http_proxy" } }, "options": { @@ -280,6 +428,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -309,6 +474,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -334,7 +516,21 @@ { "api_key": [] } - ] + ], + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "uri": "https://${stageVariables.env}.petabencana.id/feeds/qlue", + "passthroughBehavior": "when_no_match", + "httpMethod": "POST", + "type": "http" + } }, "options": { "consumes": [ @@ -361,6 +557,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -401,6 +614,31 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "requestParameters": { + "integration.request.querystring.city": "method.request.querystring.city", + "integration.request.querystring.geoformat": "method.request.querystring.geoformat", + "integration.request.querystring.format": "method.request.querystring.format" + }, + "uri": "https://${stageVariables.env}.petabencana.id/floodgauges", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "so358j", + "cacheKeyParameters": [ + "method.request.querystring.city", + "method.request.querystring.format", + "method.request.querystring.geoformat" + ], + "type": "http" } }, "options": { @@ -428,6 +666,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -457,6 +712,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -477,7 +749,26 @@ "type": "string" } ], - "responses": {} + "responses": {}, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.path.id": "method.request.path.id" + }, + "uri": "https://${stageVariables.env}.petabencana.id/floodgauges/{id}", + "passthroughBehavior": "when_no_match", + "httpMethod": "ANY", + "cacheNamespace": "p829iq", + "cacheKeyParameters": [ + "method.request.path.id", + "method.request.querystring.format" + ], + "type": "http_proxy" + } } }, "/floods": { @@ -527,6 +818,34 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Content-Type": "integration.response.header.Content-Type", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "requestParameters": { + "integration.request.querystring.city": "method.request.querystring.city", + "integration.request.querystring.geoformat": "method.request.querystring.geoformat", + "integration.request.querystring.minimum_state": "method.request.querystring.minimum_state", + "integration.request.querystring.format": "method.request.querystring.format" + }, + "uri": "https://${stageVariables.env}.petabencana.id/floods/", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "nvy9s5", + "cacheKeyParameters": [ + "method.request.querystring.city", + "method.request.querystring.format", + "method.request.querystring.geoformat", + "method.request.querystring.minimum_state" + ], + "type": "http" } }, "head": { @@ -543,6 +862,18 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } }, "options": { @@ -570,6 +901,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -599,6 +947,26 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.querystring.start": "method.request.querystring.start", + "integration.request.querystring.end": "method.request.querystring.end" + }, + "uri": "https://${stageVariables.env}.petabencana.id/reports/archive", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "bvx1ea", + "cacheKeyParameters": [ + "method.request.querystring.start", + "method.request.querystring.end" + ], + "type": "http" } }, "options": { @@ -615,6 +983,18 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -655,6 +1035,31 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "requestParameters": { + "integration.request.querystring.city": "method.request.querystring.city", + "integration.request.querystring.minimum_state": "method.request.querystring.minimum_state", + "integration.request.querystring.format": "method.request.querystring.format" + }, + "uri": "https://${stageVariables.env}.petabencana.id/floods/states", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "cxp4qo", + "cacheKeyParameters": [ + "method.request.querystring.city", + "method.request.querystring.format", + "method.request.querystring.minimum_state" + ], + "type": "http" } }, "options": { @@ -682,6 +1087,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -711,6 +1133,26 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.querystring.start": "method.request.querystring.start", + "integration.request.querystring.end": "method.request.querystring.end" + }, + "uri": "https://${stageVariables.env}.petabencana.id/reports/timeseries", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "5r93vu", + "cacheKeyParameters": [ + "method.request.querystring.end", + "method.request.querystring.start" + ], + "type": "http" } }, "options": { @@ -727,6 +1169,18 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -756,6 +1210,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -776,7 +1247,26 @@ "type": "string" } ], - "responses": {} + "responses": {}, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.path.id": "method.request.path.id" + }, + "uri": "https://${stageVariables.env}.petabencana.id/floods/{id}", + "passthroughBehavior": "when_no_match", + "httpMethod": "ANY", + "cacheNamespace": "8q9uet", + "cacheKeyParameters": [ + "method.request.path.id", + "method.request.querystring.format" + ], + "type": "http_proxy" + } } }, "/infrastructure": { @@ -805,6 +1295,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -834,6 +1341,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -866,7 +1390,28 @@ "type": "string" } ], - "responses": {} + "responses": {}, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.path.type": "method.request.path.type" + }, + "uri": "https://${stageVariables.env}.petabencana.id/infrastructure/{type}", + "passthroughBehavior": "when_no_match", + "httpMethod": "ANY", + "cacheNamespace": "qtdnlp", + "cacheKeyParameters": [ + "method.request.path.type", + "method.request.querystring.city", + "method.request.querystring.format", + "method.request.querystring.geoformat" + ], + "type": "http_proxy" + } } }, "/reports": { @@ -912,6 +1457,33 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "requestParameters": { + "integration.request.querystring.city": "method.request.querystring.city", + "integration.request.querystring.geoformat": "method.request.querystring.geoformat", + "integration.request.querystring.timeperiod": "method.request.querystring.timeperiod", + "integration.request.querystring.format": "method.request.querystring.format" + }, + "uri": "https://${stageVariables.env}.petabencana.id/reports", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "8vxlp8", + "cacheKeyParameters": [ + "method.request.querystring.city", + "method.request.querystring.geoformat", + "method.request.querystring.timeperiod", + "method.request.querystring.format" + ], + "type": "http" } }, "options": { @@ -939,6 +1511,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -986,6 +1575,32 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.querystring.city": "method.request.querystring.city", + "integration.request.querystring.start": "method.request.querystring.start", + "integration.request.querystring.geoformat": "method.request.querystring.geoformat", + "integration.request.querystring.format": "method.request.querystring.format", + "integration.request.querystring.end": "method.request.querystring.end" + }, + "uri": "https://${stageVariables.env}.petabencana.id/reports/archive", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "cvt4dg", + "cacheKeyParameters": [ + "method.request.querystring.end", + "method.request.querystring.city", + "method.request.querystring.format", + "method.request.querystring.geoformat", + "method.request.querystring.start" + ], + "type": "http" } }, "options": { @@ -1002,6 +1617,18 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -1042,6 +1669,28 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.querystring.city": "method.request.querystring.city", + "integration.request.querystring.start": "method.request.querystring.start", + "integration.request.querystring.end": "method.request.querystring.end" + }, + "uri": "https://${stageVariables.env}.petabencana.id/reports/timeseries", + "passthroughBehavior": "when_no_match", + "httpMethod": "GET", + "cacheNamespace": "jnnaak", + "cacheKeyParameters": [ + "method.request.querystring.end", + "method.request.querystring.start", + "method.request.querystring.city" + ], + "type": "http" } }, "options": { @@ -1058,6 +1707,18 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -1087,6 +1748,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } }, "x-amazon-apigateway-any-method": { @@ -1107,7 +1785,26 @@ "type": "string" } ], - "responses": {} + "responses": {}, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "requestParameters": { + "integration.request.path.id": "method.request.path.id" + }, + "uri": "https://${stageVariables.env}.petabencana.id/reports/{id}", + "passthroughBehavior": "when_no_match", + "httpMethod": "ANY", + "cacheNamespace": "5tep32", + "cacheKeyParameters": [ + "method.request.path.id", + "method.request.querystring.format" + ], + "type": "http_proxy" + } } }, "/stats": { @@ -1136,6 +1833,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -1156,6 +1870,21 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:cognicity-statistics-${stageVariables.stage}-floodedRWsSummary/invocations", + "passthroughBehavior": "when_no_match", + "httpMethod": "POST", + "contentHandling": "CONVERT_TO_TEXT", + "type": "aws_proxy" } }, "options": { @@ -1183,6 +1912,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -1203,6 +1949,21 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:cognicity-statistics-${stageVariables.stage}-floodedRegionsSummary/invocations", + "passthroughBehavior": "when_no_match", + "httpMethod": "POST", + "contentHandling": "CONVERT_TO_TEXT", + "type": "aws_proxy" } }, "options": { @@ -1230,6 +1991,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'GET,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -1245,6 +2023,18 @@ "$ref": "#/definitions/Empty" } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200" + } + }, + "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:cognicity-statistics-${stageVariables.stage}-reportsSummary/invocations", + "passthroughBehavior": "when_no_match", + "httpMethod": "POST", + "contentHandling": "CONVERT_TO_TEXT", + "type": "aws_proxy" } }, "options": { @@ -1272,6 +2062,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } }, @@ -1295,6 +2102,27 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + ".*": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Origin": "'*'" + }, + "responseTemplates": { + "text/xml": "#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))\n$errorMessageObj.message\n" + } + } + }, + "uri": "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:917524458155:function:twilio/invocations", + "passthroughBehavior": "when_no_templates", + "httpMethod": "POST", + "requestTemplates": { + "application/x-www-form-urlencoded": "{\n \"reqbody\":\"$input.path('$')\"\n}" + }, + "contentHandling": "CONVERT_TO_TEXT", + "type": "aws" } }, "options": { @@ -1322,6 +2150,23 @@ } } } + }, + "x-amazon-apigateway-integration": { + "responses": { + "default": { + "statusCode": "200", + "responseParameters": { + "method.response.header.Access-Control-Allow-Methods": "'POST,OPTIONS'", + "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'", + "method.response.header.Access-Control-Allow-Origin": "'*'" + } + } + }, + "passthroughBehavior": "when_no_match", + "requestTemplates": { + "application/json": "{\"statusCode\": 200}" + }, + "type": "mock" } } } @@ -1338,5 +2183,13 @@ "type": "object", "title": "Empty Schema" } - } + }, + "x-amazon-apigateway-binary-media-types": [ + "application/gzip", + "application/x-gzip", + "application/x-compressed", + "image/png", + "image/jpeg", + "image/gif" + ] } \ No newline at end of file From b04bc97e7e472829931e0c0b2d3401bf95cb92fe Mon Sep 17 00:00:00 2001 From: Tomas Date: Tue, 5 Dec 2017 11:17:56 -0500 Subject: [PATCH 28/28] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad86a3..b2f71fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,3 +31,4 @@ API Server for CogniCity * Added /floods/timeseries endpoint * Added /reports/timeseries endpoint * Added time window check on archive and time series endpoints +* Updated API definitions in swagger file