You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

100 lines
3.5 KiB

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}`);
}
});
};
};