mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-19 01:17:18 +02:00
feat: import dependencies (#5044)
This commit is contained in:
parent
e9e110f702
commit
5619db33ed
@ -50,6 +50,10 @@ import {
|
|||||||
createFakeSegmentService,
|
createFakeSegmentService,
|
||||||
createSegmentService,
|
createSegmentService,
|
||||||
} from '../segment/createSegmentService';
|
} from '../segment/createSegmentService';
|
||||||
|
import {
|
||||||
|
createDependentFeaturesService,
|
||||||
|
createFakeDependentFeaturesService,
|
||||||
|
} from '../dependent-features/createDependentFeaturesService';
|
||||||
|
|
||||||
export const createFakeExportImportTogglesService = (
|
export const createFakeExportImportTogglesService = (
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
@ -112,6 +116,8 @@ export const createFakeExportImportTogglesService = (
|
|||||||
|
|
||||||
const segmentService = createFakeSegmentService(config);
|
const segmentService = createFakeSegmentService(config);
|
||||||
|
|
||||||
|
const dependentFeaturesService = createFakeDependentFeaturesService(config);
|
||||||
|
|
||||||
const exportImportService = new ExportImportService(
|
const exportImportService = new ExportImportService(
|
||||||
{
|
{
|
||||||
importTogglesStore,
|
importTogglesStore,
|
||||||
@ -133,6 +139,7 @@ export const createFakeExportImportTogglesService = (
|
|||||||
strategyService,
|
strategyService,
|
||||||
tagTypeService,
|
tagTypeService,
|
||||||
segmentService,
|
segmentService,
|
||||||
|
dependentFeaturesService,
|
||||||
},
|
},
|
||||||
dependentFeaturesReadModel,
|
dependentFeaturesReadModel,
|
||||||
);
|
);
|
||||||
@ -229,6 +236,11 @@ export const deferredExportImportTogglesService = (
|
|||||||
|
|
||||||
const segmentService = createSegmentService(db, config);
|
const segmentService = createSegmentService(db, config);
|
||||||
|
|
||||||
|
const dependentFeaturesService = createDependentFeaturesService(
|
||||||
|
db,
|
||||||
|
config,
|
||||||
|
);
|
||||||
|
|
||||||
const exportImportService = new ExportImportService(
|
const exportImportService = new ExportImportService(
|
||||||
{
|
{
|
||||||
importTogglesStore,
|
importTogglesStore,
|
||||||
@ -250,6 +262,7 @@ export const deferredExportImportTogglesService = (
|
|||||||
strategyService,
|
strategyService,
|
||||||
tagTypeService,
|
tagTypeService,
|
||||||
segmentService,
|
segmentService,
|
||||||
|
dependentFeaturesService,
|
||||||
},
|
},
|
||||||
dependentFeaturesReadModel,
|
dependentFeaturesReadModel,
|
||||||
);
|
);
|
||||||
|
@ -34,6 +34,7 @@ import { extractUsernameFromUser } from '../../util';
|
|||||||
import {
|
import {
|
||||||
AccessService,
|
AccessService,
|
||||||
ContextService,
|
ContextService,
|
||||||
|
DependentFeaturesService,
|
||||||
EventService,
|
EventService,
|
||||||
FeatureTagService,
|
FeatureTagService,
|
||||||
FeatureToggleService,
|
FeatureToggleService,
|
||||||
@ -52,7 +53,6 @@ import { FeatureNameCheckResultWithFeaturePattern } from '../feature-toggle/feat
|
|||||||
import { IDependentFeaturesReadModel } from '../dependent-features/dependent-features-read-model-type';
|
import { IDependentFeaturesReadModel } from '../dependent-features/dependent-features-read-model-type';
|
||||||
import groupBy from 'lodash.groupby';
|
import groupBy from 'lodash.groupby';
|
||||||
import { ISegmentService } from '../../segments/segment-service-interface';
|
import { ISegmentService } from '../../segments/segment-service-interface';
|
||||||
import { FeatureDependenciesSchema } from '../../openapi/spec/feature-dependencies-schema';
|
|
||||||
|
|
||||||
export type IImportService = {
|
export type IImportService = {
|
||||||
validate(
|
validate(
|
||||||
@ -113,6 +113,8 @@ export default class ExportImportService
|
|||||||
|
|
||||||
private dependentFeaturesReadModel: IDependentFeaturesReadModel;
|
private dependentFeaturesReadModel: IDependentFeaturesReadModel;
|
||||||
|
|
||||||
|
private dependentFeaturesService: DependentFeaturesService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
stores: Pick<
|
stores: Pick<
|
||||||
IUnleashStores,
|
IUnleashStores,
|
||||||
@ -138,6 +140,7 @@ export default class ExportImportService
|
|||||||
tagTypeService,
|
tagTypeService,
|
||||||
featureTagService,
|
featureTagService,
|
||||||
segmentService,
|
segmentService,
|
||||||
|
dependentFeaturesService,
|
||||||
}: Pick<
|
}: Pick<
|
||||||
IUnleashServices,
|
IUnleashServices,
|
||||||
| 'featureToggleService'
|
| 'featureToggleService'
|
||||||
@ -148,6 +151,7 @@ export default class ExportImportService
|
|||||||
| 'tagTypeService'
|
| 'tagTypeService'
|
||||||
| 'featureTagService'
|
| 'featureTagService'
|
||||||
| 'segmentService'
|
| 'segmentService'
|
||||||
|
| 'dependentFeaturesService'
|
||||||
>,
|
>,
|
||||||
dependentFeaturesReadModel: IDependentFeaturesReadModel,
|
dependentFeaturesReadModel: IDependentFeaturesReadModel,
|
||||||
) {
|
) {
|
||||||
@ -168,6 +172,7 @@ export default class ExportImportService
|
|||||||
this.eventService = eventService;
|
this.eventService = eventService;
|
||||||
this.tagTypeService = tagTypeService;
|
this.tagTypeService = tagTypeService;
|
||||||
this.featureTagService = featureTagService;
|
this.featureTagService = featureTagService;
|
||||||
|
this.dependentFeaturesService = dependentFeaturesService;
|
||||||
this.importPermissionsService = new ImportPermissionsService(
|
this.importPermissionsService = new ImportPermissionsService(
|
||||||
this.importTogglesStore,
|
this.importTogglesStore,
|
||||||
this.accessService,
|
this.accessService,
|
||||||
@ -258,7 +263,7 @@ export default class ExportImportService
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async importToggleLevelInfo(
|
async importFeatureData(
|
||||||
dto: ImportTogglesSchema,
|
dto: ImportTogglesSchema,
|
||||||
user: User,
|
user: User,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -274,9 +279,9 @@ export default class ExportImportService
|
|||||||
|
|
||||||
await this.importVerify(cleanedDto, user);
|
await this.importVerify(cleanedDto, user);
|
||||||
|
|
||||||
await this.importToggleLevelInfo(cleanedDto, user);
|
await this.importFeatureData(cleanedDto, user);
|
||||||
|
|
||||||
await this.importDefault(cleanedDto, user);
|
await this.importEnvironmentData(cleanedDto, user);
|
||||||
await this.eventService.storeEvent({
|
await this.eventService.storeEvent({
|
||||||
project: cleanedDto.project,
|
project: cleanedDto.project,
|
||||||
environment: cleanedDto.environment,
|
environment: cleanedDto.environment,
|
||||||
@ -285,10 +290,34 @@ export default class ExportImportService
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async importDefault(dto: ImportTogglesSchema, user: User): Promise<void> {
|
async importEnvironmentData(
|
||||||
|
dto: ImportTogglesSchema,
|
||||||
|
user: User,
|
||||||
|
): Promise<void> {
|
||||||
await this.deleteStrategies(dto);
|
await this.deleteStrategies(dto);
|
||||||
await this.importStrategies(dto, user);
|
await this.importStrategies(dto, user);
|
||||||
await this.importToggleStatuses(dto, user);
|
await this.importToggleStatuses(dto, user);
|
||||||
|
await this.importDependencies(dto, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async importDependencies(dto: ImportTogglesSchema, user: User) {
|
||||||
|
await Promise.all(
|
||||||
|
(dto.data.dependencies || []).flatMap((dependency) => {
|
||||||
|
const projectId = dto.data.features.find(
|
||||||
|
(feature) => feature.name === dependency.feature,
|
||||||
|
)!.project!;
|
||||||
|
return dependency.dependencies.map((parentDependency) =>
|
||||||
|
this.dependentFeaturesService.upsertFeatureDependency(
|
||||||
|
{
|
||||||
|
child: dependency.feature,
|
||||||
|
projectId,
|
||||||
|
},
|
||||||
|
parentDependency,
|
||||||
|
user,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async importToggleStatuses(dto: ImportTogglesSchema, user: User) {
|
private async importToggleStatuses(dto: ImportTogglesSchema, user: User) {
|
||||||
|
@ -161,6 +161,7 @@ beforeAll(async () => {
|
|||||||
featuresExportImport: true,
|
featuresExportImport: true,
|
||||||
featureNamingPattern: true,
|
featureNamingPattern: true,
|
||||||
dependentFeatures: true,
|
dependentFeatures: true,
|
||||||
|
transactionalDecorator: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -750,6 +751,10 @@ test('import features to existing project and environment', async () => {
|
|||||||
...defaultImportPayload,
|
...defaultImportPayload,
|
||||||
data: {
|
data: {
|
||||||
...defaultImportPayload.data,
|
...defaultImportPayload.data,
|
||||||
|
features: [
|
||||||
|
...defaultImportPayload.data.features,
|
||||||
|
anotherExportedFeature,
|
||||||
|
],
|
||||||
featureStrategies: [
|
featureStrategies: [
|
||||||
{
|
{
|
||||||
...exportedStrategy,
|
...exportedStrategy,
|
||||||
@ -762,6 +767,16 @@ test('import features to existing project and environment', async () => {
|
|||||||
name: segment.name,
|
name: segment.name,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
dependencies: [
|
||||||
|
{
|
||||||
|
feature: exportedFeature.name,
|
||||||
|
dependencies: [
|
||||||
|
{
|
||||||
|
feature: anotherExportedFeature.name,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -779,6 +794,11 @@ test('import features to existing project and environment', async () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
dependencies: [
|
||||||
|
{
|
||||||
|
feature: anotherExportedFeature.name,
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { body: importedFeatureEnvironment } = await getFeatureEnvironment(
|
const { body: importedFeatureEnvironment } = await getFeatureEnvironment(
|
||||||
|
@ -1731,8 +1731,9 @@ class FeatureToggleService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (hasDisabledStrategies && shouldActivateDisabledStrategies) {
|
if (hasDisabledStrategies && shouldActivateDisabledStrategies) {
|
||||||
strategies.map(async (strategy) => {
|
await Promise.all(
|
||||||
return this.updateStrategy(
|
strategies.map((strategy) =>
|
||||||
|
this.updateStrategy(
|
||||||
strategy.id,
|
strategy.id,
|
||||||
{ disabled: false },
|
{ disabled: false },
|
||||||
{
|
{
|
||||||
@ -1741,8 +1742,9 @@ class FeatureToggleService {
|
|||||||
featureName,
|
featureName,
|
||||||
},
|
},
|
||||||
createdBy,
|
createdBy,
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasOnlyDisabledStrategies = strategies.every(
|
const hasOnlyDisabledStrategies = strategies.every(
|
||||||
|
Loading…
Reference in New Issue
Block a user