mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: transactional complete/uncomplete feature (#7451)
This commit is contained in:
parent
7f6e29b5dd
commit
d29230cd49
@ -14,48 +14,41 @@ import { FeatureEnvironmentStore } from '../../db/feature-environment-store';
|
|||||||
import FakeFeatureEnvironmentStore from '../../../test/fixtures/fake-feature-environment-store';
|
import FakeFeatureEnvironmentStore from '../../../test/fixtures/fake-feature-environment-store';
|
||||||
import EventEmitter from 'events';
|
import EventEmitter from 'events';
|
||||||
|
|
||||||
export const createFeatureLifecycleService = (
|
export const createFeatureLifecycleService =
|
||||||
db: Db,
|
(config: IUnleashConfig) => (db: Db) => {
|
||||||
config: IUnleashConfig,
|
const { eventBus, getLogger, flagResolver } = config;
|
||||||
) => {
|
const eventStore = new EventStore(db, getLogger);
|
||||||
const { eventBus, getLogger, flagResolver } = config;
|
const featureLifecycleStore = new FeatureLifecycleStore(db);
|
||||||
const eventStore = new EventStore(db, getLogger);
|
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
|
||||||
const featureLifecycleStore = new FeatureLifecycleStore(db);
|
const featureEnvironmentStore = new FeatureEnvironmentStore(
|
||||||
const environmentStore = new EnvironmentStore(db, eventBus, getLogger);
|
db,
|
||||||
const featureEnvironmentStore = new FeatureEnvironmentStore(
|
eventBus,
|
||||||
db,
|
getLogger,
|
||||||
eventBus,
|
);
|
||||||
getLogger,
|
const featureTagStore = new FeatureTagStore(
|
||||||
);
|
db,
|
||||||
const featureTagStore = new FeatureTagStore(
|
config.eventBus,
|
||||||
db,
|
config.getLogger,
|
||||||
config.eventBus,
|
);
|
||||||
config.getLogger,
|
const eventService = new EventService(
|
||||||
);
|
{ eventStore, featureTagStore },
|
||||||
const eventService = new EventService(
|
{ getLogger, eventBus: new EventEmitter() },
|
||||||
{ eventStore, featureTagStore },
|
);
|
||||||
{ getLogger, eventBus: new EventEmitter() },
|
const featureLifecycleService = new FeatureLifecycleService(
|
||||||
);
|
{
|
||||||
const featureLifecycleService = new FeatureLifecycleService(
|
eventStore,
|
||||||
{
|
featureLifecycleStore,
|
||||||
eventStore,
|
environmentStore,
|
||||||
featureLifecycleStore,
|
featureEnvironmentStore,
|
||||||
environmentStore,
|
},
|
||||||
featureEnvironmentStore,
|
{
|
||||||
},
|
eventService,
|
||||||
{
|
},
|
||||||
eventService,
|
config,
|
||||||
},
|
);
|
||||||
config,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return featureLifecycleService;
|
||||||
featureLifecycleService,
|
|
||||||
featureLifecycleStore,
|
|
||||||
eventStore,
|
|
||||||
environmentStore,
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
export const createFakeFeatureLifecycleService = (config: IUnleashConfig) => {
|
export const createFakeFeatureLifecycleService = (config: IUnleashConfig) => {
|
||||||
const eventStore = new FakeEventStore();
|
const eventStore = new FakeEventStore();
|
||||||
|
@ -21,6 +21,7 @@ import Controller from '../../routes/controller';
|
|||||||
import type { Request, Response } from 'express';
|
import type { Request, Response } from 'express';
|
||||||
import { NotFoundError } from '../../error';
|
import { NotFoundError } from '../../error';
|
||||||
import type { IAuthRequest } from '../../routes/unleash-types';
|
import type { IAuthRequest } from '../../routes/unleash-types';
|
||||||
|
import type { WithTransactional } from '../../db/transaction';
|
||||||
|
|
||||||
interface FeatureLifecycleParams {
|
interface FeatureLifecycleParams {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
@ -30,7 +31,7 @@ interface FeatureLifecycleParams {
|
|||||||
const PATH = '/:projectId/features/:featureName/lifecycle';
|
const PATH = '/:projectId/features/:featureName/lifecycle';
|
||||||
|
|
||||||
export default class FeatureLifecycleController extends Controller {
|
export default class FeatureLifecycleController extends Controller {
|
||||||
private featureLifecycleService: FeatureLifecycleService;
|
private featureLifecycleService: WithTransactional<FeatureLifecycleService>;
|
||||||
|
|
||||||
private openApiService: OpenApiService;
|
private openApiService: OpenApiService;
|
||||||
|
|
||||||
@ -39,12 +40,15 @@ export default class FeatureLifecycleController extends Controller {
|
|||||||
constructor(
|
constructor(
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
{
|
{
|
||||||
featureLifecycleService,
|
transactionalFeatureLifecycleService,
|
||||||
openApiService,
|
openApiService,
|
||||||
}: Pick<IUnleashServices, 'openApiService' | 'featureLifecycleService'>,
|
}: Pick<
|
||||||
|
IUnleashServices,
|
||||||
|
'openApiService' | 'transactionalFeatureLifecycleService'
|
||||||
|
>,
|
||||||
) {
|
) {
|
||||||
super(config);
|
super(config);
|
||||||
this.featureLifecycleService = featureLifecycleService;
|
this.featureLifecycleService = transactionalFeatureLifecycleService;
|
||||||
this.openApiService = openApiService;
|
this.openApiService = openApiService;
|
||||||
this.flagResolver = config.flagResolver;
|
this.flagResolver = config.flagResolver;
|
||||||
|
|
||||||
@ -147,11 +151,8 @@ export default class FeatureLifecycleController extends Controller {
|
|||||||
|
|
||||||
const status = req.body;
|
const status = req.body;
|
||||||
|
|
||||||
await this.featureLifecycleService.featureCompleted(
|
await this.featureLifecycleService.transactional((service) =>
|
||||||
featureName,
|
service.featureCompleted(featureName, projectId, status, req.audit),
|
||||||
projectId,
|
|
||||||
status,
|
|
||||||
req.audit,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
@ -166,10 +167,8 @@ export default class FeatureLifecycleController extends Controller {
|
|||||||
}
|
}
|
||||||
const { featureName, projectId } = req.params;
|
const { featureName, projectId } = req.params;
|
||||||
|
|
||||||
await this.featureLifecycleService.featureUncompleted(
|
await this.featureLifecycleService.transactional((service) =>
|
||||||
featureName,
|
service.featureUncompleted(featureName, projectId, req.audit),
|
||||||
projectId,
|
|
||||||
req.audit,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
res.status(200).end();
|
res.status(200).end();
|
||||||
|
@ -14,7 +14,6 @@ import {
|
|||||||
type StageName,
|
type StageName,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
import type EventEmitter from 'events';
|
import type EventEmitter from 'events';
|
||||||
import type { FeatureLifecycleService } from './feature-lifecycle-service';
|
|
||||||
import type { FeatureLifecycleCompletedSchema } from '../../openapi';
|
import type { FeatureLifecycleCompletedSchema } from '../../openapi';
|
||||||
import { FeatureLifecycleReadModel } from './feature-lifecycle-read-model';
|
import { FeatureLifecycleReadModel } from './feature-lifecycle-read-model';
|
||||||
import type { IFeatureLifecycleReadModel } from './feature-lifecycle-read-model-type';
|
import type { IFeatureLifecycleReadModel } from './feature-lifecycle-read-model-type';
|
||||||
@ -22,7 +21,6 @@ import { STAGE_ENTERED } from '../../metric-events';
|
|||||||
|
|
||||||
let app: IUnleashTest;
|
let app: IUnleashTest;
|
||||||
let db: ITestDb;
|
let db: ITestDb;
|
||||||
let featureLifecycleService: FeatureLifecycleService;
|
|
||||||
let featureLifecycleStore: IFeatureLifecycleStore;
|
let featureLifecycleStore: IFeatureLifecycleStore;
|
||||||
let eventStore: IEventStore;
|
let eventStore: IEventStore;
|
||||||
let eventBus: EventEmitter;
|
let eventBus: EventEmitter;
|
||||||
@ -43,7 +41,6 @@ beforeAll(async () => {
|
|||||||
);
|
);
|
||||||
eventStore = db.stores.eventStore;
|
eventStore = db.stores.eventStore;
|
||||||
eventBus = app.config.eventBus;
|
eventBus = app.config.eventBus;
|
||||||
featureLifecycleService = app.services.featureLifecycleService;
|
|
||||||
featureLifecycleReadModel = new FeatureLifecycleReadModel(
|
featureLifecycleReadModel = new FeatureLifecycleReadModel(
|
||||||
db.rawDatabase,
|
db.rawDatabase,
|
||||||
app.config.flagResolver,
|
app.config.flagResolver,
|
||||||
|
@ -362,9 +362,12 @@ export const createServices = (
|
|||||||
config.getLogger,
|
config.getLogger,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { featureLifecycleService } = db
|
const transactionalFeatureLifecycleService = db
|
||||||
? createFeatureLifecycleService(db, config)
|
? withTransactional(createFeatureLifecycleService(config), db)
|
||||||
: createFakeFeatureLifecycleService(config);
|
: withFakeTransactional(
|
||||||
|
createFakeFeatureLifecycleService(config).featureLifecycleService,
|
||||||
|
);
|
||||||
|
const featureLifecycleService = transactionalFeatureLifecycleService;
|
||||||
featureLifecycleService.listen();
|
featureLifecycleService.listen();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -426,6 +429,7 @@ export const createServices = (
|
|||||||
projectInsightsService,
|
projectInsightsService,
|
||||||
jobService,
|
jobService,
|
||||||
featureLifecycleService,
|
featureLifecycleService,
|
||||||
|
transactionalFeatureLifecycleService,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -117,4 +117,5 @@ export interface IUnleashServices {
|
|||||||
projectInsightsService: ProjectInsightsService;
|
projectInsightsService: ProjectInsightsService;
|
||||||
jobService: JobService;
|
jobService: JobService;
|
||||||
featureLifecycleService: FeatureLifecycleService;
|
featureLifecycleService: FeatureLifecycleService;
|
||||||
|
transactionalFeatureLifecycleService: WithTransactional<FeatureLifecycleService>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user