Skip to content

Commit de8f7ab

Browse files
authored
Merge pull request #1776 from RedisInsight/feature/RI-4141_Data_decompressors
#RI-4141 - Data decompressors
2 parents c941cf6 + 3cd8d5e commit de8f7ab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+962
-92
lines changed

jest.config.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ module.exports = {
5454
],
5555
coverageThreshold: {
5656
global: {
57-
statements: 77,
58-
branches: 55,
59-
functions: 65,
60-
lines: 75,
57+
statements: 78,
58+
branches: 61,
59+
functions: 70,
60+
lines: 79,
6161
},
6262
// './redisinsight/ui/src/slices/**/*.ts': {
6363
// statements: 90,

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
"@types/electron-store": "^3.2.0",
119119
"@types/express": "^4.17.3",
120120
"@types/file-saver": "^2.0.5",
121+
"@types/gzip-js": "^0.3.3",
121122
"@types/html-entities": "^1.3.4",
122123
"@types/ioredis": "^4.26.0",
123124
"@types/is-glob": "^4.0.2",
@@ -217,6 +218,7 @@
217218
"@elastic/eui": "34.6.0",
218219
"@msgpack/msgpack": "^2.7.2",
219220
"@reduxjs/toolkit": "^1.6.2",
221+
"@stablelib/snappy": "^1.0.2",
220222
"axios": "^0.25.0",
221223
"buffer": "^6.0.3",
222224
"classnames": "^2.3.1",
@@ -230,12 +232,15 @@
230232
"electron-updater": "^5.0.5",
231233
"file-saver": "^2.0.5",
232234
"formik": "^2.2.9",
235+
"fzstd": "^0.1.0",
236+
"gzip-js": "^0.3.2",
233237
"html-entities": "^2.3.2",
234238
"html-react-parser": "^1.2.4",
235239
"java-object-serialization": "^0.1.1",
236240
"jpickle": "^0.4.1",
237241
"jsonpath": "^1.1.1",
238242
"lodash": "^4.17.21",
243+
"lz4js": "^0.2.0",
239244
"php-serialize": "^4.0.2",
240245
"rawproto": "^0.7.6",
241246
"react": "^18.2.0",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { MigrationInterface, QueryRunner } from "typeorm";
2+
3+
export class databaseCompressor1678182722874 implements MigrationInterface {
4+
name = 'databaseCompressor1678182722874'
5+
6+
public async up(queryRunner: QueryRunner): Promise<void> {
7+
await queryRunner.query(`CREATE TABLE "temporary_database_instance" ("id" varchar PRIMARY KEY NOT NULL, "host" varchar NOT NULL, "port" integer NOT NULL, "name" varchar NOT NULL, "username" varchar, "password" varchar, "tls" boolean, "verifyServerCert" boolean, "lastConnection" datetime, "caCertId" varchar, "clientCertId" varchar, "connectionType" varchar NOT NULL DEFAULT ('STANDALONE'), "nodes" varchar DEFAULT ('[]'), "nameFromProvider" varchar, "sentinelMasterName" varchar, "sentinelMasterUsername" varchar, "sentinelMasterPassword" varchar, "provider" varchar DEFAULT ('UNKNOWN'), "modules" varchar NOT NULL DEFAULT ('[]'), "db" integer, "encryption" varchar, "tlsServername" varchar, "new" boolean, "ssh" boolean, "timeout" integer, "compressor" varchar NOT NULL DEFAULT ('NONE'), CONSTRAINT "FK_d1bc747b5938e22b4b708d8e9a5" FOREIGN KEY ("caCertId") REFERENCES "ca_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, CONSTRAINT "FK_3b9b625266c00feb2d66a9f36e4" FOREIGN KEY ("clientCertId") REFERENCES "client_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION)`);
8+
await queryRunner.query(`INSERT INTO "temporary_database_instance"("id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername", "new", "ssh", "timeout") SELECT "id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername", "new", "ssh", "timeout" FROM "database_instance"`);
9+
await queryRunner.query(`DROP TABLE "database_instance"`);
10+
await queryRunner.query(`ALTER TABLE "temporary_database_instance" RENAME TO "database_instance"`);
11+
}
12+
13+
public async down(queryRunner: QueryRunner): Promise<void> {
14+
await queryRunner.query(`ALTER TABLE "database_instance" RENAME TO "temporary_database_instance"`);
15+
await queryRunner.query(`CREATE TABLE "database_instance" ("id" varchar PRIMARY KEY NOT NULL, "host" varchar NOT NULL, "port" integer NOT NULL, "name" varchar NOT NULL, "username" varchar, "password" varchar, "tls" boolean, "verifyServerCert" boolean, "lastConnection" datetime, "caCertId" varchar, "clientCertId" varchar, "connectionType" varchar NOT NULL DEFAULT ('STANDALONE'), "nodes" varchar DEFAULT ('[]'), "nameFromProvider" varchar, "sentinelMasterName" varchar, "sentinelMasterUsername" varchar, "sentinelMasterPassword" varchar, "provider" varchar DEFAULT ('UNKNOWN'), "modules" varchar NOT NULL DEFAULT ('[]'), "db" integer, "encryption" varchar, "tlsServername" varchar, "new" boolean, "ssh" boolean, "timeout" integer, CONSTRAINT "FK_d1bc747b5938e22b4b708d8e9a5" FOREIGN KEY ("caCertId") REFERENCES "ca_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION, CONSTRAINT "FK_3b9b625266c00feb2d66a9f36e4" FOREIGN KEY ("clientCertId") REFERENCES "client_certificate" ("id") ON DELETE SET NULL ON UPDATE NO ACTION)`);
16+
await queryRunner.query(`INSERT INTO "database_instance"("id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername", "new", "ssh", "timeout") SELECT "id", "host", "port", "name", "username", "password", "tls", "verifyServerCert", "lastConnection", "caCertId", "clientCertId", "connectionType", "nodes", "nameFromProvider", "sentinelMasterName", "sentinelMasterUsername", "sentinelMasterPassword", "provider", "modules", "db", "encryption", "tlsServername", "new", "ssh", "timeout" FROM "temporary_database_instance"`);
17+
await queryRunner.query(`DROP TABLE "temporary_database_instance"`);
18+
}
19+
20+
}

redisinsight/api/migration/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { workbenchAndAnalysisDbIndex1673934231410 } from './1673934231410-workbe
2727
import { browserHistory1674539211397 } from './1674539211397-browser-history';
2828
import { databaseAnalysisRecommendations1674660306971 } from './1674660306971-database-analysis-recommendations';
2929
import { databaseTimeout1675398140189 } from './1675398140189-database-timeout';
30+
import { databaseCompressor1678182722874 } from './1678182722874-database-compressor';
3031

3132
export default [
3233
initialMigration1614164490968,
@@ -58,4 +59,5 @@ export default [
5859
databaseAnalysisRecommendations1674660306971,
5960
browserHistory1674539211397,
6061
databaseTimeout1675398140189,
62+
databaseCompressor1678182722874,
6163
];

redisinsight/api/src/__mocks__/databases.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Database } from 'src/modules/database/models/database';
22
import { mockCaCertificate, mockClientCertificate } from 'src/__mocks__/certificates';
33
import { SentinelMaster } from 'src/modules/redis-sentinel/models/sentinel-master';
4-
import { ConnectionType, DatabaseEntity } from 'src/modules/database/entities/database.entity';
4+
import { Compressor, ConnectionType, DatabaseEntity } from 'src/modules/database/entities/database.entity';
55
import { EncryptionStrategy } from 'src/modules/encryption/models';
66
import { mockIORedisClient } from 'src/__mocks__/redis';
77
import { mockSentinelMasterDto } from 'src/__mocks__/redis-sentinel';
@@ -34,6 +34,7 @@ export const mockDatabase = Object.assign(new Database(), {
3434
connectionType: ConnectionType.STANDALONE,
3535
timeout: 30_000,
3636
new: false,
37+
compressor: Compressor.NONE,
3738
});
3839

3940
export const mockDatabaseEntity = Object.assign(new DatabaseEntity(), {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ describe('DatabaseAnalytics', () => {
104104
numberOfModules: 0,
105105
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
106106
databaseIndex: 0,
107+
useDecompression: mockDatabaseWithTlsAuth.compressor,
107108
...DEFAULT_REDIS_MODULES_SUMMARY,
108109
},
109110
);
@@ -134,6 +135,7 @@ describe('DatabaseAnalytics', () => {
134135
numberOfModules: 0,
135136
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
136137
databaseIndex: 0,
138+
useDecompression: mockDatabaseWithTlsAuth.compressor,
137139
...DEFAULT_REDIS_MODULES_SUMMARY,
138140
},
139141
);
@@ -166,6 +168,7 @@ describe('DatabaseAnalytics', () => {
166168
numberOfModules: 2,
167169
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
168170
databaseIndex: 0,
171+
useDecompression: mockDatabaseWithTlsAuth.compressor,
169172
...DEFAULT_REDIS_MODULES_SUMMARY,
170173
RediSearch: {
171174
loaded: true,
@@ -204,6 +207,7 @@ describe('DatabaseAnalytics', () => {
204207
numberOfModules: 2,
205208
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
206209
databaseIndex: 2,
210+
useDecompression: mockDatabaseWithTlsAuth.compressor,
207211
...DEFAULT_REDIS_MODULES_SUMMARY,
208212
RediSearch: {
209213
loaded: true,
@@ -240,6 +244,7 @@ describe('DatabaseAnalytics', () => {
240244
useSNI: 'enabled',
241245
useSSH: 'disabled',
242246
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
247+
useDecompression: mockDatabaseWithTlsAuth.compressor,
243248
previousValues: {
244249
connectionType: prev.connectionType,
245250
provider: prev.provider,
@@ -275,6 +280,7 @@ describe('DatabaseAnalytics', () => {
275280
useSNI: 'enabled',
276281
useSSH: 'disabled',
277282
timeout: mockDatabaseWithTlsAuth.timeout / 1_000, // milliseconds to seconds
283+
useDecompression: mockDatabaseWithTlsAuth.compressor,
278284
previousValues: {
279285
connectionType: prev.connectionType,
280286
provider: prev.provider,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export class DatabaseAnalytics extends TelemetryBaseService {
6767
numberOfModules: instance.modules?.length || 0,
6868
timeout: instance.timeout / 1_000, // milliseconds to seconds
6969
databaseIndex: instance.db || 0,
70+
useDecompression: instance.compressor || null,
7071
...modulesSummary,
7172
},
7273
);
@@ -100,6 +101,7 @@ export class DatabaseAnalytics extends TelemetryBaseService {
100101
useSNI: cur?.tlsServername ? 'enabled' : 'disabled',
101102
useSSH: cur?.ssh ? 'enabled' : 'disabled',
102103
timeout: cur?.timeout / 1_000, // milliseconds to seconds
104+
useDecompression: cur?.compressor || null,
103105
previousValues: {
104106
connectionType: prev.connectionType,
105107
provider: prev.provider,

redisinsight/api/src/modules/database/dto/create.database.dto.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { sshOptionsTransformer } from 'src/modules/ssh/transformers/ssh-options.
2323
)
2424
export class CreateDatabaseDto extends PickType(Database, [
2525
'host', 'port', 'name', 'db', 'username', 'password', 'timeout', 'nameFromProvider', 'provider',
26-
'tls', 'tlsServername', 'verifyServerCert', 'sentinelMaster', 'ssh',
26+
'tls', 'tlsServername', 'verifyServerCert', 'sentinelMaster', 'ssh', 'compressor',
2727
] as const) {
2828
@ApiPropertyOptional({
2929
description: 'CA Certificate',

redisinsight/api/src/modules/database/dto/update.database.dto.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ApiPropertyOptional, getSchemaPath } from '@nestjs/swagger';
22
import {
33
IsBoolean,
4+
IsEnum,
45
IsInt, IsNotEmpty, IsNotEmptyObject, IsOptional, IsString, MaxLength, Min, ValidateIf, ValidateNested,
56
} from 'class-validator';
67
import { CreateCaCertificateDto } from 'src/modules/certificate/dto/create.ca-certificate.dto';
@@ -16,6 +17,7 @@ import { CreateDatabaseDto } from 'src/modules/database/dto/create.database.dto'
1617
import { CreateBasicSshOptionsDto } from 'src/modules/ssh/dto/create.basic-ssh-options.dto';
1718
import { CreateCertSshOptionsDto } from 'src/modules/ssh/dto/create.cert-ssh-options.dto';
1819
import { sshOptionsTransformer } from 'src/modules/ssh/transformers/ssh-options.transformer';
20+
import { Compressor } from '../entities/database.entity';
1921

2022
export class UpdateDatabaseDto extends CreateDatabaseDto {
2123
@ValidateIf((object, value) => value !== undefined)
@@ -157,4 +159,14 @@ export class UpdateDatabaseDto extends CreateDatabaseDto {
157159
@ValidateNested()
158160
@Default(null)
159161
sshOptions?: CreateBasicSshOptionsDto | CreateCertSshOptionsDto;
162+
163+
@ApiPropertyOptional({
164+
description: 'Database compressor',
165+
default: Compressor.NONE,
166+
enum: Compressor,
167+
})
168+
@Expose()
169+
@IsEnum(Compressor)
170+
@IsOptional()
171+
compressor?: Compressor = Compressor.NONE;
160172
}

redisinsight/api/src/modules/database/entities/database.entity.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ export enum ConnectionType {
2525
NOT_CONNECTED = 'NOT CONNECTED',
2626
}
2727

28+
export enum Compressor {
29+
NONE = 'NONE',
30+
GZIP = 'GZIP',
31+
ZSTD = 'ZSTD',
32+
LZ4 = 'LZ4',
33+
SNAPPY = 'SNAPPY',
34+
}
35+
2836
@Entity('database_instance')
2937
export class DatabaseEntity {
3038
@Expose()
@@ -184,4 +192,11 @@ export class DatabaseEntity {
184192
)
185193
@Type(() => SshOptionsEntity)
186194
sshOptions: SshOptionsEntity;
195+
196+
@Expose()
197+
@Column({
198+
nullable: false,
199+
default: Compressor.NONE,
200+
})
201+
compressor: Compressor;
187202
}

0 commit comments

Comments
 (0)