|
|
|
const request = require('superagent');
|
|
|
|
const _ = require('lodash');
|
|
|
|
const isDNT = require( '../helper/logging' ).isDNT;
|
|
|
|
|
|
|
|
const logger = require( 'pelias-logger' ).get( 'placeholder' );
|
|
|
|
|
|
|
|
const ServiceConfiguration = require('./configurations/ServiceConfiguration');
|
|
|
|
|
|
|
|
// superagent doesn't exposed the assembled GET request, so synthesize it
|
|
|
|
function synthesizeUrl(serviceConfig, req) {
|
|
|
|
const parameters = _.map(serviceConfig.getParameters(), (value, key) => {
|
|
|
|
return `${key}=${value}`;
|
|
|
|
}).join('&');
|
|
|
|
|
|
|
|
if (parameters) {
|
|
|
|
return encodeURI(`${serviceConfig.getUrl(req)}?${parameters}`);
|
|
|
|
} else {
|
|
|
|
return serviceConfig.getUrl(req);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = function setup(serviceConfig) {
|
|
|
|
if (!(serviceConfig instanceof ServiceConfiguration)) {
|
|
|
|
throw Error('serviceConfig should be an instance of ServiceConfiguration');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_.isEmpty(serviceConfig.getBaseUrl())) {
|
|
|
|
logger.warn(`${serviceConfig.getName()} service disabled`);
|
|
|
|
|
|
|
|
return (req, callback) => {
|
|
|
|
// respond with an error to any call
|
|
|
|
callback(`${serviceConfig.getName()} service disabled`);
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.info(`using ${serviceConfig.getName()} service at ${serviceConfig.getBaseUrl()}`);
|
|
|
|
return (req, callback) => {
|
|
|
|
const headers = serviceConfig.getHeaders(req) || {};
|
|
|
|
const do_not_track = isDNT(req);
|
|
|
|
|
|
|
|
if (do_not_track) {
|
|
|
|
headers.dnt = '1';
|
|
|
|
}
|
|
|
|
|
|
|
|
request
|
|
|
|
.get(serviceConfig.getUrl(req))
|
|
|
|
.set(headers)
|
|
|
|
.timeout(serviceConfig.getTimeout())
|
|
|
|
.retry(serviceConfig.getRetries())
|
|
|
|
.accept('json')
|
|
|
|
.query(serviceConfig.getParameters(req))
|
|
|
|
.on('error', (err) => {
|
|
|
|
if (err.status) {
|
|
|
|
// first handle case where a non-200 was returned
|
|
|
|
if (do_not_track) {
|
|
|
|
logger.error(`${serviceConfig.getBaseUrl()} [do_not_track] returned status ${err.status}: ${err.response.text}`);
|
|
|
|
return callback(`${serviceConfig.getBaseUrl()} [do_not_track] returned status ${err.status}: ${err.response.text}`);
|
|
|
|
} else {
|
|
|
|
logger.error(`${synthesizeUrl(serviceConfig, req)} returned status ${err.status}: ${err.response.text}`);
|
|
|
|
return callback(`${synthesizeUrl(serviceConfig, req)} returned status ${err.status}: ${err.response.text}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle case that something catastrophic happened while contacting the server
|
|
|
|
if (do_not_track) {
|
|
|
|
logger.error(`${serviceConfig.getBaseUrl()} [do_not_track]: ${JSON.stringify(err)}`);
|
|
|
|
return callback(err);
|
|
|
|
} else {
|
|
|
|
logger.error(`${serviceConfig.getUrl(req)}: ${JSON.stringify(err)}`);
|
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
.end((err, response) => {
|
|
|
|
// bail early if there's an error (shouldn't happen since it was already handled above)
|
|
|
|
if (err) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if json was returned then just return it
|
|
|
|
if (response.type === 'application/json') {
|
|
|
|
return callback(null, response.body);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (do_not_track) {
|
|
|
|
logger.error(`${serviceConfig.getBaseUrl()} [do_not_track] could not parse response: ${response.text}`);
|
|
|
|
return callback(`${serviceConfig.getBaseUrl()} [do_not_track] could not parse response: ${response.text}`);
|
|
|
|
} else {
|
|
|
|
logger.error(`${synthesizeUrl(serviceConfig, req)} could not parse response: ${response.text}`);
|
|
|
|
return callback(`${synthesizeUrl(serviceConfig, req)} could not parse response: ${response.text}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|