1
0
mirror of https://github.com/Unleash/unleash.git synced 2024-10-18 20:09:08 +02:00
unleash.unleash/lib/state-service.js

123 lines
3.6 KiB
JavaScript
Raw Normal View History

'use strict';
2020-01-02 19:23:52 +01:00
const joi = require('@hapi/joi');
const fs = require('fs');
const mime = require('mime');
const YAML = require('js-yaml');
const { featureShema } = require('./routes/admin-api/feature-schema');
const strategySchema = require('./routes/admin-api/strategy-schema');
const {
FEATURE_IMPORT,
DROP_FEATURES,
STRATEGY_IMPORT,
DROP_STRATEGIES,
} = require('./event-type');
const dataSchema = joi.object().keys({
version: joi.number(),
features: joi
.array()
.optional()
.items(featureShema),
strategies: joi
.array()
.optional()
.items(strategySchema),
});
function readFile(file) {
return new Promise((resolve, reject) =>
fs.readFile(file, (err, v) => (err ? reject(err) : resolve(v))),
);
}
function parseFile(file, data) {
return mime.getType(file) === 'text/yaml'
? YAML.safeLoad(data)
: JSON.parse(data);
}
class StateService {
constructor(config) {
this.config = config;
this.logger = config.getLogger('state-service.js');
}
importFile({ file, dropBeforeImport, userName }) {
return readFile(file)
.then(data => parseFile(file, data))
.then(data => this.import({ data, userName, dropBeforeImport }));
}
async import({ data, userName, dropBeforeImport }) {
const { eventStore } = this.config.stores;
2020-01-02 19:23:52 +01:00
const importData = await dataSchema.validateAsync(data);
if (importData.features) {
this.logger.info(
`Importing ${importData.features.length} features`,
);
if (dropBeforeImport) {
this.logger.info(`Dropping existing features`);
await eventStore.store({
type: DROP_FEATURES,
createdBy: userName,
data: { name: 'all-features' },
});
}
await Promise.all(
importData.features.map(feature =>
eventStore.store({
type: FEATURE_IMPORT,
createdBy: userName,
data: feature,
}),
),
);
}
if (importData.strategies) {
this.logger.info(
`Importing ${importData.strategies.length} strategies`,
);
if (dropBeforeImport) {
this.logger.info(`Dropping existing strategies`);
await eventStore.store({
type: DROP_STRATEGIES,
createdBy: userName,
data: { name: 'all-strategies' },
});
}
await Promise.all(
importData.strategies.map(strategy =>
eventStore.store({
type: STRATEGY_IMPORT,
createdBy: userName,
data: strategy,
}),
),
);
}
}
async export({ includeFeatureToggles = true, includeStrategies = true }) {
const { featureToggleStore, strategyStore } = this.config.stores;
return Promise.all([
includeFeatureToggles
? featureToggleStore.getFeatures()
: Promise.resolve(),
includeStrategies
? strategyStore.getEditableStrategies()
: Promise.resolve(),
]).then(([features, strategies]) => ({
version: 1,
features,
strategies,
}));
}
}
module.exports = StateService;