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