2018-10-23 23:45:42 +08:00
|
|
|
'use strict';
|
|
|
|
|
2018-04-03 01:02:31 +08:00
|
|
|
const _ = require('underscore');
|
2019-03-29 22:30:29 +08:00
|
|
|
const semver = require('semver');
|
2018-04-03 19:21:41 +08:00
|
|
|
const express = require('express');
|
2018-04-04 01:08:56 +08:00
|
|
|
const windshaft = require('windshaft');
|
|
|
|
const { mapnik } = windshaft;
|
2015-07-05 02:41:22 +08:00
|
|
|
|
2018-04-03 19:21:41 +08:00
|
|
|
const jsonReplacer = require('./utils/json-replacer');
|
|
|
|
|
2018-04-09 22:18:30 +08:00
|
|
|
const ApiRouter = require('./api/api-router');
|
|
|
|
const ServerInfoController = require('./server-info-controller');
|
2018-03-29 01:58:30 +08:00
|
|
|
|
2018-04-03 19:21:41 +08:00
|
|
|
const StatsClient = require('./stats/client');
|
2015-07-05 05:09:00 +08:00
|
|
|
|
2018-04-03 01:02:31 +08:00
|
|
|
module.exports = function createServer (serverOptions) {
|
2019-10-02 01:34:03 +08:00
|
|
|
if (!serverOptions.hasOwnProperty('routes')) {
|
|
|
|
throw new Error('Must initialise server with "routes" as base paths configuration');
|
|
|
|
}
|
2015-07-05 02:41:22 +08:00
|
|
|
|
2018-04-03 01:02:31 +08:00
|
|
|
// Make stats client globally accessible
|
|
|
|
global.statsClient = StatsClient.getInstance(serverOptions.statsd);
|
2015-07-05 02:41:22 +08:00
|
|
|
|
|
|
|
serverOptions.grainstore.mapnik_version = mapnikVersion(serverOptions);
|
|
|
|
|
|
|
|
bootstrapFonts(serverOptions);
|
|
|
|
|
2018-04-03 19:21:41 +08:00
|
|
|
const app = express();
|
2018-03-29 01:37:31 +08:00
|
|
|
|
2018-04-03 19:21:41 +08:00
|
|
|
app.enable('jsonp callback');
|
|
|
|
app.disable('x-powered-by');
|
|
|
|
app.disable('etag');
|
|
|
|
app.set('json replacer', jsonReplacer());
|
2018-04-03 18:26:35 +08:00
|
|
|
|
2018-04-06 01:42:20 +08:00
|
|
|
const apiRouter = new ApiRouter({ serverOptions, environmentOptions: global.environment });
|
2019-10-04 18:35:12 +08:00
|
|
|
|
|
|
|
// TODO: remove it before releasing next major version
|
|
|
|
if (!Array.isArray(serverOptions.routes.api)) {
|
|
|
|
serverOptions.routes.api = [ serverOptions.routes.api ];
|
|
|
|
}
|
|
|
|
|
2019-10-04 18:22:23 +08:00
|
|
|
apiRouter.route(app, serverOptions.routes.api);
|
2018-04-04 01:16:37 +08:00
|
|
|
|
2018-04-04 01:08:56 +08:00
|
|
|
const versions = getAndValidateVersions(serverOptions);
|
2018-04-04 01:16:37 +08:00
|
|
|
|
2018-04-04 21:52:54 +08:00
|
|
|
const serverInfoController = new ServerInfoController(versions);
|
2019-10-04 18:22:23 +08:00
|
|
|
serverInfoController.route(app);
|
2017-09-21 17:46:31 +08:00
|
|
|
|
2015-07-05 02:41:22 +08:00
|
|
|
return app;
|
|
|
|
};
|
|
|
|
|
|
|
|
function bootstrapFonts(opts) {
|
|
|
|
// Set carto renderer configuration for MMLStore
|
|
|
|
opts.grainstore.carto_env = opts.grainstore.carto_env || {};
|
|
|
|
var cenv = opts.grainstore.carto_env;
|
|
|
|
cenv.validation_data = cenv.validation_data || {};
|
|
|
|
if ( ! cenv.validation_data.fonts ) {
|
|
|
|
mapnik.register_system_fonts();
|
|
|
|
mapnik.register_default_fonts();
|
|
|
|
cenv.validation_data.fonts = _.keys(mapnik.fontFiles());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapnikVersion(opts) {
|
|
|
|
return opts.grainstore.mapnik_version || mapnik.versions.mapnik;
|
|
|
|
}
|
2018-04-04 01:08:56 +08:00
|
|
|
|
|
|
|
function getAndValidateVersions(options) {
|
2018-10-24 00:20:11 +08:00
|
|
|
var warn = console.warn.bind(console); // jshint ignore:line
|
2018-04-04 01:08:56 +08:00
|
|
|
|
2019-10-07 15:40:50 +08:00
|
|
|
var packageDefinition = require('../package.json');
|
2018-04-04 01:08:56 +08:00
|
|
|
|
|
|
|
var declaredDependencies = packageDefinition.dependencies || {};
|
|
|
|
var installedDependenciesVersions = {
|
|
|
|
camshaft: require('camshaft').version,
|
|
|
|
grainstore: windshaft.grainstore.version(),
|
|
|
|
mapnik: windshaft.mapnik.versions.mapnik,
|
|
|
|
node_mapnik: windshaft.mapnik.version,
|
|
|
|
'turbo-carto': require('turbo-carto').version,
|
|
|
|
windshaft: windshaft.version,
|
|
|
|
windshaft_cartodb: packageDefinition.version
|
|
|
|
};
|
|
|
|
|
2019-09-12 19:28:33 +08:00
|
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
|
|
var dependenciesToValidate = ['camshaft', 'turbo-carto', 'windshaft'];
|
|
|
|
dependenciesToValidate.forEach(function(depName) {
|
|
|
|
var declaredDependencyVersion = declaredDependencies[depName];
|
|
|
|
var installedDependencyVersion = installedDependenciesVersions[depName];
|
|
|
|
if (!semver.satisfies(installedDependencyVersion,declaredDependencyVersion)) {
|
|
|
|
warn(`Dependency="${depName}" installed version="${installedDependencyVersion}" does ` +
|
|
|
|
`not match declared version="${declaredDependencyVersion}". Check your installation.`);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Be nice and warn if configured mapnik version is != installed mapnik version
|
|
|
|
if (windshaft.mapnik.versions.mapnik !== options.grainstore.mapnik_version) {
|
|
|
|
warn('WARNING: detected mapnik version (' + windshaft.mapnik.versions.mapnik + ')' +
|
|
|
|
' != configured mapnik version (' + options.grainstore.mapnik_version + ')');
|
2018-04-04 01:08:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return installedDependenciesVersions;
|
|
|
|
}
|