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
77 changes: 39 additions & 38 deletions redisinsight/ui/src/utils/redistack.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,68 @@
import { isArray, map, concat } from 'lodash'
import { isArray, map, concat, remove, find } from 'lodash'
import { Instance, RedisDefaultModules } from 'uiSrc/slices/interfaces'
import { isVersionHigherOrEquals, Nullable } from 'uiSrc/utils'

const REDISTACK_LOW_VERSION = '6.2.6'
const REDISTACK_HIGH_VERSION = '7.1'
const REDISTACK_VERSION = '6.2.5'

const REDISTACK_LOW_VERSION_REQUIRE_MODULES: Array<string | Array<string>> = [
RedisDefaultModules.ReJSON,
RedisDefaultModules.Bloom,
RedisDefaultModules.Graph,
[RedisDefaultModules.Search, RedisDefaultModules.SearchLight],
RedisDefaultModules.TimeSeries,
]

const REDISTACK_HIGH_VERSION_REQUIRE_MODULES: Array<string | Array<string>> = [
const REDISTACK_REQUIRE_MODULES: Array<string | Array<string>> = [
RedisDefaultModules.ReJSON,
RedisDefaultModules.Bloom,
[RedisDefaultModules.Search, RedisDefaultModules.SearchLight],
RedisDefaultModules.TimeSeries,
]

const REDISTACK_HIGH_VERSION_OPTIONAL_MODULES: Array<string[]> = [
const REDISTACK_OPTIONAL_MODULES: Array<string | Array<string>> = [
RedisDefaultModules.Graph,
[RedisDefaultModules.RedisGears, RedisDefaultModules.RedisGears2]
]

const checkRediStackModules = (modules: any[], required: any[], optional: any[] = []) => {
const MIN_MODULES_LENGTH = REDISTACK_REQUIRE_MODULES.length
const MAX_MODULES_LENGTH = REDISTACK_REQUIRE_MODULES.length + REDISTACK_OPTIONAL_MODULES.length

const checkRediStackModules = (modules: any[]) => {
if (!modules?.length) return false
const moduleNames = map(modules, 'name').sort()

if (modules.length === required.length) {
return map(modules, 'name')
.sort()
.every((m, index) => (isArray(required[index])
? (required[index] as Array<string>).some((rm) => rm === m)
: required[index] === m))
if (modules.length === MIN_MODULES_LENGTH) {
return moduleNames
.every((m, index) => (isArray(REDISTACK_REQUIRE_MODULES[index])
? (REDISTACK_REQUIRE_MODULES[index] as Array<string>).some((rm) => rm === m)
: REDISTACK_REQUIRE_MODULES[index] === m))
}

if (modules.length === (required.length + optional.length)) {
const rediStackModules = concat(required, optional).sort()
return map(modules, 'name')
.sort()
.every((m, index) => (isArray(rediStackModules[index])
? (rediStackModules[index] as Array<string>).some((rm) => rm === m)
: rediStackModules[index] === m))
if (modules.length > MIN_MODULES_LENGTH
&& modules.length <= (MAX_MODULES_LENGTH)) {
let isCustomModule = false
const rediStackModules = concat(REDISTACK_REQUIRE_MODULES, REDISTACK_OPTIONAL_MODULES).sort()

const diff = rediStackModules.reduce((acc: Array<string>, current: string | Array<string>) => {
const moduleName = isArray(current)
? (current as Array<string>).find((item) => find(moduleNames, (m) => item === m))
: find(moduleNames, (name) => name === current)

if (moduleName) {
remove(acc, (name) => moduleName === name)

return acc
}
isCustomModule = true

return acc
}, moduleNames)

return isCustomModule && !diff.length
}

return false
}

const isRediStack = (modules: any[], version?: Nullable<string>): boolean => {
if (!version) {
return checkRediStackModules(modules, REDISTACK_LOW_VERSION_REQUIRE_MODULES)
}

if (isVersionHigherOrEquals(version, REDISTACK_HIGH_VERSION)) {
return checkRediStackModules(
modules,
REDISTACK_HIGH_VERSION_REQUIRE_MODULES,
REDISTACK_HIGH_VERSION_OPTIONAL_MODULES
)
return checkRediStackModules(modules)
}

if (isVersionHigherOrEquals(version, REDISTACK_LOW_VERSION)) {
return checkRediStackModules(modules, REDISTACK_LOW_VERSION_REQUIRE_MODULES)
if (isVersionHigherOrEquals(version, REDISTACK_VERSION)) {
return checkRediStackModules(modules)
}

return false
Expand Down
61 changes: 38 additions & 23 deletions redisinsight/ui/src/utils/tests/redistack.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,45 @@ import { isRediStack } from 'uiSrc/utils'
const unmapWithName = (arr: any[]) => arr.map((item) => ({ name: item }))

const isRediStackTests = [
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'custom']), '6.2.6'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph', 'custom']), '6.2.6'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph']), '6.2.6'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph'])], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'searchlight']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'redisgears']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'redisgears']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'redisgears_2']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'redisgears_2']), '6.2.5'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'search', 'redisgears_2']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'redisgears_2']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph', 'redisgears_2']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'redisgears']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph', 'redisgears']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph', 'redisgears', 'redisgears_2']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'custom']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'custom']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'redisgears', 'custom']), '6.2.5'], expected: false },

{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'searchlight']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'rg', 'search'])], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph']), '6.2.6'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph']), '6.2.5'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph']), '7.1'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph']), '7.1'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'redisgears', 'searchlight']), '7.1'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'redisgears', 'search']), '7.1'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'redisgears_2', 'searchlight']), '7.1'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'redisgears_2', 'search']), '7.1'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'rg', 'searchlight']), '7.1'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'rg', 'search']), '7.1'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'redisgears_2', 'redisgears', 'search']), '7.1'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight']), '7.1'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search']), '7.1'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search']), '7.1'], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'custom']), '7.1'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'seasearchlightrch', 'custom']), '7.1'], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'redisgears']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'redisgears']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'redisgears_2']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'redisgears_2']), null], expected: true },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'search', 'redisgears_2']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'redisgears_2']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph', 'redisgears_2']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'redisgears']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph', 'redisgears']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'search', 'graph', 'redisgears', 'redisgears_2']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'custom']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'custom']), null], expected: false },
{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight', 'graph', 'redisgears', 'custom']), null], expected: false },

{ input: [unmapWithName(['bf', 'timeseries', 'ReJSON', 'searchlight']), '6.2.4'], expected: false },
]

describe('isRediStack', () => {
Expand Down