Skip to content

Commit 5b02a83

Browse files
Merge pull request #3659 from RedisInsight/feature/RI-5955-auto-load-demo-data-for-cloud-databases
RI-5955 auto-load data for empty free cloud database
2 parents 70a7882 + 921a8c0 commit 5b02a83

File tree

14 files changed

+121
-11
lines changed

14 files changed

+121
-11
lines changed

redisinsight/api/src/__mocks__/databases.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export const mockDatabaseSentinelMasterPasswordEncrypted = 'database.sentinelMas
2929

3030
export const mockDatabaseSentinelMasterPasswordPlain = 'some sentinel pass';
3131

32+
export const mockDBSize = 1;
33+
3234
export const mockDatabase = Object.assign(new Database(), {
3335
id: mockDatabaseId,
3436
name: 'database-name',
@@ -275,6 +277,7 @@ export const mockDatabaseInfoProvider = jest.fn(() => ({
275277
determineSentinelMasterGroups: jest.fn().mockReturnValue([mockSentinelMasterDto]),
276278
determineClusterNodes: jest.fn().mockResolvedValue(mockClusterNodes),
277279
getRedisGeneralInfo: jest.fn().mockResolvedValueOnce(mockRedisGeneralInfo),
280+
getRedisDBSize: jest.fn().mockResolvedValue(mockDBSize),
278281
getClientListInfo: jest.fn().mockReturnValue(mockRedisClientListResult),
279282
}));
280283

redisinsight/api/src/modules/bulk-actions/bulk-actions.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,9 @@ import { BulkImportService } from 'src/modules/bulk-actions/bulk-import.service'
1515
BulkActionsAnalytics,
1616
BulkImportService,
1717
],
18+
exports: [
19+
BulkImportService,
20+
BulkActionsAnalytics,
21+
],
1822
})
1923
export class BulkActionsModule {}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { CloudDatabaseAnalytics } from 'src/modules/cloud/database/cloud-databas
1717
import { CloudRequestUtm } from 'src/modules/cloud/common/models';
1818
import { CloudCapiKeyService } from 'src/modules/cloud/capi-key/cloud-capi-key.service';
1919
import { CloudSubscriptionApiService } from 'src/modules/cloud/subscription/cloud-subscription.api.service';
20+
import { BulkImportService } from 'src/modules/bulk-actions/bulk-import.service';
21+
import { DatabaseInfoService } from 'src/modules/database/database-info.service';
2022

2123
@Injectable()
2224
export class CloudJobFactory {
@@ -26,6 +28,8 @@ export class CloudJobFactory {
2628
private readonly cloudTaskCapiService: CloudTaskCapiService,
2729
private readonly cloudDatabaseAnalytics: CloudDatabaseAnalytics,
2830
private readonly databaseService: DatabaseService,
31+
private readonly databaseInfoService: DatabaseInfoService,
32+
private readonly bulkImportService: BulkImportService,
2933
private readonly cloudCapiKeyService: CloudCapiKeyService,
3034
private readonly cloudSubscriptionApiService: CloudSubscriptionApiService,
3135
) {}
@@ -54,6 +58,8 @@ export class CloudJobFactory {
5458
cloudTaskCapiService: this.cloudTaskCapiService,
5559
cloudDatabaseAnalytics: this.cloudDatabaseAnalytics,
5660
databaseService: this.databaseService,
61+
databaseInfoService: this.databaseInfoService,
62+
bulkImportService: this.bulkImportService,
5763
cloudCapiKeyService: this.cloudCapiKeyService,
5864
cloudSubscriptionApiService: this.cloudSubscriptionApiService,
5965
},
@@ -71,6 +77,8 @@ export class CloudJobFactory {
7177
cloudTaskCapiService: this.cloudTaskCapiService,
7278
cloudDatabaseAnalytics: this.cloudDatabaseAnalytics,
7379
databaseService: this.databaseService,
80+
databaseInfoService: this.databaseInfoService,
81+
bulkImportService: this.bulkImportService,
7482
cloudCapiKeyService: this.cloudCapiKeyService,
7583
},
7684
);

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ import { CloudJobController } from 'src/modules/cloud/job/cloud-job.controller';
44
import { CloudJobService } from 'src/modules/cloud/job/cloud-job.service';
55
import { CloudSubscriptionModule } from 'src/modules/cloud/subscription/cloud-subscription.module';
66
import { CloudDatabaseModule } from 'src/modules/cloud/database/cloud-database.module';
7-
import { CloudUserModule } from 'src/modules/cloud/user/cloud-user.module';
87
import { CloudJobFactory } from 'src/modules/cloud/job/cloud-job.factory';
98
import { CloudJobProvider } from 'src/modules/cloud/job/cloud-job.provider';
109
import { CloudJobGateway } from 'src/modules/cloud/job/cloud-job.gateway';
1110
import { CloudCapiKeyModule } from 'src/modules/cloud/capi-key/cloud-capi-key.module';
11+
import { BulkImportService } from 'src/modules/bulk-actions/bulk-import.service';
12+
import { BulkActionsAnalytics } from 'src/modules/bulk-actions/bulk-actions.analytics';
1213

