Skip to content

Commit f8da249

Browse files
Merge branch 'feature/RI-5221_auto_select_plan' of https://github.com/RedisInsight/RedisInsight into feature/RI-5221_auto_select_plan
2 parents a16796c + a72085d commit f8da249

File tree

25 files changed

+486
-45
lines changed

25 files changed

+486
-45
lines changed

redisinsight/api/config/features-config.json

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": 2.3402,
2+
"version": 2.3403,
33
"features": {
44
"insightsRecommendations": {
55
"flag": true,
@@ -47,6 +47,22 @@
4747
}
4848
}
4949
},
50+
"cloudSsoRecommendedSettings": {
51+
"flag": true,
52+
"perc": [[0, 50]],
53+
"filters": [
54+
{
55+
"name": "config.server.buildType",
56+
"value": "ELECTRON",
57+
"cond": "eq"
58+
},
59+
{
60+
"name": "agreements.analytics",
61+
"value": true,
62+
"cond": "eq"
63+
}
64+
]
65+
},
5066
"redisModuleFilter": {
5167
"flag": true,
5268
"perc": [[0, 100]],

redisinsight/api/src/__mocks__/feature.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,12 @@ export const mockFeatureSso = Object.assign(new Feature(), {
182182
redisStackPreview: [
183183
{
184184
provider: 'AWS',
185-
regions: ['us-east-2', 'ap-southeast-1', 'sa-east-1']
185+
regions: ['us-east-2', 'ap-southeast-1', 'sa-east-1'],
186186
},
187187
{
188188
provider: 'GCP',
189-
regions: ['asia-northeast1', 'europe-west1', 'us-central1']
190-
}
189+
regions: ['asia-northeast1', 'europe-west1', 'us-central1'],
190+
},
191191
],
192192
},
193193
},

redisinsight/api/src/modules/cloud/job/cloud-job.factory.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
22
import {
33
CloudJob,
44
CreateFreeSubscriptionAndDatabaseCloudJob,
5-
ImportFreeDatabaseCloudJob
5+
ImportFreeDatabaseCloudJob,
66
} from 'src/modules/cloud/job/jobs';
77
import { CloudJobName } from 'src/modules/cloud/job/constants';
88
import { CreateFreeDatabaseCloudJob } from 'src/modules/cloud/job/jobs/create-free-database.cloud-job';
@@ -16,6 +16,7 @@ import { DatabaseService } from 'src/modules/database/database.service';
1616
import { CloudDatabaseAnalytics } from 'src/modules/cloud/database/cloud-database.analytics';
1717
import { CloudRequestUtm } from 'src/modules/cloud/common/models';
1818
import { CloudCapiKeyService } from 'src/modules/cloud/capi-key/cloud-capi-key.service';
19+
import { CloudSubscriptionApiService } from 'src/modules/cloud/subscription/cloud-subscription.api.service';
1920

