diff --git a/Dockerfile b/Dockerfile index 81b7d32..b032ff0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,12 +2,12 @@ # and runs it against the specified Topcoder backend (development or # production) when container is executed. -FROM node:8.2.1 -LABEL app="tc email" version="1.0" +FROM node:6.10 +LABEL app="tc email" version="1.1" WORKDIR /opt/app COPY . . RUN npm install -RUN npm install dotenv --save +#RUN npm install dotenv --save RUN npm run lint CMD ["npm", "start"] diff --git a/README.md b/README.md index 19f49f5..1c2fad6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Dependencies -- nodejs https://nodejs.org/en/ (v8+) +- nodejs https://nodejs.org/en/ (v6+) - Heroku Toolbelt https://toolbelt.heroku.com - git - PostgreSQL 9.5 diff --git a/config/default.js b/config/default.js index 155638b..239d7fc 100644 --- a/config/default.js +++ b/config/default.js @@ -40,4 +40,8 @@ module.exports = { //in every 2 minutes will retry for failed status EMAIL_RETRY_SCHEDULE: process.env.EMAIL_RETRY_SCHEDULE || '0 */2 * * * *', + + API_CONTEXT_PATH: process.env.API_CONTEXT_PATH || '/email', + API_VERSION: process.env.API_VERSION || 'v5', + }; diff --git a/deploy.sh b/deploy.sh index ee48d4d..60f8cb6 100755 --- a/deploy.sh +++ b/deploy.sh @@ -66,6 +66,9 @@ EMAIL_PAUSE_TIME=$(eval "echo \$${ENV}_EMAIL_PAUSE_TIME") EMAIL_RETRY_SCHEDULE=$(eval "echo \"\$${ENV}_EMAIL_RETRY_SCHEDULE\"") DISABLE_LOGGING=$(eval "echo \$${ENV}_DISABLE_LOGGING") +API_CONTEXT_PATH=$(eval "echo \$${ENV}_API_CONTEXT_PATH") +API_VERSION=$(eval "echo \$${ENV}_API_VERSION") + configure_aws_cli() { aws --version aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID @@ -188,6 +191,14 @@ make_task_def(){ { "name": "DISABLE_LOGGING", "value": "%s" + }, + { + "name": "API_CONTEXT_PATH", + "value": "%s" + }, + { + "name": "API_VERSION", + "value": "%s" } ], "portMappings": [ @@ -209,7 +220,7 @@ make_task_def(){ ] }' - task_def=$(printf "$task_template" $family $AWS_ACCOUNT_ID $AWS_ECS_CONTAINER_NAME $AWS_ACCOUNT_ID $AWS_REGION $AWS_REPOSITORY $TAG $ENV $AUTH_DOMAIN $AUTH_SECRET $DATABASE_URL $EMAIL_FROM "$JWKS_URI" "$KAFKA_CLIENT_CERT" "$KAFKA_CLIENT_CERT_KEY" $KAFKA_GROUP_ID $KAFKA_URL $LOG_LEVEL $PORT $SENDGRID_API_KEY "$TEMPLATE_MAP" "$VALID_ISSUERS" $EMAIL_MAX_ERRORS $EMAIL_PAUSE_TIME "$EMAIL_RETRY_SCHEDULE" "$DISABLE_LOGGING" $PORT $PORT $AWS_ECS_CLUSTER $AWS_REGION $ENV) + task_def=$(printf "$task_template" $family $AWS_ACCOUNT_ID $AWS_ECS_CONTAINER_NAME $AWS_ACCOUNT_ID $AWS_REGION $AWS_REPOSITORY $TAG $ENV $AUTH_DOMAIN $AUTH_SECRET $DATABASE_URL $EMAIL_FROM "$JWKS_URI" "$KAFKA_CLIENT_CERT" "$KAFKA_CLIENT_CERT_KEY" $KAFKA_GROUP_ID $KAFKA_URL $LOG_LEVEL $PORT $SENDGRID_API_KEY "$TEMPLATE_MAP" "$VALID_ISSUERS" $EMAIL_MAX_ERRORS $EMAIL_PAUSE_TIME "$EMAIL_RETRY_SCHEDULE" "$DISABLE_LOGGING" "$API_CONTEXT_PATH" "$API_VERSION" $PORT $PORT $AWS_ECS_CLUSTER $AWS_REGION $ENV) } diff --git a/src/app.js b/src/app.js index c9d2f1c..06e4a1f 100644 --- a/src/app.js +++ b/src/app.js @@ -79,27 +79,27 @@ function configureKafkaConsumer(handlers) { // emailTries[topicName] += 1; //temporary disabling this feature emailModel.status = 'FAILED'; return emailModel.save().then(() => { - /* - * temporary disabling this feature as there is chance of losing message during - * unsubscribe/pausing due to simple kafka consumer - */ - /* - const currentTries = emailTries[topicName]; - if (currentTries > maxErrors) { - logger.debug(`Failed to send email. Will sleep for ${pauseTime}s`); - emailTries[topicName] = 0; - - schedule.scheduleJob(new Date(now.getTime() + pauseTime * 1000), () => { - consumer.subscribe(topic, dataHandler); - }); - - return consumer.unsubscribe(topic, partition).then(() => { - throw result.error - }); - } else { - logger.debug(`Failed to send email (retries left ${maxErrors - currentTries})`); - throw result.error; - }*/ + /* + * temporary disabling this feature as there is chance of losing message during + * unsubscribe/pausing due to simple kafka consumer + */ + /* + const currentTries = emailTries[topicName]; + if (currentTries > maxErrors) { + logger.debug(`Failed to send email. Will sleep for ${pauseTime}s`); + emailTries[topicName] = 0; + + schedule.scheduleJob(new Date(now.getTime() + pauseTime * 1000), () => { + consumer.subscribe(topic, dataHandler); + }); + + return consumer.unsubscribe(topic, partition).then(() => { + throw result.error + }); + } else { + logger.debug(`Failed to send email (retries left ${maxErrors - currentTries})`); + throw result.error; + }*/ }); } }).then(() => consumer.commitOffset({ topic, partition, offset: m.offset })) // commit offset @@ -124,9 +124,9 @@ function startKafkaConsumer(consumer, handlers, dataHandler) { return consumer .init() .then(() => Promise.each(_.keys(handlers), (topicName) => { // add back the ignored topic prefix to use full topic name - emailTries[topicName] = 0; - return consumer.subscribe(`${config.KAFKA_TOPIC_IGNORE_PREFIX || ''}${topicName}`, dataHandler); - }) + emailTries[topicName] = 0; + return consumer.subscribe(`${config.KAFKA_TOPIC_IGNORE_PREFIX || ''}${topicName}`, dataHandler); + }) ); } @@ -189,7 +189,8 @@ function start(handlers) { req.signature = `${def.controller}#${def.method}`; next(); }); - if (url !== '/email/health') { + if ((url !== '/email/health') + && (url !== `${config.API_CONTEXT_PATH}/${config.API_VERSION}/health`)) { actions.push(jwtAuth()); actions.push((req, res, next) => { if (!req.authUser) { diff --git a/src/routes.js b/src/routes.js index c8db8ef..db0aae2 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1,16 +1,40 @@ 'use strict'; -module.exports = { - '/email/templates/eventType/:name': { - get: { - controller: 'TemplateController', - method: 'eventTypes', - }, - }, - '/email/health': { - get: { - controller: 'HealthController', - method: 'health', - }, - }, +const config = require('config'); + +const routes = {}; + +const oldkeyEventType = '/email/templates/eventType/:name' +routes[oldkeyEventType] = { + get: { + controller: 'TemplateController', + method: 'eventTypes', + } +}; + +const oldkeyHealthCheck = '/email/health' +routes[oldkeyHealthCheck] = { + get: { + controller: 'HealthController', + method: 'health', + } +}; + +const keyEventType = `${config.API_CONTEXT_PATH}/${config.API_VERSION}/templates/eventType/:name`; +routes[keyEventType] = { + get: { + controller: 'TemplateController', + method: 'eventTypes', + } +}; + +const keyHealthCheck = `${config.API_CONTEXT_PATH}/${config.API_VERSION}/health`; +routes[keyHealthCheck] = { + get: { + controller: 'HealthController', + method: 'health', + } }; + + +module.exports = routes;