1314
@Module({
1415
imports: [
@@ -22,6 +23,8 @@ import { CloudCapiKeyModule } from 'src/modules/cloud/capi-key/cloud-capi-key.mo
2223
CloudJobFactory,
2324
CloudJobProvider,
2425
CloudJobGateway,
26+
BulkImportService,
27+
BulkActionsAnalytics,
2528
],
2629
controllers: [CloudJobController],
2730
})

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import { Database } from 'src/modules/database/models/database';
1919
import config from 'src/utils/config';
2020
import { CloudDatabaseAnalytics } from 'src/modules/cloud/database/cloud-database.analytics';
2121
import { CloudCapiKeyService } from 'src/modules/cloud/capi-key/cloud-capi-key.service';
22+
import { BulkImportService } from 'src/modules/bulk-actions/bulk-import.service';
23+
import { ClientContext } from 'src/common/models';
24+
import { DatabaseInfoService } from 'src/modules/database/database-info.service';
2225

2326
const cloudConfig = config.get('cloud');
2427

@@ -36,6 +39,8 @@ export class CreateFreeDatabaseCloudJob extends CloudJob {
3639
cloudTaskCapiService: CloudTaskCapiService,
3740
cloudDatabaseAnalytics: CloudDatabaseAnalytics,
3841
databaseService: DatabaseService,
42+
databaseInfoService: DatabaseInfoService,
43+
bulkImportService: BulkImportService,
3944
cloudCapiKeyService: CloudCapiKeyService,
4045
},
4146
) {
@@ -128,6 +133,22 @@ export class CreateFreeDatabaseCloudJob extends CloudJob {
128133
timeout: cloudConfig.cloudDatabaseConnectionTimeout,
129134
});
130135

136+
try {
137+
const clientMetadata = {
138+
databaseId: database.id,
139+
sessionMetadata: this.options.sessionMetadata,
140+
context: ClientContext.Common,
141+
db: database.db,
142+
};
143+
const dbSize = await this.dependencies.databaseInfoService.getDBSize(clientMetadata);
144+
145+
if (dbSize === 0) {
146+
this.dependencies.bulkImportService.importDefaultData(clientMetadata);
147+
}
148+
} catch (e) {
149+
this.logger.error('Error when trying to feed the db with default data');
150+
}
151+
131152
this.result = {
132153
resourceId: database.id,
133154
region: freeSubscription?.region,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { Database } from 'src/modules/database/models/database';
1111
import { CloudDatabaseAnalytics } from 'src/modules/cloud/database/cloud-database.analytics';
1212
import { CloudCapiKeyService } from 'src/modules/cloud/capi-key/cloud-capi-key.service';
1313
import { CloudSubscription } from 'src/modules/cloud/subscription/models';
14+
import { DatabaseInfoService } from 'src/modules/database/database-info.service';
15+
import { BulkImportService } from 'src/modules/bulk-actions/bulk-import.service';
1416
import { CloudSubscriptionApiService } from '../../subscription/cloud-subscription.api.service';
1517
import { CloudSubscriptionPlanResponse } from '../../subscription/dto';
1618

@@ -31,6 +33,8 @@ export class CreateFreeSubscriptionAndDatabaseCloudJob extends CloudJob {
3133
cloudTaskCapiService: CloudTaskCapiService,
3234
cloudDatabaseAnalytics: CloudDatabaseAnalytics,
3335
databaseService: DatabaseService,
36+
databaseInfoService: DatabaseInfoService,
37+
bulkImportService: BulkImportService,
3438
cloudCapiKeyService: CloudCapiKeyService,
3539
cloudSubscriptionApiService: CloudSubscriptionApiService,
3640
},

redisinsight/api/src/modules/database/database-info.service.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
mockDatabaseOverviewProvider,
88
mockDatabaseRecommendationService,
99
mockDatabaseService,
10+
mockDBSize,
1011
mockRedisGeneralInfo,
1112
mockStandaloneRedisClient,
1213
MockType,
@@ -73,6 +74,12 @@ describe('DatabaseInfoService', () => {
7374
});
7475
});
7576