2021
@Injectable()
2122
export class CloudJobFactory {
@@ -26,6 +27,7 @@ export class CloudJobFactory {
2627
private readonly cloudDatabaseAnalytics: CloudDatabaseAnalytics,
2728
private readonly databaseService: DatabaseService,
2829
private readonly cloudCapiKeyService: CloudCapiKeyService,
30+
private readonly cloudSubscriptionApiService: CloudSubscriptionApiService,
2931
) {}
3032

3133
async create(
@@ -53,6 +55,7 @@ export class CloudJobFactory {
5355
cloudDatabaseAnalytics: this.cloudDatabaseAnalytics,
5456
databaseService: this.databaseService,
5557
cloudCapiKeyService: this.cloudCapiKeyService,
58+
cloudSubscriptionApiService: this.cloudSubscriptionApiService,
5659
},
5760
);
5861
case CloudJobName.CreateFreeDatabase:
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
import { ApiProperty } from '@nestjs/swagger';
2-
import { IsNotEmpty, IsNumber } from 'class-validator';
1+
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
2+
import { IsBoolean, IsNotEmpty, IsNumber, IsOptional, ValidateIf } from 'class-validator';
33

44
export class CreateSubscriptionAndDatabaseCloudJobDataDto {
55
@ApiProperty({
66
description: 'Plan id for create a subscription.',
77
type: Number,
88
})
9+
@ValidateIf((object) => !object.isRecommendedSettings)
910
@IsNumber()
1011
@IsNotEmpty()
1112
planId: number;
13+
14+
@ApiPropertyOptional({
15+
description: 'Use recommended settings',
16+
type: Boolean,
17+
})
18+
@IsBoolean()
19+
@IsOptional()
20+
isRecommendedSettings?: boolean;
1221
}

redisinsight/api/src/modules/cloud/job/jobs/create-free-subscription-and-database.cloud-job.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { sortBy } from 'lodash';
12
import { CloudJob, CloudJobOptions, CreateFreeDatabaseCloudJob } from 'src/modules/cloud/job/jobs';
23
import { CloudTaskCapiService } from 'src/modules/cloud/task/cloud-task.capi.service';
34
import { CloudSubscriptionCapiService } from 'src/modules/cloud/subscription/cloud-subscription.capi.service';
@@ -10,15 +11,18 @@ import { Database } from 'src/modules/database/models/database';
1011
import { CloudDatabaseAnalytics } from 'src/modules/cloud/database/cloud-database.analytics';
1112
import { CloudCapiKeyService } from 'src/modules/cloud/capi-key/cloud-capi-key.service';
1213
import { CloudSubscription } from 'src/modules/cloud/subscription/models';
14+
import { CloudSubscriptionApiService } from '../../subscription/cloud-subscription.api.service';
15+
import { CloudSubscriptionPlanResponse } from '../../subscription/dto';
1316

1417
export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
1518
protected name = CloudJobName.CreateFreeSubscriptionAndDatabase;
1619

1720
constructor(
1821
readonly options: CloudJobOptions,
1922

20-
private readonly data: {
21-
planId: number,
23+
private data: {
24+
planId?: number,
25+
isRecommendedSettings?: boolean,
2226
},
2327

2428
protected readonly dependencies: {
@@ -28,12 +32,15 @@ export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
2832
cloudDatabaseAnalytics: CloudDatabaseAnalytics,
2933
databaseService: DatabaseService,
3034
cloudCapiKeyService: CloudCapiKeyService,
35+
cloudSubscriptionApiService: CloudSubscriptionApiService,
3136
},
3237
) {
3338
super(options);
3439
}
3540

3641
async iteration(): Promise<Database> {
42+
let planId = this.data?.planId;
43+
3744
this.logger.log('Create free subscription and database');
3845

3946
this.checkSignal();
@@ -42,9 +49,15 @@ export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
4249

4350
this.logger.debug('Get or create free subscription');
4451

52+
if (this.data?.isRecommendedSettings) {
53+
const plans = await this.dependencies.cloudSubscriptionApiService.getSubscriptionPlans(this.options.sessionMetadata);
54+
55+
planId = this.getRecommendedPlanId(plans);
56+
}
57+
4558
const freeSubscription: CloudSubscription = await this.runChildJob(
4659
CreateFreeSubscriptionCloudJob,
47-
this.data,
60+
{ planId },
4861
this.options,
4962
);
5063

@@ -72,4 +85,9 @@ export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
7285

7386
return database;
7487
}
88+
89+
private getRecommendedPlanId(plans: CloudSubscriptionPlanResponse[]) {
90+
const defaultPlan = sortBy(plans, ['details.displayOrder']);
91+
return defaultPlan[0]?.id;
92+
}
7593
}

redisinsight/api/src/modules/cloud/subscription/cloud-subscription.module.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { CloudSubscriptionCapiProvider } from './providers/cloud-subscription.ca
2525
],
2626
exports: [
2727
CloudSubscriptionCapiService,
28+
CloudSubscriptionApiService,
2829
],
2930
})
3031
export class CloudSubscriptionModule {}

