<commit_before>const { Router: router } = require('express');

const RedisPool = require('redis-mpool');
const cartodbRedis = require('cartodb-redis');

const windshaft = require('windshaft');

const PgConnection = require('../backends/pg_connection');
const AnalysisBackend = require('../backends/analysis');
const AnalysisStatusBackend = require('../backends/analysis-status');
const DataviewBackend = require('../backends/dataview');
const TemplateMaps = require('../backends/template_maps.js');
const PgQueryRunner = require('../backends/pg_query_runner');
const StatsBackend = require('../backends/stats');

const AuthApi = require('../api/auth_api');
const UserLimitsApi = require('../api/user_limits_api');
const OverviewsMetadataApi = require('../api/overviews_metadata_api');
const FilterStatsApi = require('../api/filter_stats_api');
const TablesExtentApi = require('../api/tables_extent_api');

const LayergroupAffectedTablesCache = require('../cache/layergroup_affected_tables');
const SurrogateKeysCache = require('../cache/surrogate_keys_cache');
const VarnishHttpCacheBackend = require('../cache/backend/varnish_http');
const FastlyCacheBackend = require('../cache/backend/fastly');
const NamedMapProviderCache = require('../cache/named_map_provider_cache');
const NamedMapsCacheEntry = require('../cache/model/named_maps_entry');

const SqlWrapMapConfigAdapter = require('../models/mapconfig/adapter/sql-wrap-mapconfig-adapter');
const MapConfigNamedLayersAdapter = require('../models/mapconfig/adapter/mapconfig-named-layers-adapter');
const MapConfigBufferSizeAdapter = require('../models/mapconfig/adapter/mapconfig-buffer-size-adapter');
const AnalysisMapConfigAdapter = require('../models/mapconfig/adapter/analysis-mapconfig-adapter');
const MapConfigOverviewsAdapter = require('../models/mapconfig/adapter/mapconfig-overviews-adapter');
const TurboCartoAdapter = require('../models/mapconfig/adapter/turbo-carto-adapter');
const DataviewsWidgetsAdapter = require('../models/mapconfig/adapter/dataviews-widgets-adapter');
const AggregationMapConfigAdapter = require('../models/mapconfig/adapter/aggregation-mapconfig-adapter');
const MapConfigAdapter = require('../models/mapconfig/adapter');

const ResourceLocator = require('../models/resource-locator');
const LayergroupMetadata = require('../utils/layergroup-metadata');
const RendererStatsReporter = require('../stats/reporter/renderer');

const AnalysisLayergroupController = require('./layergroup/analysis');
const AttributesLayergroupController = require('./layergroup/attributes');
const DataviewLayergroupController = require('./layergroup/dataview');
const PreviewLayergroupController = require('./layergroup/preview');
const TileLayergroupController = require('./layergroup/tile');

const AnonymousMapController = require('./map/anonymous');
const NamedMapController = require('./map/named');

const AdminTemplateController = require('./template/admin');
const PreviewTemplateController = require('./template/preview');
const TileTemplateController = require('./template/tile');

const AnalysesController = require('./analyses');

const ServerInfoController = require('./server-info');