77+
describe('getDBSize', () => {
78+
it('should create client and gets db size', async () => {
79+
expect(await service.getDBSize(mockCommonClientMetadata)).toEqual(mockDBSize);
80+
});
81+
});
82+
7683
describe('getDatabaseIndex', () => {
7784
it('should not return a new client', async () => {
7885
expect(await service.getDatabaseIndex(mockCommonClientMetadata, 0)).toEqual(undefined);

redisinsight/api/src/modules/database/database-info.service.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ export class DatabaseInfoService {
5050
return this.databaseOverviewProvider.getOverview(clientMetadata, client);
5151
}
5252

53+
/**
54+
* Get redis database number of keys
55+
*
56+
* @param clientMetadata
57+
*/
58+
async getDBSize(clientMetadata: ClientMetadata): Promise<number> {
59+
const client: RedisClient = await this.databaseClientFactory.getOrCreateClient(clientMetadata);
60+
61+
return this.databaseInfoProvider.getRedisDBSize(client);
62+
}
63+
5364
/**
5465
* Create connection to specified database index
5566
*

redisinsight/api/src/modules/database/providers/database-info.provider.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,29 @@ describe('DatabaseInfoProvider', () => {
308308
});
309309
});
310310

311+
describe('getRedisDBSize', () => {
312+
it('get dbsize for redis standalone', async () => {
313+
when(standaloneClient.sendCommand)
314+
.calledWith(['dbsize'], { replyEncoding: 'utf8' })
315+
.mockResolvedValue('1');
316+
317+
const result = await service.getRedisDBSize(standaloneClient);
318+
expect(result).toEqual(1);
319+
});
320+
321+
it('get general info for redis cluster', async () => {
322+
clusterClient.nodes.mockResolvedValueOnce([standaloneClient, standaloneClient]);
323+
when(standaloneClient.sendCommand)
324+
.calledWith(['dbsize'], { replyEncoding: 'utf8' })
325+
.mockResolvedValueOnce('1')
326+
.mockResolvedValueOnce('2');
327+
328+
const result = await service.getRedisDBSize(clusterClient);
329+
330+
expect(result).toEqual(3);
331+
});
332+
});
333+
311334
describe('getRedisGeneralInfo', () => {
312335
beforeEach(() => {
313336
service.getDatabasesCount = jest.fn().mockResolvedValue(16);

redisinsight/api/src/modules/database/providers/database-info.provider.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,16 @@ export class DatabaseInfoProvider {
110110
return await this.filterRawModules(modules);
111111
}
112112

113+
public async getRedisDBSize(client: RedisClient): Promise<number> {
114+
if (client.getConnectionType() === RedisClientConnectionType.CLUSTER) {
115+
const nodesResult: number[] = await Promise.all(
116+
(await client.nodes()).map(async (node) => this.getRedisNodeDBSize(node)),
117+
);
118+
return nodesResult.reduce((ac, cur) => ac + cur, 0);
119+
}
120+
return await this.getRedisNodeDBSize(client);
121+
}
122+
113123
public async getRedisGeneralInfo(
114124
client: RedisClient,
115125
): Promise<RedisDatabaseInfoResponse> {
@@ -238,4 +248,15 @@ export class DatabaseInfoProvider {
238248
return undefined;
239249
}
240250
}
251+
252+
private async getRedisNodeDBSize(client: RedisClient): Promise<number> {
253+
try {
254+
const total = await client.sendCommand(['dbsize'], {
255+
replyEncoding: 'utf8',
256+
}) as string;
257+
return parseInt(total, 10);
258+
} catch (e) {
259+
throw catchAclError(e);
260+
}
261+
}
241262
}

0 commit comments

Comments
 (0)