Skip to content

Commit e36548c

Browse files
authored
Merge pull request #2585 from RedisInsight/feature/RI-4717-import_existing_free_cloud_database
Feature/ri 4717 import existing free cloud database
2 parents b5a0730 + 002197d commit e36548c

36 files changed

+733
-155
lines changed

redisinsight/api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"start:prod": "cross-env NODE_ENV=production BUILD_TYPE=DOCKER_ON_PREMISE node dist/src/main",
2828
"test": "cross-env NODE_ENV=test ./node_modules/.bin/jest -w 1",
2929
"test:watch": "cross-env NODE_ENV=test jest --watch -w 1",
30-
"test:cov": "cross-env NODE_ENV=test ./node_modules/.bin/jest --forceExit --coverage -w 1",
30+
"test:cov": "cross-env NODE_ENV=test ./node_modules/.bin/jest --forceExit --coverage -w 4",
3131
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand -w 1",
3232
"test:e2e": "jest --config ./test/jest-e2e.json -w 1",
3333
"typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -d ./config/ormconfig.ts",

redisinsight/api/src/modules/cloud/database/cloud-database.analytics.spec.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ describe('CloudDatabaseAnalytics', () => {
7373
it('should emit error event with selected plan', async () => {
7474
await service.sendCloudFreeDatabaseFailed(
7575
httpException,
76-
{},
77-
cloudSubscriptionCapiService,
78-
mockData,
76+
{
77+
region: mockFreeCloudSubscriptionPlan1.region,
78+
provider: mockFreeCloudSubscriptionPlan1.provider,
79+
},
7980
);
8081

8182
expect(sendFailedEventMethod).toHaveBeenCalledWith(
@@ -93,26 +94,19 @@ describe('CloudDatabaseAnalytics', () => {
9394
await service.sendCloudFreeDatabaseFailed(
9495
httpException,
9596
undefined,
96-
cloudSubscriptionCapiService,
97-
mockData,
9897
);
9998

10099
expect(sendFailedEventMethod).toHaveBeenCalledWith(
101100
TelemetryEvents.CloudFreeDatabaseFailed,
102101
httpException,
103-
{
104-
region: mockFreeCloudSubscriptionPlan1.region,
105-
provider: mockFreeCloudSubscriptionPlan1.provider,
106-
},
102+
{},
107103
);
108104
});
109105

110106
it('should emit error event when free subscription is not exist', async () => {
111107
await service.sendCloudFreeDatabaseFailed(
112108
httpException,
113109
undefined,
114-
cloudSubscriptionCapiService,
115-
{ planId: 123, capiCredentials: mockCloudCapiAuthDto },
116110
);
117111

118112
expect(sendFailedEventMethod).toHaveBeenCalledWith(

redisinsight/api/src/modules/cloud/database/cloud-database.analytics.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@ import { HttpException, Injectable } from '@nestjs/common';
22
import { TelemetryBaseService } from 'src/modules/analytics/telemetry.base.service';
33
import { EventEmitter2 } from '@nestjs/event-emitter';
44
import { TelemetryEvents } from 'src/constants';
5-
import { CloudSubscriptionCapiService } from '../subscription/cloud-subscription.capi.service';
6-
import { CloudSubscriptionType } from '../subscription/models';
7-
import { CloudCapiAuthDto } from '../common/dto';
85

96
@Injectable()
107
export class CloudDatabaseAnalytics extends TelemetryBaseService {
@@ -19,25 +16,12 @@ export class CloudDatabaseAnalytics extends TelemetryBaseService {
1916
async sendCloudFreeDatabaseFailed(
2017
exception: HttpException,
2118
eventData: object = {},
22-
cloudSubscriptionCapiService: CloudSubscriptionCapiService,
23-
data: { planId: number, capiCredentials: CloudCapiAuthDto },
2419
) {
2520
try {
26-
const fixedPlans = await cloudSubscriptionCapiService.getSubscriptionsPlans(
27-
data.capiCredentials,
28-
CloudSubscriptionType.Fixed,
29-
);
30-
31-
const selectedPlan = CloudSubscriptionCapiService.findFreePlanById(fixedPlans, data.planId);
32-
3321
this.sendFailedEvent(
3422
TelemetryEvents.CloudFreeDatabaseFailed,
3523
exception,
36-
{
37-
...eventData,
38-
region: selectedPlan?.region,
39-
provider: selectedPlan?.provider,
40-
},
24+
eventData,
4125
);
4226
} catch (error) {
4327
// ignore

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { Injectable } from '@nestjs/common';
2-
import { CloudJob } from 'src/modules/cloud/job/jobs';
2+
import {
3+
CloudJob,
4+
CreateFreeSubscriptionAndDatabaseCloudJob,
5+
ImportFreeDatabaseCloudJob
6+
} from 'src/modules/cloud/job/jobs';
37
import { CloudJobName } from 'src/modules/cloud/job/constants';
48
import { CreateFreeDatabaseCloudJob } from 'src/modules/cloud/job/jobs/create-free-database.cloud-job';
59
import { CloudDatabaseCapiService } from 'src/modules/cloud/database/cloud-database.capi.service';
@@ -31,10 +35,26 @@ export class CloudJobFactory {
3135
sessionMetadata: SessionMetadata,
3236
utm?: CloudRequestUtm,
3337
capiCredentials?: CloudCapiAuthDto,
34-
stateCallback?: (self: CloudJob) => any,
38+
stateCallbacks?: ((self: CloudJob) => any)[],
3539
},
3640
): Promise<CloudJob> {
3741
switch (name) {
42+
case CloudJobName.CreateFreeSubscriptionAndDatabase:
43+
return new CreateFreeSubscriptionAndDatabaseCloudJob(
44+
{
45+
abortController: new AbortController(),
46+
...options,
47+
},
48+
data,
49+
{
50+
cloudDatabaseCapiService: this.cloudDatabaseCapiService,
51+
cloudSubscriptionCapiService: this.cloudSubscriptionCapiService,
52+
cloudTaskCapiService: this.cloudTaskCapiService,
53+
cloudDatabaseAnalytics: this.cloudDatabaseAnalytics,
54+
databaseService: this.databaseService,
55+
cloudCapiKeyService: this.cloudCapiKeyService,
56+
},
57+
);
3858
case CloudJobName.CreateFreeDatabase:
3959
return new CreateFreeDatabaseCloudJob(
4060
{
@@ -51,6 +71,22 @@ export class CloudJobFactory {
5171
cloudCapiKeyService: this.cloudCapiKeyService,
5272
},
5373
);
74+
case CloudJobName.ImportFreeDatabase:
75+
return new ImportFreeDatabaseCloudJob(
76+
{
77+
abortController: new AbortController(),
78+
...options,
79+
},
80+
data,
81+
{
82+
cloudDatabaseCapiService: this.cloudDatabaseCapiService,
83+
cloudSubscriptionCapiService: this.cloudSubscriptionCapiService,
84+
cloudTaskCapiService: this.cloudTaskCapiService,
85+
cloudDatabaseAnalytics: this.cloudDatabaseAnalytics,
86+
databaseService: this.databaseService,
87+
cloudCapiKeyService: this.cloudCapiKeyService,
88+
},
89+
);
5490
default:
5591
throw new CloudJobUnsupportedException();
5692
}

redisinsight/api/src/modules/cloud/job/constants/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
export enum CloudJobName {
2+
CreateFreeSubscriptionAndDatabase = 'CREATE_FREE_SUBSCRIPTION_AND_DATABASE',
23
CreateFreeDatabase = 'CREATE_FREE_DATABASE',
34
CreateFreeSubscription = 'CREATE_FREE_SUBSCRIPTION',
5+
ImportFreeDatabase = 'IMPORT_FREE_DATABASE',
46
WaitForActiveDatabase = 'WAIT_FOR_ACTIVE_DATABASE',
57
WaitForActiveSubscription = 'WAIT_FOR_ACTIVE_SUBSCRIPTION',
68
WaitForTask = 'WAIT_FOR_TASK',

redisinsight/api/src/modules/cloud/job/dto/create-database.cloud-job.data.dto.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { IsNotEmpty, IsNumber } from 'class-validator';
33

44
export class CreateDatabaseCloudJobDataDto {
55
@ApiProperty({
6-
description: 'Plan id for create a subscription.',
6+
description: 'Subscription id for create a database.',
77
type: Number,
88
})
99
@IsNumber()
1010
@IsNotEmpty()
11-
planId: number;
11+
subscriptionId: number;
1212
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsNotEmpty, IsNumber } from 'class-validator';
3+
4+
export class CreateSubscriptionAndDatabaseCloudJobDataDto {
5+
@ApiProperty({
6+
description: 'Plan id for create a subscription.',
7+
type: Number,
8+
})
9+
@IsNumber()
10+
@IsNotEmpty()
11+
planId: number;
12+
}

redisinsight/api/src/modules/cloud/job/dto/create.cloud-job.dto.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@ import { cloudJobDataTransformer } from 'src/modules/cloud/job/transformers/clou
1313
import { CloudJobName } from 'src/modules/cloud/job/constants';
1414
import { CloudJobRunMode } from 'src/modules/cloud/job/models';
1515
import { CreateDatabaseCloudJobDataDto } from 'src/modules/cloud/job/dto/create-database.cloud-job.data.dto';
16+
import {
17+
CreateSubscriptionAndDatabaseCloudJobDataDto,
18+
} from 'src/modules/cloud/job/dto/create-subscription-and-database.cloud-job.data.dto';
19+
import { ImportDatabaseCloudJobDataDto } from 'src/modules/cloud/job/dto/import-database.cloud-job.data.dto';
1620

17-
@ApiExtraModels(CreateDatabaseCloudJobDataDto)
21+
@ApiExtraModels(
22+
CreateDatabaseCloudJobDataDto, CreateSubscriptionAndDatabaseCloudJobDataDto, ImportDatabaseCloudJobDataDto,
23+
)
1824
export class CreateCloudJobDto {
1925
@ApiProperty({
2026
description: 'Job name to create',
@@ -38,12 +44,14 @@ export class CreateCloudJobDto {
3844
description: 'Any data for create a job.',
3945
oneOf: [
4046
{ $ref: getSchemaPath(CreateDatabaseCloudJobDataDto) },
47+
{ $ref: getSchemaPath(CreateSubscriptionAndDatabaseCloudJobDataDto) },
48+
{ $ref: getSchemaPath(ImportDatabaseCloudJobDataDto) },
4149
],
4250
})
4351
@Expose()
4452
@IsOptional()
4553
@IsNotEmptyObject()
4654
@Type(cloudJobDataTransformer)
4755
@ValidateNested()
48-
data?: CreateDatabaseCloudJobDataDto;
56+
data?: CreateDatabaseCloudJobDataDto | CreateSubscriptionAndDatabaseCloudJobDataDto | ImportDatabaseCloudJobDataDto;
4957
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { ApiProperty } from '@nestjs/swagger';
2+
import { IsNotEmpty, IsNumber } from 'class-validator';
3+
4+
export class ImportDatabaseCloudJobDataDto {
5+
@ApiProperty({
6+
description: 'Subscription id of database',
7+
type: Number,
8+
})
9+
@IsNumber()
10+
@IsNotEmpty()
11+
subscriptionId: number;
12+
13+
@ApiProperty({
14+
description: 'Database id to import',
15+
type: Number,
16+
})
17+
@IsNumber()
18+
@IsNotEmpty()
19+
databaseId: number;
20+
}

redisinsight/api/src/modules/cloud/job/exceptions/cloud-database-already-exists-free.exception.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@ import ERROR_MESSAGES from 'src/constants/error-messages';
33
import { CustomErrorCodes } from 'src/constants';
44

55
export class CloudDatabaseAlreadyExistsFreeException extends HttpException {
6-
constructor(message = ERROR_MESSAGES.CLOUD_DATABASE_ALREADY_EXISTS_FREE, options?: HttpExceptionOptions) {
6+
constructor(
7+
message = ERROR_MESSAGES.CLOUD_DATABASE_ALREADY_EXISTS_FREE,
8+
options?: HttpExceptionOptions & { subscriptionId?: number, databaseId?: number },
9+
) {
710
const response = {
811
message,
912
statusCode: HttpStatus.CONFLICT,
1013
error: 'CloudDatabaseAlreadyExistsFree',
1114
errorCode: CustomErrorCodes.CloudDatabaseAlreadyExistsFree,
15+
resource: {
16+
subscriptionId: options?.subscriptionId,
17+
databaseId: options?.databaseId,
18+
},
1219
};
1320

1421
super(response, response.statusCode, options);

0 commit comments

Comments
 (0)