Skip to content

Commit 1e51006

Browse files
#RI-3312-update modules (#938)
* #RI-3312-update modules
1 parent c1a63d3 commit 1e51006

File tree

5 files changed

+159
-6
lines changed

5 files changed

+159
-6
lines changed

redisinsight/ui/src/pages/home/components/AddInstanceForm/InstanceForm/InstanceForm.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ import { handlePasteHostName } from 'uiSrc/utils'
5353
import { APPLICATION_NAME, PageNames, Pages } from 'uiSrc/constants'
5454
import { useResizableFormField } from 'uiSrc/services'
5555
import validationErrors from 'uiSrc/constants/validationErrors'
56-
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
56+
import { sendEventTelemetry, TelemetryEvent, getRedisModulesSummary } from 'uiSrc/telemetry'
5757
import { resetKeys } from 'uiSrc/slices/browser/keys'
5858
import { appContextSelector, setAppContextInitialState } from 'uiSrc/slices/app/context'
5959
import DatabaseAlias from 'uiSrc/pages/home/components/DatabaseAlias'
@@ -363,12 +363,13 @@ const AddStandaloneForm = (props: Props) => {
363363
}
364364

365365
const handleCheckConnectToInstance = () => {
366+
const modulesSummary = getRedisModulesSummary(modules)
366367
sendEventTelemetry({
367368
event: TelemetryEvent.CONFIG_DATABASES_OPEN_DATABASE_BUTTON_CLICKED,
368369
eventData: {
369370
databaseId: id,
370371
provider,
371-
modules,
372+
...modulesSummary,
372373
}
373374
})
374375
dispatch(checkConnectToInstanceAction(id, connectToInstance))

redisinsight/ui/src/pages/home/components/DatabasesListComponent/DatabasesListWrapper.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
} from 'uiSrc/slices/interfaces'
2727
import { resetKeys } from 'uiSrc/slices/browser/keys'
2828
import { PageNames, Pages, Theme } from 'uiSrc/constants'
29-
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
29+
import { sendEventTelemetry, TelemetryEvent, getRedisModulesSummary } from 'uiSrc/telemetry'
3030
import { ThemeContext } from 'uiSrc/contexts/themeContext'
3131
import { formatLongName, getDbIndex, lastConnectionFormat, Nullable, replaceSpaces } from 'uiSrc/utils'
3232
import { appContextSelector, setAppContextInitialState } from 'uiSrc/slices/app/context'
@@ -125,12 +125,13 @@ const DatabasesListWrapper = ({
125125
{ id, provider, modules }: Instance
126126
) => {
127127
event.preventDefault()
128+
const modulesSummary = getRedisModulesSummary(modules)
128129
sendEventTelemetry({
129130
event: TelemetryEvent.CONFIG_DATABASES_OPEN_DATABASE,
130131
eventData: {
131132
databaseId: id,
132133
provider,
133-
modules,
134+
...modulesSummary,
134135
}
135136
})
136137
dispatch(checkConnectToInstanceAction(id, connectToInstance))

redisinsight/ui/src/telemetry/interfaces.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { RedisModuleDto } from 'apiSrc/modules/instances/dto/database-instance.dto'
12
import { TelemetryEvent } from './events'
23

34
export interface ITelemetryIdentify {
@@ -34,3 +35,22 @@ export enum MatchType {
3435
EXACT_VALUE_NAME = 'EXACT_VALUE_NAME',
3536
PATTERN = 'PATTERN'
3637
}
38+
39+
export enum RedisModules {
40+
RedisAI = 'ai',
41+
RedisGraph = 'graph',
42+
RedisGears = 'rg',
43+
RedisBloom = 'bf',
44+
RedisJSON = 'ReJSON',
45+
RediSearch = 'search',
46+
RedisTimeSeries = 'timeseries',
47+
}
48+
49+
interface IModuleSummary {
50+
loaded: boolean;
51+
version?: number;
52+
semanticVersion?: number;
53+
}
54+
export interface IRedisModulesSummary extends Record<keyof typeof RedisModules, IModuleSummary> {
55+
customModules: RedisModuleDto[]
56+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { getRedisModulesSummary } from './telemetryUtils'
2+
3+
const DEFAULT_SUMMARY = Object.freeze(
4+
{
5+
RediSearch: { loaded: false },
6+
RedisAI: { loaded: false },
7+
RedisGraph: { loaded: false },
8+
RedisGears: { loaded: false },
9+
RedisBloom: { loaded: false },
10+
RedisJSON: { loaded: false },
11+
RedisTimeSeries: { loaded: false },
12+
customModules: [],
13+
},
14+
)
15+
16+
const getRedisModulesSummaryTests = [
17+
{
18+
input: [{ name: 'ai', version: 20000 }],
19+
expected: { ...DEFAULT_SUMMARY, RedisAI: { loaded: true, version: 20000 }, customModules: [] },
20+
},
21+
{
22+
input: [{ name: 'search', version: 10000 }],
23+
expected: { ...DEFAULT_SUMMARY, RediSearch: { loaded: true, version: 10000 } },
24+
},
25+
{
26+
input: [{ name: 'bf', version: 1000 }, { name: 'rediSQL', version: 1 }],
27+
expected: {
28+
...DEFAULT_SUMMARY,
29+
RedisBloom: { loaded: true, version: 1000 },
30+
customModules: [{ name: 'rediSQL', version: 1 }],
31+
},
32+
},
33+
{
34+
input: [{ name: 'ReJSON' }],
35+
expected: { ...DEFAULT_SUMMARY, RedisJSON: { loaded: true } },
36+
},
37+
{
38+
input: [
39+
{ name: 'ai', version: 10000, semanticVersion: '1.0.0' },
40+
{ name: 'graph', version: 20000, semanticVersion: '2.0.0' },
41+
{ name: 'rg', version: 10000, semanticVersion: '1.0.0' },
42+
{ name: 'bf' },
43+
{ name: 'ReJSON', version: 10000, semanticVersion: '1.0.0' },
44+
{ name: 'search', version: 10000, semanticVersion: '1.0.0' },
45+
{ name: 'timeseries', version: 10000, semanticVersion: '1.0.0' },
46+
],
47+
expected: {
48+
RedisAI: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
49+
RedisGraph: { loaded: true, version: 20000, semanticVersion: '2.0.0' },
50+
RedisGears: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
51+
RedisBloom: { loaded: true },
52+
RedisJSON: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
53+
RediSearch: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
54+
RedisTimeSeries: { loaded: true, version: 10000, semanticVersion: '1.0.0' },
55+
customModules: [],
56+
},
57+
},
58+
{ input: [], expected: DEFAULT_SUMMARY },
59+
{ input: {}, expected: DEFAULT_SUMMARY },
60+
{ input: undefined, expected: DEFAULT_SUMMARY },
61+
{ input: null, expected: DEFAULT_SUMMARY },
62+
{ input: 1, expected: DEFAULT_SUMMARY },
63+
]
64+
65+
describe('getRedisModulesSummary', () => {
66+
test.each(getRedisModulesSummaryTests)('%j', ({ input, expected }) => {
67+
// @ts-ignore
68+
const result = getRedisModulesSummary(input)
69+
expect(result).toEqual(expected)
70+
})
71+
})

redisinsight/ui/src/telemetry/telemetryUtils.ts

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,23 @@
33
* This module abstracts the exact service/framework used for tracking usage.
44
*/
55
import isGlob from 'is-glob'
6+
import { cloneDeep } from 'lodash'
67
import * as jsonpath from 'jsonpath'
78
import { Nullable } from 'uiSrc/utils'
89
import { localStorageService } from 'uiSrc/services'
910
import { ApiEndpoints, BrowserStorageItem, KeyTypes, StreamViews } from 'uiSrc/constants'
1011
import { KeyViewType } from 'uiSrc/slices/interfaces/keys'
1112
import { StreamViewType } from 'uiSrc/slices/interfaces/stream'
1213
import { checkIsAnalyticsGranted, getAppType } from 'uiSrc/telemetry/checkAnalytics'
13-
import { ITelemetrySendEvent, ITelemetrySendPageView, ITelemetryService, MatchType } from './interfaces'
14+
import { RedisModuleDto } from 'apiSrc/modules/instances/dto/database-instance.dto'
15+
import {
16+
ITelemetrySendEvent,
17+
ITelemetrySendPageView,
18+
ITelemetryService,
19+
IRedisModulesSummary,
20+
MatchType,
21+
RedisModules,
22+
} from './interfaces'
1423
import { TelemetryEvent } from './events'
1524
import { NON_TRACKING_ANONYMOUS_ID, SegmentTelemetryService } from './segment'
1625

@@ -179,6 +188,56 @@ export const getRefreshEventData = (eventData: any, type: string, streamViewType
179188
return eventData
180189
}
181190

191+
const SUPPORTED_REDIS_MODULES = Object.freeze({
192+
ai: RedisModules.RedisAI,
193+
graph: RedisModules.RedisGraph,
194+
rg: RedisModules.RedisGears,
195+
bf: RedisModules.RedisBloom,
196+
ReJSON: RedisModules.RedisJSON,
197+
search: RedisModules.RediSearch,
198+
timeseries: RedisModules.RedisTimeSeries,
199+
})
200+
201+
const DEFAULT_SUMMARY: IRedisModulesSummary = Object.freeze(
202+
{
203+
RediSearch: { loaded: false },
204+
RedisAI: { loaded: false },
205+
RedisGraph: { loaded: false },
206+
RedisGears: { loaded: false },
207+
RedisBloom: { loaded: false },
208+
RedisJSON: { loaded: false },
209+
RedisTimeSeries: { loaded: false },
210+
customModules: [],
211+
},
212+
)
213+
214+
const getEnumKeyBValue = (myEnum: any, enumValue: number | string): string => {
215+
const keys = Object.keys(myEnum)
216+
const index = keys.findIndex((x) => myEnum[x] === enumValue)
217+
return index > -1 ? keys[index] : ''
218+
}
219+
220+
const getRedisModulesSummary = (modules: RedisModuleDto[] = []): IRedisModulesSummary => {
221+
const summary = cloneDeep(DEFAULT_SUMMARY)
222+
try {
223+
modules.forEach(((module) => {
224+
if (SUPPORTED_REDIS_MODULES[module.name]) {
225+
const moduleName = getEnumKeyBValue(RedisModules, module.name)
226+
summary[moduleName] = {
227+
loaded: true,
228+
version: module.version,
229+
semanticVersion: module.semanticVersion,
230+
}
231+
} else {
232+
summary.customModules.push(module)
233+
}
234+
}))
235+
} catch (e) {
236+
// continue regardless of error
237+
}
238+
return summary
239+
}
240+
182241
export {
183242
getTelemetryService,
184243
sendEventTelemetry,
@@ -187,5 +246,6 @@ export {
187246
getBasedOnViewTypeEvent,
188247
getJsonPathLevel,
189248
getAdditionalAddedEventData,
190-
getMatchType
249+
getMatchType,
250+
getRedisModulesSummary
191251
}

0 commit comments

Comments
 (0)