1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-09-05 17:53:12 +02:00

Added events for feature_strategy update

This commit is contained in:
Christopher Kolstad 2021-09-16 09:07:00 +02:00
parent 68d4ac0252
commit 1ae90f6942
No known key found for this signature in database
GPG Key ID: 559ACB0E3DB5538A
3 changed files with 96 additions and 22 deletions

View File

@ -17,6 +17,7 @@ import {
} from '../../../types/model';
import { extractUsername } from '../../../util/extract-user';
import { IAuthRequest } from '../../unleash-types';
import { projectSchema } from '../../../services/project-schema';
interface FeatureStrategyParams {
projectId: string;
@ -220,14 +221,16 @@ export default class ProjectFeaturesController extends Controller {
}
async addStrategy(
req: Request<FeatureStrategyParams, any, IStrategyConfig, any>,
req: IAuthRequest<FeatureStrategyParams, any, IStrategyConfig, any>,
res: Response,
): Promise<void> {
const { projectId, featureName, environment } = req.params;
const userName = extractUsername(req);
const featureStrategy = await this.featureService.createStrategy(
req.body,
projectId,
featureName,
userName,
environment,
);
res.status(200).json(featureStrategy);
@ -248,34 +251,42 @@ export default class ProjectFeaturesController extends Controller {
}
async updateStrategy(
req: Request<StrategyIdParams, any, StrategyUpdateBody, any>,
req: IAuthRequest<StrategyIdParams, any, StrategyUpdateBody, any>,
res: Response,
): Promise<void> {
const { strategyId } = req.params;
const { strategyId, environment, projectId } = req.params;
const userName = extractUsername(req);
const updatedStrategy = await this.featureService.updateStrategy(
strategyId,
environment,
projectId,
userName,
req.body,
);
res.status(200).json(updatedStrategy);
}
async patchStrategy(
req: Request<StrategyIdParams, any, Operation[], any>,
req: IAuthRequest<StrategyIdParams, any, Operation[], any>,
res: Response,
): Promise<void> {
const { strategyId } = req.params;
const { strategyId, projectId, environment } = req.params;
const userName = extractUsername(req);
const patch = req.body;
const strategy = await this.featureService.getStrategy(strategyId);
const { newDocument } = applyPatch(strategy, patch);
const updatedStrategy = await this.featureService.updateStrategy(
strategyId,
environment,
projectId,
userName,
newDocument,
);
res.status(200).json(updatedStrategy);
}
async getStrategy(
req: Request<StrategyIdParams, any, any, any>,
req: IAuthRequest<StrategyIdParams, any, any, any>,
res: Response,
): Promise<void> {
this.logger.info('Getting strategy');
@ -286,18 +297,25 @@ export default class ProjectFeaturesController extends Controller {
}
async deleteStrategy(
req: Request<StrategyIdParams, any, any, any>,
req: IAuthRequest<StrategyIdParams, any, any, any>,
res: Response,
): Promise<void> {
this.logger.info('Deleting strategy');
const { environment, projectId } = req.params;
const userName = extractUsername(req);
const { strategyId } = req.params;
this.logger.info(strategyId);
const strategy = await this.featureService.deleteStrategy(strategyId);
const strategy = await this.featureService.deleteStrategy(
strategyId,
userName,
projectId,
environment,
);
res.status(200).json(strategy);
}
async updateStrategyParameter(
req: Request<
req: IAuthRequest<
StrategyIdParams,
any,
{ name: string; value: string | number },
@ -305,7 +323,8 @@ export default class ProjectFeaturesController extends Controller {
>,
res: Response,
): Promise<void> {
const { strategyId } = req.params;
const { strategyId, environment, projectId } = req.params;
const userName = extractUsername(req);
const { name, value } = req.body;
const updatedStrategy =
@ -313,6 +332,9 @@ export default class ProjectFeaturesController extends Controller {
strategyId,
name,
value,
userName,
projectId,
environment,
);
res.status(200).json(updatedStrategy);
}

View File

@ -10,11 +10,14 @@ import {
FEATURE_ARCHIVED,
FEATURE_CREATED,
FEATURE_DELETED,
FEATURE_METADATA_UPDATED,
FEATURE_REVIVED,
FEATURE_STALE_OFF,
FEATURE_STALE_ON,
FEATURE_STRATEGY_ADD,
FEATURE_STRATEGY_REMOVE,
FEATURE_STRATEGY_UPDATE,
FEATURE_UPDATED,
FEATURE_METADATA_UPDATED,
} from '../types/events';
import { GLOBAL_ENV } from '../types/environment';
import NotFoundError from '../error/notfound-error';
@ -88,16 +91,11 @@ class FeatureToggleServiceV2 {
this.featureEnvironmentStore = featureEnvironmentStore;
}
/*
TODO after 4.1.0 release:
- add FEATURE_STRATEGY_ADD event
- add FEATURE_STRATEGY_REMOVE event
- add FEATURE_STRATEGY_UPDATE event
*/
async createStrategy(
strategyConfig: Omit<IStrategyConfig, 'id'>,
projectId: string,
featureName: string,
userName: string,
environment: string = GLOBAL_ENV,
): Promise<IStrategyConfig> {
try {
@ -111,12 +109,20 @@ class FeatureToggleServiceV2 {
featureName,
environment,
});
return {
const data = {
id: newFeatureStrategy.id,
name: newFeatureStrategy.strategyName,
constraints: newFeatureStrategy.constraints,
parameters: newFeatureStrategy.parameters,
};
await this.eventStore.store({
type: FEATURE_STRATEGY_ADD,
project: projectId,
createdBy: userName,
environment,
data,
});
return data;
} catch (e) {
if (e.code === FOREIGN_KEY_VIOLATION) {
throw new BadDataError(
@ -126,6 +132,12 @@ class FeatureToggleServiceV2 {
throw e;
}
}
/*
TODO after 4.1.0 release:
- add FEATURE_STRATEGY_ADD event
- add FEATURE_STRATEGY_REMOVE event
- add FEATURE_STRATEGY_UPDATE event
*/
/**
* PUT /api/admin/projects/:projectId/features/:featureName/strategies/:strategyId ?
@ -139,6 +151,9 @@ class FeatureToggleServiceV2 {
// TODO: verify projectId is not changed from URL!
async updateStrategy(
id: string,
environment: string,
project: string,
userName: string,
updates: Partial<IFeatureStrategy>,
): Promise<IStrategyConfig> {
const existingStrategy = await this.featureStrategiesStore.get(id);
@ -147,12 +162,20 @@ class FeatureToggleServiceV2 {
id,
updates,
);
return {
const data = {
id: strategy.id,
name: strategy.strategyName,
constraints: strategy.constraints || [],
parameters: strategy.parameters,
};
await this.eventStore.store({
type: FEATURE_STRATEGY_UPDATE,
project,
environment,
createdBy: userName,
data,
});
return data;
}
throw new NotFoundError(`Could not find strategy with id ${id}`);
}
@ -162,6 +185,9 @@ class FeatureToggleServiceV2 {
id: string,
name: string,
value: string | number,
userName: string,
project: string,
environment: string,
): Promise<IStrategyConfig> {
const existingStrategy = await this.featureStrategiesStore.get(id);
if (existingStrategy.id === id) {
@ -170,12 +196,20 @@ class FeatureToggleServiceV2 {
id,
existingStrategy,
);
return {
const data = {
id: strategy.id,
name: strategy.strategyName,
constraints: strategy.constraints || [],
parameters: strategy.parameters,
};
await this.eventStore.store({
type: FEATURE_STRATEGY_UPDATE,
project,
environment,
createdBy: userName,
data,
});
return data;
}
throw new NotFoundError(`Could not find strategy with id ${id}`);
}
@ -188,8 +222,22 @@ class FeatureToggleServiceV2 {
* @param id
* @param updates
*/
async deleteStrategy(id: string): Promise<void> {
return this.featureStrategiesStore.delete(id);
async deleteStrategy(
id: string,
userName: string,
project: string = 'default',
environment: string = GLOBAL_ENV,
): Promise<void> {
await this.featureStrategiesStore.delete(id);
await this.eventStore.store({
type: FEATURE_STRATEGY_REMOVE,
project,
environment,
createdBy: userName,
data: {
id,
},
});
}
async getStrategiesForEnvironment(
@ -519,6 +567,7 @@ class FeatureToggleServiceV2 {
data,
tags,
project: projectId,
environment,
});
return feature;
}

View File

@ -9,6 +9,9 @@ export const FEATURE_REVIVED = 'feature-revived';
export const FEATURE_IMPORT = 'feature-import';
export const FEATURE_TAGGED = 'feature-tagged';
export const FEATURE_TAG_IMPORT = 'feature-tag-import';
export const FEATURE_STRATEGY_UPDATE = 'feature-strategy-update';
export const FEATURE_STRATEGY_ADD = 'feature-strategy-add';
export const FEATURE_STRATEGY_REMOVE = 'feature-strategy-remove';
export const DROP_FEATURE_TAGS = 'drop-feature-tags';
export const FEATURE_UNTAGGED = 'feature-untagged';
export const FEATURE_STALE_ON = 'feature-stale-on';