Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions redisinsight/api/src/constants/redis-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export enum AdditionalRedisModuleName {
RedisJSON = 'ReJSON',
RediSearch = 'search',
RedisTimeSeries = 'timeseries',
'Triggers & Functions' = 'redisgears'
}

export enum AdditionalSearchModuleName {
Expand All @@ -14,6 +15,11 @@ export enum AdditionalSearchModuleName {
FTL = 'ftl',
}

export enum AdditionalTriggersAndFunctionsModuleName {
TriggersAndFunctions = 'redisgears',
TriggersAndFunctions2 = 'redisgears_2',
}

export const SUPPORTED_REDIS_MODULES = Object.freeze({
ai: AdditionalRedisModuleName.RedisAI,
graph: AdditionalRedisModuleName.RedisGraph,
Expand Down Expand Up @@ -60,3 +66,8 @@ export const REDISEARCH_MODULES: string[] = [
AdditionalSearchModuleName.FT,
AdditionalSearchModuleName.FTL,
]

export const TRIGGERED_AND_FUNCTIONS_MODULES: string[] = [
AdditionalTriggersAndFunctionsModuleName.TriggersAndFunctions,
AdditionalTriggersAndFunctionsModuleName.TriggersAndFunctions2,
]
3 changes: 3 additions & 0 deletions redisinsight/api/src/utils/redis-modules-summary.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const DEFAULT_SUMMARY = Object.freeze(
RedisBloom: { loaded: false },
RedisJSON: { loaded: false },
RedisTimeSeries: { loaded: false },
'Triggers & Functions': { loaded: false },
customModules: [],
},
);
Expand Down Expand Up @@ -43,6 +44,7 @@ const getRedisModulesSummaryTests = [
{ name: 'ReJSON', version: 10000, semanticVersion: '1.0.0' },
{ name: 'search', version: 10000, semanticVersion: '1.0.0' },
{ name: 'timeseries', version: 10000, semanticVersion: '1.0.0' },
{ name: 'redisgears_2', version: 10000, semanticVersion: '1.0.0' },
],
expected: {
RedisAI: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
Expand All @@ -52,6 +54,7 @@ const getRedisModulesSummaryTests = [
RedisJSON: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
RediSearch: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
RedisTimeSeries: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
'Triggers & Functions': { loaded: true, version: 10000, semanticVersion: '1.0.0' },
customModules: [],
},
},
Expand Down
49 changes: 41 additions & 8 deletions redisinsight/api/src/utils/redis-modules-summary.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { cloneDeep } from 'lodash';
import { AdditionalRedisModuleName, SUPPORTED_REDIS_MODULES } from 'src/constants';
import {
AdditionalRedisModuleName,
SUPPORTED_REDIS_MODULES,
REDISEARCH_MODULES,
TRIGGERED_AND_FUNCTIONS_MODULES,
} from 'src/constants';
import { AdditionalRedisModule } from 'src/modules/database/models/additional.redis.module';

interface IModuleSummary {
Expand All @@ -19,30 +24,58 @@ export const DEFAULT_SUMMARY: IRedisModulesSummary = Object.freeze(
RedisBloom: { loaded: false },
RedisJSON: { loaded: false },
RedisTimeSeries: { loaded: false },
'Triggers & Functions': { loaded: false },
customModules: [],
},
);

export const isRedisearchAvailable = (modules: AdditionalRedisModule[]): boolean => (
modules?.some(({ name }) => REDISEARCH_MODULES.some((search) => name === search))
);

export const isTriggeredAndFunctionsAvailable = (modules: AdditionalRedisModule[]): boolean => (
modules?.some(({ name }) => TRIGGERED_AND_FUNCTIONS_MODULES.some((value) => name === value))
);

const getEnumKeyBValue = (myEnum: any, enumValue: number | string): string => {
const keys = Object.keys(myEnum);
const index = keys.findIndex((x) => myEnum[x] === enumValue);
return index > -1 ? keys[index] : '';
};

const getModuleSummaryToSent = (module: AdditionalRedisModule) => ({
loaded: true,
version: module.version,
semanticVersion: module.semanticVersion,
});

// same function as in FE
export const getRedisModulesSummary = (modules: AdditionalRedisModule[] = []): IRedisModulesSummary => {
const summary = cloneDeep(DEFAULT_SUMMARY);
try {
modules.forEach(((module) => {
if (SUPPORTED_REDIS_MODULES[module.name]) {
const moduleName = getEnumKeyBValue(AdditionalRedisModuleName, module.name);
summary[moduleName] = {
loaded: true,
version: module.version,
semanticVersion: module.semanticVersion,
};
} else {
summary.customModules.push(module);
summary[moduleName] = getModuleSummaryToSent(module);
return;
}

if (isRedisearchAvailable([module])) {
const redisearchName = getEnumKeyBValue(AdditionalRedisModuleName, AdditionalRedisModuleName.RediSearch);
summary[redisearchName] = getModuleSummaryToSent(module);
return;
}

if (isTriggeredAndFunctionsAvailable([module])) {
const triggeredAndFunctionsName = getEnumKeyBValue(
AdditionalRedisModuleName,
AdditionalRedisModuleName['Triggers & Functions'],
);
summary[triggeredAndFunctionsName] = getModuleSummaryToSent(module);
return;
}

summary.customModules.push(module);
}));
} catch (e) {
// continue regardless of error
Expand Down
14 changes: 14 additions & 0 deletions redisinsight/ui/src/assets/img/modules/RedisGears2Dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions redisinsight/ui/src/assets/img/modules/RedisGears2Light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import RedisBloomLight from 'uiSrc/assets/img/modules/RedisBloomLight.svg'
import RedisBloomDark from 'uiSrc/assets/img/modules/RedisBloomDark.svg'
import RedisGearsLight from 'uiSrc/assets/img/modules/RedisGearsLight.svg'
import RedisGearsDark from 'uiSrc/assets/img/modules/RedisGearsDark.svg'
import RedisGears2Light from 'uiSrc/assets/img/modules/RedisGears2Light.svg'
import RedisGears2Dark from 'uiSrc/assets/img/modules/RedisGears2Dark.svg'
import RedisGraphLight from 'uiSrc/assets/img/modules/RedisGraphLight.svg'
import RedisGraphDark from 'uiSrc/assets/img/modules/RedisGraphDark.svg'
import RedisJSONLight from 'uiSrc/assets/img/modules/RedisJSONLight.svg'
Expand Down Expand Up @@ -69,6 +71,16 @@ export const modulesDefaultInit = {
iconLight: RedisGraphLight,
text: DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.Graph],
},
[RedisDefaultModules.RedisGears]: {
iconDark: RedisGearsDark,
iconLight: RedisGearsLight,
text: DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.RedisGears],
},
[RedisDefaultModules.RedisGears2]: {
iconDark: RedisGears2Dark,
iconLight: RedisGears2Light,
text: DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.RedisGears2],
},
[RedisDefaultModules.ReJSON]: {
iconDark: RedisJSONDark,
iconLight: RedisJSONLight,
Expand Down
9 changes: 8 additions & 1 deletion redisinsight/ui/src/slices/interfaces/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,11 @@ export const REDISEARCH_MODULES: string[] = [
RedisDefaultModules.FTL,
]

export const TRIGGERED_AND_FUNCTIONS_MODULES: string[] = [
RedisDefaultModules.RedisGears,
RedisDefaultModules.RedisGears2,
]

export const COMMAND_MODULES = {
[RedisDefaultModules.Search]: REDISEARCH_MODULES,
[RedisDefaultModules.ReJSON]: [RedisDefaultModules.ReJSON],
Expand All @@ -188,6 +193,7 @@ export const COMMAND_MODULES = {
}

const RediSearchModulesText = [...REDISEARCH_MODULES].reduce((prev, next) => ({ ...prev, [next]: 'RediSearch' }), {})
const TriggeredAndFunctionsModulesText = [...TRIGGERED_AND_FUNCTIONS_MODULES].reduce((prev, next) => ({ ...prev, [next]: 'Triggers & Functions' }), {})

// Enums don't allow to use dynamic key
export const DATABASE_LIST_MODULES_TEXT = Object.freeze({
Expand All @@ -199,7 +205,8 @@ export const DATABASE_LIST_MODULES_TEXT = Object.freeze({
[RedisDefaultModules.TimeSeries]: 'RedisTimeSeries',
[RedisCustomModulesName.Proto]: 'redis-protobuf',
[RedisCustomModulesName.IpTables]: 'RedisPushIpTables',
...RediSearchModulesText
...RediSearchModulesText,
...TriggeredAndFunctionsModulesText,
})

export enum AddRedisClusterDatabaseOptions {
Expand Down
7 changes: 5 additions & 2 deletions redisinsight/ui/src/telemetry/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@ export enum RedisModules {
RedisJSON = 'ReJSON',
RediSearch = 'search',
RedisTimeSeries = 'timeseries',
'Triggers & Functions' = 'redisgears'
}

interface IModuleSummary {
export interface IModuleSummary {
loaded: boolean
version?: number
semanticVersion?: number
semanticVersion?: string
}

export type RedisModulesKeyType = keyof typeof RedisModules
export interface IRedisModulesSummary extends Record<keyof typeof RedisModules, IModuleSummary> {
customModules: AdditionalRedisModule[]
}
3 changes: 3 additions & 0 deletions redisinsight/ui/src/telemetry/telemetryUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const DEFAULT_SUMMARY = Object.freeze(
RedisBloom: { loaded: false },
RedisJSON: { loaded: false },
RedisTimeSeries: { loaded: false },
'Triggers & Functions': { loaded: false },
customModules: [],
},
)
Expand Down Expand Up @@ -43,6 +44,7 @@ const getRedisModulesSummaryTests = [
{ name: 'ReJSON', version: 10000, semanticVersion: '1.0.0' },
{ name: 'search', version: 10000, semanticVersion: '1.0.0' },
{ name: 'timeseries', version: 10000, semanticVersion: '1.0.0' },
{ name: 'redisgears_2', version: 10000, semanticVersion: '1.0.0' },
],
expected: {
RedisAI: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
Expand All @@ -52,6 +54,7 @@ const getRedisModulesSummaryTests = [
RedisJSON: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
RediSearch: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
RedisTimeSeries: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
'Triggers & Functions': { loaded: true, version: 10000, semanticVersion: '1.0.0' },
customModules: [],
},
},
Expand Down
28 changes: 17 additions & 11 deletions redisinsight/ui/src/telemetry/telemetryUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
import isGlob from 'is-glob'
import { cloneDeep } from 'lodash'
import * as jsonpath from 'jsonpath'
import { isRedisearchAvailable, Nullable } from 'uiSrc/utils'
import { isRedisearchAvailable, isTriggeredAndFunctionsAvailable, Nullable } from 'uiSrc/utils'
import { localStorageService } from 'uiSrc/services'
import { ApiEndpoints, BrowserStorageItem, KeyTypes, StreamViews } from 'uiSrc/constants'
import { KeyViewType } from 'uiSrc/slices/interfaces/keys'
import { StreamViewType } from 'uiSrc/slices/interfaces/stream'
import { checkIsAnalyticsGranted, getInfoServer } from 'uiSrc/telemetry/checkAnalytics'
import { IModuleSummary, RedisModulesKeyType } from 'uiSrc/telemetry/interfaces'
import { AdditionalRedisModule } from 'apiSrc/modules/database/models/additional.redis.module'
import {
ITelemetrySendEvent,
Expand Down Expand Up @@ -219,6 +220,7 @@ const DEFAULT_SUMMARY: IRedisModulesSummary = Object.freeze(
RedisBloom: { loaded: false },
RedisJSON: { loaded: false },
RedisTimeSeries: { loaded: false },
'Triggers & Functions': { loaded: false },
customModules: [],
},
)
Expand All @@ -229,27 +231,31 @@ const getEnumKeyBValue = (myEnum: any, enumValue: number | string): string => {
return index > -1 ? keys[index] : ''
}

const getModuleSummaryToSent = (module: AdditionalRedisModule): IModuleSummary => ({
loaded: true,
version: module.version,
semanticVersion: module.semanticVersion,
})

const getRedisModulesSummary = (modules: AdditionalRedisModule[] = []): IRedisModulesSummary => {
const summary = cloneDeep(DEFAULT_SUMMARY)
try {
modules.forEach(((module) => {
if (SUPPORTED_REDIS_MODULES[module.name]) {
const moduleName = getEnumKeyBValue(RedisModules, module.name)
summary[moduleName] = {
loaded: true,
version: module.version,
semanticVersion: module.semanticVersion,
}
summary[moduleName as RedisModulesKeyType] = getModuleSummaryToSent(module)
return
}

if (isRedisearchAvailable([module])) {
const redisearchName = getEnumKeyBValue(RedisModules, RedisModules.RediSearch)
summary[redisearchName] = {
loaded: true,
version: module.version,
semanticVersion: module.semanticVersion,
}
summary[redisearchName as RedisModulesKeyType] = getModuleSummaryToSent(module)
return
}

if (isTriggeredAndFunctionsAvailable([module])) {
const triggeredAndFunctionsName = getEnumKeyBValue(RedisModules, RedisModules['Triggers & Functions'])
summary[triggeredAndFunctionsName as RedisModulesKeyType] = getModuleSummaryToSent(module)
return
}

Expand Down
6 changes: 5 additions & 1 deletion redisinsight/ui/src/utils/modules.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DATABASE_LIST_MODULES_TEXT, RedisDefaultModules, REDISEARCH_MODULES } from 'uiSrc/slices/interfaces'
import { DATABASE_LIST_MODULES_TEXT, RedisDefaultModules, REDISEARCH_MODULES, TRIGGERED_AND_FUNCTIONS_MODULES } from 'uiSrc/slices/interfaces'
import { AdditionalRedisModule } from 'apiSrc/modules/database/models/additional.redis.module'

export interface IDatabaseModule {
Expand Down Expand Up @@ -41,5 +41,9 @@ export const isRedisearchAvailable = (modules: AdditionalRedisModule[]): boolean
modules?.some(({ name }) =>
REDISEARCH_MODULES.some((search) => name === search))

export const isTriggeredAndFunctionsAvailable = (modules: AdditionalRedisModule[]): boolean =>
modules?.some(({ name }) =>
TRIGGERED_AND_FUNCTIONS_MODULES.some((value) => name === value))

export const isContainJSONModule = (modules: AdditionalRedisModule[]): boolean =>
modules?.some((m: AdditionalRedisModule) => m.name === RedisDefaultModules.ReJSON)