mirror of
https://github.com/Unleash/unleash.git
synced 2024-10-18 20:09:08 +02:00
155 lines
4.8 KiB
JavaScript
155 lines
4.8 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const memoize = require('memoizee');
|
||
|
const addonProvidersClasses = require('../addons');
|
||
|
const events = require('../event-type');
|
||
|
const { addonSchema } = require('./addon-schema');
|
||
|
const NameExistsError = require('../error/name-exists-error');
|
||
|
|
||
|
const SUPPORTED_EVENTS = Object.keys(events).map(k => events[k]);
|
||
|
|
||
|
const ADDONS_CACHE_TIME = 60 * 1000; // 60s
|
||
|
|
||
|
class AddonService {
|
||
|
constructor(
|
||
|
{ addonStore, eventStore, featureToggleStore },
|
||
|
{ getLogger },
|
||
|
tagTypeService,
|
||
|
) {
|
||
|
this.eventStore = eventStore;
|
||
|
this.addonStore = addonStore;
|
||
|
this.featureToggleStore = featureToggleStore;
|
||
|
this.getLogger = getLogger;
|
||
|
this.logger = getLogger('services/addon-service.js');
|
||
|
this.tagTypeService = tagTypeService;
|
||
|
|
||
|
this.addonProviders = addonProvidersClasses.reduce((map, Provider) => {
|
||
|
try {
|
||
|
const provider = new Provider({ getLogger });
|
||
|
// eslint-disable-next-line no-param-reassign
|
||
|
map[provider.name] = provider;
|
||
|
} finally {
|
||
|
// Do nothing
|
||
|
}
|
||
|
return map;
|
||
|
}, {});
|
||
|
if (addonStore) {
|
||
|
this.registerEventHandler();
|
||
|
}
|
||
|
|
||
|
// Memoized function
|
||
|
this.fetchAddonConfigs = memoize(
|
||
|
() => addonStore.getAll({ enabled: true }),
|
||
|
{ promise: true, maxAge: ADDONS_CACHE_TIME },
|
||
|
);
|
||
|
}
|
||
|
|
||
|
registerEventHandler() {
|
||
|
SUPPORTED_EVENTS.forEach(eventName =>
|
||
|
this.eventStore.on(eventName, this.handleEvent(eventName)),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
handleEvent(eventName) {
|
||
|
const { addonProviders } = this;
|
||
|
return event => {
|
||
|
this.fetchAddonConfigs().then(addonInstances => {
|
||
|
addonInstances
|
||
|
.filter(addon => addon.events.includes(eventName))
|
||
|
.filter(addon => addonProviders[addon.provider])
|
||
|
.forEach(addon =>
|
||
|
addonProviders[addon.provider].handleEvent(
|
||
|
event,
|
||
|
addon.parameters,
|
||
|
),
|
||
|
);
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
async getAddons() {
|
||
|
return this.addonStore.getAll();
|
||
|
}
|
||
|
|
||
|
async getAddon(id) {
|
||
|
return this.addonStore.get(id);
|
||
|
}
|
||
|
|
||
|
getProviderDefinition() {
|
||
|
const { addonProviders } = this;
|
||
|
return Object.values(addonProviders).map(p => p.definition);
|
||
|
}
|
||
|
|
||
|
async addTagTypes(providerName) {
|
||
|
const provider = this.addonProviders[providerName];
|
||
|
if (provider) {
|
||
|
const tagTypes = provider.definition.tagTypes || [];
|
||
|
const createTags = tagTypes.map(async tagType => {
|
||
|
try {
|
||
|
await this.tagTypeService.validateUnique(tagType);
|
||
|
await this.tagTypeService.createTagType(tagType);
|
||
|
} catch (err) {
|
||
|
this.logger.error(err);
|
||
|
if (!(err instanceof NameExistsError)) {
|
||
|
this.logger.error(err);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
return Promise.all(createTags);
|
||
|
}
|
||
|
return Promise.resolve();
|
||
|
}
|
||
|
|
||
|
async createAddon(data, userName) {
|
||
|
const addonConfig = await addonSchema.validateAsync(data);
|
||
|
await this.validateKnownProvider(addonConfig);
|
||
|
|
||
|
const createdAddon = await this.addonStore.insert(addonConfig);
|
||
|
await this.addTagTypes(createdAddon.provider);
|
||
|
|
||
|
this.logger.info(
|
||
|
`User ${userName} created addon ${addonConfig.provider}`,
|
||
|
);
|
||
|
|
||
|
await this.eventStore.store({
|
||
|
type: events.ADDON_CONFIG_CREATED,
|
||
|
createdBy: userName,
|
||
|
data: { provider: addonConfig.provider },
|
||
|
});
|
||
|
|
||
|
return createdAddon;
|
||
|
}
|
||
|
|
||
|
async updateAddon(id, data, userName) {
|
||
|
const addonConfig = await addonSchema.validateAsync(data);
|
||
|
await this.addonStore.update(id, addonConfig);
|
||
|
await this.eventStore.store({
|
||
|
type: events.ADDON_CONFIG_UPDATED,
|
||
|
createdBy: userName,
|
||
|
data: { id, provider: addonConfig.provider },
|
||
|
});
|
||
|
this.logger.info(`User ${userName} updated addon ${id}`);
|
||
|
}
|
||
|
|
||
|
async removeAddon(id, userName) {
|
||
|
await this.addonStore.delete(id);
|
||
|
await this.eventStore.store({
|
||
|
type: events.ADDON_CONFIG_DELETED,
|
||
|
createdBy: userName,
|
||
|
data: { id },
|
||
|
});
|
||
|
this.logger.info(`User ${userName} removed addon ${id}`);
|
||
|
}
|
||
|
|
||
|
async validateKnownProvider(config) {
|
||
|
const p = this.addonProviders[config.provider];
|
||
|
if (!p) {
|
||
|
throw new TypeError(`Unknown addon provider ${config.provider}`);
|
||
|
} else {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = AddonService;
|