redisinsight/api/src/modules/feature/constants/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export enum FeatureConfigConfigDestination {
2222
export enum KnownFeatures {
2323
InsightsRecommendations = 'insightsRecommendations',
2424
CloudSso = 'cloudSso',
25+
CloudSsoRecommendedSettings = 'cloudSsoRecommendedSettings',
2526
RedisModuleFilter = 'redisModuleFilter',
2627
}
2728

redisinsight/api/src/modules/feature/constants/known-features.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export const knownFeatures: Record<KnownFeatures, IFeatureFlag> = {
1111
storage: FeatureStorage.Database,
1212
factory: CloudSsoFeatureFlag.getFeature,
1313
},
14+
[KnownFeatures.CloudSsoRecommendedSettings]: {
15+
name: KnownFeatures.CloudSsoRecommendedSettings,
16+
storage: FeatureStorage.Database,
17+
},
1418
[KnownFeatures.RedisModuleFilter]: {
1519
name: KnownFeatures.RedisModuleFilter,
1620
storage: FeatureStorage.Database,

redisinsight/api/src/modules/feature/providers/feature-flag/feature-flag.provider.spec.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { FeatureFlagProvider } from 'src/modules/feature/providers/feature-flag/
99
import { SettingsService } from 'src/modules/settings/settings.service';
1010
import { KnownFeatures } from 'src/modules/feature/constants';
1111
import {
12-
InsightsRecommendationsFlagStrategy,
13-
} from 'src/modules/feature/providers/feature-flag/strategies/insights-recommendations.flag.strategy';
12+
CommonFlagStrategy,
13+
} from 'src/modules/feature/providers/feature-flag/strategies/common.flag.strategy';
1414
import { DefaultFlagStrategy } from 'src/modules/feature/providers/feature-flag/strategies/default.flag.strategy';
1515
import { knownFeatures } from 'src/modules/feature/constants/known-features';
1616

@@ -37,9 +37,13 @@ describe('FeatureFlagProvider', () => {
3737
});
3838

3939
describe('getStrategy', () => {
40-
it('should return insights strategy', async () => {
40+
it('should return common strategy', async () => {
4141
expect(await service.getStrategy(KnownFeatures.InsightsRecommendations))
42-
.toBeInstanceOf(InsightsRecommendationsFlagStrategy);
42+
.toBeInstanceOf(CommonFlagStrategy);
43+
});
44+
it('should return common strategy', async () => {
45+
expect(await service.getStrategy(KnownFeatures.CloudSsoRecommendedSettings))
46+
.toBeInstanceOf(CommonFlagStrategy);
4347
});
4448
it('should return default strategy when directly called', async () => {
4549
expect(await service.getStrategy('default'))
@@ -54,7 +58,7 @@ describe('FeatureFlagProvider', () => {
5458
describe('calculate', () => {
5559
it('should calculate ', async () => {
5660
jest.spyOn(service, 'getStrategy')
57-
.mockReturnValue(mockInsightsRecommendationsFlagStrategy as unknown as InsightsRecommendationsFlagStrategy);
61+
.mockReturnValue(mockInsightsRecommendationsFlagStrategy as unknown as CommonFlagStrategy);
5862

5963
expect(await service.calculate(
6064
knownFeatures[KnownFeatures.InsightsRecommendations],

redisinsight/api/src/modules/feature/providers/feature-flag/feature-flag.provider.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Injectable } from '@nestjs/common';
22
import { FeatureFlagStrategy } from 'src/modules/feature/providers/feature-flag/strategies/feature.flag.strategy';
33
import {
4-
InsightsRecommendationsFlagStrategy,
5-
} from 'src/modules/feature/providers/feature-flag/strategies/insights-recommendations.flag.strategy';
4+
CommonFlagStrategy,
5+
} from 'src/modules/feature/providers/feature-flag/strategies/common.flag.strategy';
66
import { DefaultFlagStrategy } from 'src/modules/feature/providers/feature-flag/strategies/default.flag.strategy';
77
import { FeaturesConfigService } from 'src/modules/feature/features-config.service';
88
import { SettingsService } from 'src/modules/settings/settings.service';
99
import { IFeatureFlag, KnownFeatures } from 'src/modules/feature/constants';
1010
import { CloudSsoFlagStrategy } from 'src/modules/feature/providers/feature-flag/strategies/cloud-sso.flag.strategy';
1111
import { Feature } from 'src/modules/feature/model/feature';
12-
import { SimpleFlagStrategy } from 'src/modules/feature/providers/feature-flag/strategies/simple.flag.strategy';
12+
import { WithDataFlagStrategy } from 'src/modules/feature/providers/feature-flag/strategies/with-data.flag.strategy';
1313

1414
@Injectable()
1515
export class FeatureFlagProvider {
@@ -23,15 +23,19 @@ export class FeatureFlagProvider {
2323
this.featuresConfigService,
2424
this.settingsService,
2525
));
26-
this.strategies.set(KnownFeatures.InsightsRecommendations, new InsightsRecommendationsFlagStrategy(
26+
this.strategies.set(KnownFeatures.InsightsRecommendations, new CommonFlagStrategy(
2727
this.featuresConfigService,
2828
this.settingsService,
2929
));
3030
this.strategies.set(KnownFeatures.CloudSso, new CloudSsoFlagStrategy(
3131
this.featuresConfigService,
3232
this.settingsService,
3333
));
34-
this.strategies.set(KnownFeatures.RedisModuleFilter, new SimpleFlagStrategy(
34+
this.strategies.set(KnownFeatures.CloudSsoRecommendedSettings, new CommonFlagStrategy(
35+
this.featuresConfigService,
36+
this.settingsService,
37+
));
38+
this.strategies.set(KnownFeatures.RedisModuleFilter, new WithDataFlagStrategy(
3539
this.featuresConfigService,
3640
this.settingsService,
3741
));

0 commit comments

Comments
 (0)