Added more explicit adapter config syntax

refs https://github.com/TryGhost/Toolbox/issues/384

- Existing adapter config was based on the notion there can only be one configuration per one adapter class. With adapter cache now allowing instantiating multiple adapter instances with the same base class it opened up a possibility to have shared configuration for a base class and then extend/override it in "feature" configurations (see tests in this commit for specific examples)
This commit is contained in:
Naz 2022-09-06 14:30:18 +08:00
parent 37dd187fe6
commit 1fc8c8d671
No known key found for this signature in database
2 changed files with 126 additions and 2 deletions

View File

@ -5,10 +5,20 @@ module.exports = function resolveAdapterOptions(name, adapterServiceConfig) {
let adapterName;
let adapterConfig;
// CASE: load resource-specific adapter when there is an adapter feature name specified as well as custom feature config
if (feature && adapterSettings[feature] && adapterSettings[adapterSettings[feature]]) {
const hasFeatureConfig = feature && adapterSettings[feature];
if (hasFeatureConfig && adapterSettings[adapterSettings[feature]]) {
// CASE: load resource-specific adapter when there is an adapter feature
// name (String) specified as well as custom feature config
adapterName = adapterSettings[feature];
adapterConfig = adapterSettings[adapterName];
} else if (hasFeatureConfig && adapterSettings[feature].adapter) {
// CASE: load resource-specific adapter when there is an adapter feature
// name (Object) specified as well as custom feature config
adapterName = adapterSettings[feature].adapter;
const commonAdapterConfig = {...adapterSettings[adapterName]};
const featureAdapterConfig = {...adapterSettings[feature]};
delete featureAdapterConfig.adapter;
adapterConfig = {...commonAdapterConfig, ...featureAdapterConfig};
} else {
adapterName = adapterSettings.active;
adapterConfig = adapterSettings[adapterName];

View File

@ -3,6 +3,22 @@ const should = require('should');
const resolveAdapterOptions = require('../../../../../core/server/services/adapter-manager/options-resolver');
describe('Adapter Manager: options resolver', function () {
it('creates empty configs for unknown adapter with a default (active) instance', function () {
const name = 'cache:images';
const adapterServiceConfig = {
cache: {
active: 'Memory'
}
};
const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(name, adapterServiceConfig);
adapterType.should.equal('cache');
adapterName.should.equal('Memory');
should.equal(adapterConfig, undefined);
});
it('returns default adapter configuration', function () {
const name = 'storage';
const adapterServiceConfig = {
@ -71,4 +87,102 @@ describe('Adapter Manager: options resolver', function () {
custom: 'configValue'
});
});
it('combines configurations from shared adapter and feature adapter instances', function () {
const primaryAdapterName = 'cache:images';
const secondaryAdapterName = 'cache:settings';
const adapterServiceConfig = {
cache: {
Redis: {
commonConfigValue: 'common_config_value'
},
images: {
adapter: 'Redis',
adapterConfigValue: 'images_redis_value'
},
settings: {
adapter: 'Redis',
adapterConfigValue: 'settings_redis_value'
}
}
};
const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(primaryAdapterName, adapterServiceConfig);
adapterType.should.equal('cache');
adapterName.should.equal('Redis');
adapterConfig.should.deepEqual({
commonConfigValue: 'common_config_value',
adapterConfigValue: 'images_redis_value'
});
const {adapterType: secondAdapterType, adapterName: secondAdapterName, adapterConfig: secondAdapterConfig} = resolveAdapterOptions(secondaryAdapterName, adapterServiceConfig);
secondAdapterType.should.equal('cache');
secondAdapterName.should.equal('Redis');
secondAdapterConfig.should.deepEqual({
commonConfigValue: 'common_config_value',
adapterConfigValue: 'settings_redis_value'
});
});
it('combines empty configuration from shared adapter and feature adapter instances', function () {
const primaryAdapterName = 'cache:images';
const secondaryAdapterName = 'cache:settings';
const adapterServiceConfig = {
cache: {
images: {
adapter: 'Redis',
adapterConfigValue: 'images_redis_value'
},
settings: {
adapter: 'Redis',
adapterConfigValue: 'settings_redis_value'
}
}
};
const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(primaryAdapterName, adapterServiceConfig);
adapterType.should.equal('cache');
adapterName.should.equal('Redis');
adapterConfig.should.deepEqual({
adapterConfigValue: 'images_redis_value'
});
const {adapterType: secondAdapterType, adapterName: secondAdapterName, adapterConfig: secondAdapterConfig} = resolveAdapterOptions(secondaryAdapterName, adapterServiceConfig);
secondAdapterType.should.equal('cache');
secondAdapterName.should.equal('Redis');
secondAdapterConfig.should.deepEqual({
adapterConfigValue: 'settings_redis_value'
});
});
it('gives priority to a feature config over a common adapter config', function () {
const primaryAdapterName = 'cache:images';
const adapterServiceConfig = {
cache: {
Redis: {
commonConfigValue: 'common_config_value',
overrideMe: 'common_value'
},
images: {
adapter: 'Redis',
adapterConfigValue: 'images_redis_value',
overrideMe: 'images_override'
}
}
};
const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(primaryAdapterName, adapterServiceConfig);
adapterType.should.equal('cache');
adapterName.should.equal('Redis');
adapterConfig.should.deepEqual({
commonConfigValue: 'common_config_value',
adapterConfigValue: 'images_redis_value',
overrideMe: 'images_override'
});
});
});