module.exports = class ControllersFactory {
    constructor ({ serverOptions, environmentOptions }) {
        const redisOptions = Object.assign({}, environmentOptions.redis, {
            name: 'windshaft-server',
            unwatchOnRelease: false,
            noReadyCheck: true
        });

        const redisPool = new RedisPool(redisOptions);

        redisPool.on('status', function(status) {
            var keyPrefix = 'windshaft.redis-pool.' + status.name + '.db' + status.db + '.';
            global.statsClient.gauge(keyPrefix + 'count', status.count);
            global.statsClient.gauge(keyPrefix + 'unused', status.unused);
            global.statsClient.gauge(keyPrefix + 'waiting', status.waiting);
        });

        const metadataBackend = cartodbRedis({ pool: redisPool });
        const pgConnection = new PgConnection(metadataBackend);

        const mapStore = new windshaft.storage.MapStore({
            pool: redisPool,
            expire_time: serverOptions.grainstore.default_layergroup_ttl
        });

        const rendererFactory = createRendererFactory({ redisPool, serverOptions, environmentOptions });

        const rendererCacheOpts = Object.assign({}, serverOptions.renderCache || {}, {
            ttl: 60000, // 60 seconds TTL by default
            statsInterval: 60000 // reports stats every milliseconds defined here
        });
        const rendererCache = new windshaft.cache.RendererCache(rendererFactory, rendererCacheOpts);
        const rendererStatsReporter = new RendererStatsReporter(rendererCache, rendererCacheOpts.statsInterval);
        rendererStatsReporter.start();

        const tileBackend = new windshaft.backend.Tile(rendererCache);
        const attributesBackend = new windshaft.backend.Attributes();
        const previewBackend = new windshaft.backend.Preview(rendererCache);
        const mapValidatorBackend = new windshaft.backend.MapValidator(tileBackend, attributesBackend);
        const mapBackend = new windshaft.backend.Map(rendererCache, mapStore, mapValidatorBackend);

        const surrogateKeysCacheBackends = createSurrogateKeysCacheBackends(serverOptions);
        const surrogateKeysCache = new SurrogateKeysCache(surrogateKeysCacheBackends);
        const templateMaps = createTemplateMaps({ redisPool, surrogateKeysCache });

        const analysisStatusBackend = new AnalysisStatusBackend();
        const analysisBackend = new AnalysisBackend(metadataBackend, serverOptions.analysis);
        const dataviewBackend = new DataviewBackend(analysisBackend);
        const statsBackend = new StatsBackend();

        const userLimitsApi = new UserLimitsApi(metadataBackend, {
            limits: {
                cacheOnTimeout: serverOptions.renderer.mapnik.limits.cacheOnTimeout || false,
                render: serverOptions.renderer.mapnik.limits.render || 0,
                rateLimitsEnabled: global.environment.enabledFeatures.rateLimitsEnabled
            }
        });
        const authApi = new AuthApi(pgConnection, metadataBackend, mapStore, templateMaps);

        const layergroupAffectedTablesCache = new LayergroupAffectedTablesCache();<commit_msg>Respect default values with object.assign<commit_after>const { Router: router } = require('express');

const RedisPool = require('redis-mpool');
const cartodbRedis = require('cartodb-redis');

const windshaft = require('windshaft');

const PgConnection = require('../backends/pg_connection');
const AnalysisBackend = require('../backends/analysis');
const AnalysisStatusBackend = require('../backends/analysis-status');
const DataviewBackend = require('../backends/dataview');
const TemplateMaps = require('../backends/template_maps.js');
const PgQueryRunner = require('../backends/pg_query_runner');
const StatsBackend = require('../backends/stats');

const AuthApi = require('../api/auth_api');
const UserLimitsApi = require('../api/user_limits_api');
const OverviewsMetadataApi = require('../api/overviews_metadata_api');
const FilterStatsApi = require('../api/filter_stats_api');
const TablesExtentApi = require('../api/tables_extent_api');

const LayergroupAffectedTablesCache = require('../cache/layergroup_affected_tables');
const SurrogateKeysCache = require('../cache/surrogate_keys_cache');
const VarnishHttpCacheBackend = require('../cache/backend/varnish_http');
const FastlyCacheBackend = require('../cache/backend/fastly');
const NamedMapProviderCache = require('../cache/named_map_provider_cache');
const NamedMapsCacheEntry = require('../cache/model/named_maps_entry');

const SqlWrapMapConfigAdapter = require('../models/mapconfig/adapter/sql-wrap-mapconfig-adapter');
const MapConfigNamedLayersAdapter = require('../models/mapconfig/adapter/mapconfig-named-layers-adapter');
const MapConfigBufferSizeAdapter = require('../models/mapconfig/adapter/mapconfig-buffer-size-adapter');
const AnalysisMapConfigAdapter = require('../models/mapconfig/adapter/analysis-mapconfig-adapter');
const MapConfigOverviewsAdapter = require('../models/mapconfig/adapter/mapconfig-overviews-adapter');
const TurboCartoAdapter = require('../models/mapconfig/adapter/turbo-carto-adapter');
const DataviewsWidgetsAdapter = require('../models/mapconfig/adapter/dataviews-widgets-adapter');
const AggregationMapConfigAdapter = require('../models/mapconfig/adapter/aggregation-mapconfig-adapter');
const MapConfigAdapter = require('../models/mapconfig/adapter');

const ResourceLocator = require('../models/resource-locator');
const LayergroupMetadata = require('../utils/layergroup-metadata');
const RendererStatsReporter = require('../stats/reporter/renderer');

const AnalysisLayergroupController = require('./layergroup/analysis');
const AttributesLayergroupController = require('./layergroup/attributes');
const DataviewLayergroupController = require('./layergroup/dataview');
const PreviewLayergroupController = require('./layergroup/preview');
const TileLayergroupController = require('./layergroup/tile');

const AnonymousMapController = require('./map/anonymous');
const NamedMapController = require('./map/named');

const AdminTemplateController = require('./template/admin');
const PreviewTemplateController = require('./template/preview');
const TileTemplateController = require('./template/tile');

const AnalysesController = require('./analyses');

const ServerInfoController = require('./server-info');

module.exports = class ControllersFactory {
    constructor ({ serverOptions, environmentOptions }) {
        const redisOptions = Object.assign({
            name: 'windshaft-server',
            unwatchOnRelease: false,
            noReadyCheck: true
        }, environmentOptions.redis);

        const redisPool = new RedisPool(redisOptions);

        redisPool.on('status', function(status) {
            var keyPrefix = 'windshaft.redis-pool.' + status.name + '.db' + status.db + '.';
            global.statsClient.gauge(keyPrefix + 'count', status.count);
            global.statsClient.gauge(keyPrefix + 'unused', status.unused);
            global.statsClient.gauge(keyPrefix + 'waiting', status.waiting);
        });

        const metadataBackend = cartodbRedis({ pool: redisPool });
        const pgConnection = new PgConnection(metadataBackend);

        const mapStore = new windshaft.storage.MapStore({
            pool: redisPool,
            expire_time: serverOptions.grainstore.default_layergroup_ttl
        });

        const rendererFactory = createRendererFactory({ redisPool, serverOptions, environmentOptions });

        const rendererCacheOpts = Object.assign({
            ttl: 60000, // 60 seconds TTL by default
            statsInterval: 60000 // reports stats every milliseconds defined here
        }, serverOptions.renderCache || {});

        const rendererCache = new windshaft.cache.RendererCache(rendererFactory, rendererCacheOpts);
        const rendererStatsReporter = new RendererStatsReporter(rendererCache, rendererCacheOpts.statsInterval);
        rendererStatsReporter.start();

        const tileBackend = new windshaft.backend.Tile(rendererCache);
        const attributesBackend = new windshaft.backend.Attributes();
        const previewBackend = new windshaft.backend.Preview(rendererCache);
        const mapValidatorBackend = new windshaft.backend.MapValidator(tileBackend, attributesBackend);
        const mapBackend = new windshaft.backend.Map(rendererCache, mapStore, mapValidatorBackend);

        const surrogateKeysCacheBackends = createSurrogateKeysCacheBackends(serverOptions);
        const surrogateKeysCache = new SurrogateKeysCache(surrogateKeysCacheBackends);
        const templateMaps = createTemplateMaps({ redisPool, surrogateKeysCache });

        const analysisStatusBackend = new AnalysisStatusBackend();
        const analysisBackend = new AnalysisBackend(metadataBackend, serverOptions.analysis);
        const dataviewBackend = new DataviewBackend(analysisBackend);
        const statsBackend = new StatsBackend();

        const userLimitsApi = new UserLimitsApi(metadataBackend, {
            limits: {
                cacheOnTimeout: serverOptions.renderer.mapnik.limits.cacheOnTimeout || false,
                render: serverOptions.renderer.mapnik.limits.render || 0,
                rateLimitsEnabled: global.environment.enabledFeatures.rateLimitsEnabled
            }
        });
        const authApi = new AuthApi(pgConnection, metadataBackend, mapStore, templateMaps);

        const layergroupAffectedTablesCache = new LayergroupAffectedTablesCache();
{'fraction_non_alphanumeric': 0.11870021295054815, 'fraction_numerical': 0.002050634908115782, 'mean_word_length': 4.51064754454585, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4021382', 'n_tokens_mistral': 3310, 'n_tokens_neox': 3266, 'n_words': 613}