Skip to content
This repository has been archived by the owner on Feb 14, 2022. It is now read-only.

Commit

Permalink
Import (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
yoanm committed Feb 26, 2017
1 parent 01204b8 commit ec55bf7
Show file tree
Hide file tree
Showing 35 changed files with 1,625 additions and 267 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
},
"extends": "google",
"rules": {
"no-use-before-define": 0,
"indent": [2,4, { "SwitchCase": 1 }],
"camelcase": ["error"],
"max-len": [1, 121],
Expand All @@ -17,6 +18,7 @@
}]
},
"env": {
"node": true
"node": true,
"es6": true
}
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ log
config/local.json

# BUILD
coverage
build
2 changes: 1 addition & 1 deletion .scrutinizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ build:
-
command: 'npm run coverage-clover'
coverage:
file: 'coverage/clover.xml'
file: 'build/coverage.clover.xml'
format: 'clover'
11 changes: 11 additions & 0 deletions config/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"debug": false,
"logger": {
"path": "log",
"level": "info"
},
"server": {
"host": "localhost",
"port": 8000
}
}
6 changes: 6 additions & 0 deletions config/dev.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"debug": true,
"logger": {
"level": "debug"
}
}
3 changes: 3 additions & 0 deletions config/local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
/** Add here a custom config specific to local machine. File is not tracked by git */
}
6 changes: 6 additions & 0 deletions config/prod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"debug": false,
"logger": {
"level": "error"
}
}
59 changes: 59 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"use strict";

if (['dev', 'prod'].indexOf(process.env.NODE_ENV)) {
console.warn(`Undefined node environment "${process.env.NODE_ENV}", fallback to dev !`);
process.env.NODE_ENV = 'dev';
}

const onDeath = require('death')({
SIGTERM: false,
SIGQUIT: false
});

const logger = require('./lib/logger');
const taskLoggerFactory = require('./lib/logger/taskLogger');
const server = require('./lib/server');
const pkg = require('./package.json');
const NestedError = require('nested-error-stacks');

const appName = pkg.name;
const taskLogger = taskLoggerFactory(appName);

onDeath(signal => {
let exitCode = 0;
if (signal === 'SIGTERM' || signal === 'SIGQUIT') {
exitCode = 1;
}
cleanAndExit(exitCode);
});

process.on('unhandledRejection', (reason, p) => {
console.warn('Unhandled Rejection at: Promise', p, 'reason:', reason);

return cleanAndExit(1);
});

const cleanAndExit = (exitCode = 0) => {
taskLogger.stopping();
const _exit = error => {
if (error instanceof Error) {
console.error(error);
}
taskLogger.stopped();
process.exit(exitCode);
};

return server.stop()
.then(_exit, _exit);
};

taskLogger.starting();

server.start()
.then(() => taskLogger.started())
.catch(error => {
const newError = new NestedError(`Exit ${appName} after an error at initialisation`, error);
logger.error(newError.stack);

return Promise.reject(cleanAndExit(1));
});
82 changes: 82 additions & 0 deletions lib/client/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
"use strict";

const requestPromise = require('request-promise-native');
const pkg = require('../../package.json');
const logger = require('../logger/taskLogger')('Client');
const Response = require('../model/Response');

const defaultOptionList = {
headers: {'User-Agent': pkg.name},
json: true,
simple: false,
resolveWithFullResponse: true
};

/**
* @param {Request} request
*
* @returns {Promise<Response|Error>}
*/
module.exports = request => {
const optionList = Object.assign(
{},
defaultOptionList,
{
uri: request.getUri(),
method: request.getMethod(),
headers: Object.assign({}, defaultOptionList.headers, request.getHeaders()),
json: request.isJson()
}
);

if (request.getForm() && Object.keys(request.getForm()).length > 0) {
optionList.form = request.getForm();
}
if (request.getPayload() && Object.keys(request.getPayload()).length > 0) {
optionList.body = request.getPayload();
} else {
optionList.body = optionList.json === true ? {} : '';
}
if (request.getQueryString() && Object.keys(request.getQueryString()).length > 0) {
optionList.qs = request.getQueryString();
} else {
optionList.qs = optionList.json === true ? {} : null;
}

const transformResponseToResponseObject = response => {
return new Response(
response.body,
response.statusCode,
response.headers,
request
);
};

const transformErrorToResponseObject = error => {
logger.debug('[Error] Conversion to Response.', {options: optionList});

return Promise.resolve(new Response(
optionList.json === true ? {
error: error.error.code,
message: error.message
} : `${error.error.code} ${error.message}`,
500,
{},
request
));
};

const logResponseObject = response => {
logger.debug('[Reponse]', {response: response, options: optionList});

return response;
};

logger.debug('[Request]', {options: optionList});

const transform = requestPromise(optionList)
.then(transformResponseToResponseObject, transformErrorToResponseObject);

return transform
.then(logResponseObject);
};
7 changes: 7 additions & 0 deletions lib/handlers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"use strict";

const send = require('./send');

module.exports = {
send
};
37 changes: 37 additions & 0 deletions lib/handlers/send.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"use strict";

const client = require('../client');
const logger = require('../logger');
const Request = require('../model/Request');

/**
* @param {Request} request
*
* @returns {Promise<Response[]>}
*/
module.exports = request => {
return new Promise(resolve => {
const requestStack = [];

request.getPayload().forEach(request => {
const clientRequest = new Request(
request.uri,
request.method,
request.payload,
request.queryString,
request.headers,
request.form,
request.json
);
requestStack.push(
client(clientRequest)
.catch(error => {/* $lab:coverage:off$ */
logger.error(error.stack);
return Promise.reject(error);
})/* $lab:coverage:on$ */
);
});

resolve(Promise.all(requestStack));
});
};
63 changes: 63 additions & 0 deletions lib/logger/EnhancedLogger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"use strict";

const Logger = require('./Logger');
const Response = require('../model/Response');
const Request = require('../model/Request');
const transformers = require('./transformers');

const normalize = (meta = {}, level = 0) => {
if (level++ < 5) {
if (Array.isArray(meta)) {
return meta.map(metaData => normalize(metaData, level));
} else if (meta instanceof Request) {
return transformers.request(meta);
} else if (meta instanceof Response) {
return transformers.response(meta);
} else if (meta instanceof Object) {
const newObject = {};
for (let metaKey in meta) {
if (meta.hasOwnProperty(metaKey)) {
newObject[metaKey] = normalize(meta[metaKey], level);
}
}

return newObject;
}
}

return meta;
};

class EnhancedLogger extends Logger {
/**
* @public
* @param {Object} request
*
* @returns {Object}
*/
formatRequest(request) {
return {
url: request.url,
query: request.query,
path: request.path,
method: request.method,
mime: request.mime,
params: request.paramsArray,
payload: request.payload
};
}

/**
* @inheritDoc
*/
normalizeMeta(meta = {}) {
return normalize(meta);
}

}

/**
* @return {TaskLogger} Logger for a task
*/
module.exports = EnhancedLogger;

0 comments on commit ec55bf7

Please sign in to comment.