From 093fa0c3d7f2a5877385906f2bcb84f2493f1dca Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Thu, 19 Oct 2023 14:55:11 +0200 Subject: [PATCH 1/2] Redis: use pre-existing command instances instead of using Command.create() This is more idiomatic and prevents troubles with Redis cluster where the Vert.x Redis client needs to know the key affected by the command in order to route the command to the correct cluster node. That works correctly with pre-existing `Command` instances and will _not_ work correctly with `Command.create()` until the Vert.x Redis client itself is fixed. --- .../datasource/AbstractListCommands.java | 11 +++----- .../datasource/AbstractSetCommands.java | 6 ++-- .../datasource/AbstractSortedSetCommands.java | 28 ++++++++----------- .../datasource/AbstractStringCommands.java | 6 ++-- .../redis/datasource/CustomCommandsTest.java | 9 +++--- 5 files changed, 24 insertions(+), 36 deletions(-) diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractListCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractListCommands.java index 51aa71db4f0b0..ad1625e60ec1f 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractListCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractListCommands.java @@ -26,9 +26,6 @@ class AbstractListCommands extends ReactiveSortable { protected static final LPosArgs DEFAULT_INSTANCE = new LPosArgs(); - public static final Command LMPOP = Command.create("lmpop"); - public static final Command BLMPOP = Command.create("blmpop"); - AbstractListCommands(RedisCommandExecutor redis, Type k, Type v) { super(redis, new Marshaller(k, v), v); this.typeOfKey = k; @@ -59,7 +56,7 @@ Uni _blmpop(Duration timeout, Position position, K... keys) { notNullOrEmpty(keys, "keys"); doesNotContainNull(keys, "keys"); validate(timeout, "timeout"); - RedisCommand cmd = RedisCommand.of(BLMPOP); + RedisCommand cmd = RedisCommand.of(Command.BLMPOP); cmd.put(timeout.toSeconds()); cmd.put(keys.length); cmd.putAll(marshaller.encode(keys)); @@ -97,7 +94,7 @@ Uni _blmpop(Duration timeout, Position position, int count, K... keys) validate(timeout, "timeout"); positive(count, "count"); - RedisCommand cmd = RedisCommand.of(BLMPOP); + RedisCommand cmd = RedisCommand.of(Command.BLMPOP); cmd.put(timeout.toSeconds()); cmd.put(keys.length); cmd.putAll(marshaller.encode(keys)); @@ -203,7 +200,7 @@ Uni _lmpop(Position position, K... keys) { notNullOrEmpty(keys, "keys"); doesNotContainNull(keys, "keys"); - RedisCommand cmd = RedisCommand.of(LMPOP); + RedisCommand cmd = RedisCommand.of(Command.LMPOP); cmd.put(keys.length); cmd.putAll(marshaller.encode(keys)); cmd.put(position.name()); @@ -216,7 +213,7 @@ Uni _lmpop(Position position, int count, K... keys) { doesNotContainNull(keys, "keys"); positive(count, "count"); - RedisCommand cmd = RedisCommand.of(LMPOP); + RedisCommand cmd = RedisCommand.of(Command.LMPOP); cmd.put(keys.length); cmd.putAll(marshaller.encode(keys)); cmd.put(position.name()); diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSetCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSetCommands.java index 6ab4e7a52b845..0f9339509d401 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSetCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSetCommands.java @@ -17,8 +17,6 @@ class AbstractSetCommands extends ReactiveSortable { protected final Type typeOfValue; - public static final Command SINTERCARD = Command.create("sintercard"); - AbstractSetCommands(RedisCommandExecutor redis, Type k, Type v) { super(redis, new Marshaller(k, v), v); this.typeOfValue = v; @@ -80,7 +78,7 @@ Uni _sintercard(K... keys) { throw new IllegalArgumentException("`keys` must contain at least 2 keys"); } - RedisCommand cmd = RedisCommand.of(SINTERCARD).put(keys.length).putAll(marshaller.encode(keys)); + RedisCommand cmd = RedisCommand.of(Command.SINTERCARD).put(keys.length).putAll(marshaller.encode(keys)); return execute(cmd); } @@ -94,7 +92,7 @@ Uni _sintercard(int limit, K... keys) { throw new IllegalArgumentException("`keys` must contain at least 2 keys"); } - RedisCommand cmd = RedisCommand.of(SINTERCARD).put(keys.length).putAll(marshaller.encode(keys)) + RedisCommand cmd = RedisCommand.of(Command.SINTERCARD).put(keys.length).putAll(marshaller.encode(keys)) .put("LIMIT").put(limit); return execute(cmd); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java index ee014247dd5e0..4321e723e1517 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractSortedSetCommands.java @@ -39,10 +39,6 @@ class AbstractSortedSetCommands extends ReactiveSortable { protected static final ZAggregateArgs DEFAULT_INSTANCE_AGG = new ZAggregateArgs(); protected static final ZRangeArgs DEFAULT_INSTANCE_RANGE = new ZRangeArgs(); - public static final Command ZINTERCARD = Command.create("zintercard"); - public static final Command ZMPOP = Command.create("zmpop"); - public static final Command BZMPOP = Command.create("bzmpop"); - AbstractSortedSetCommands(RedisCommandExecutor redis, Type k, Type v) { super(redis, new Marshaller(k, v), v); this.typeOfValue = v; @@ -237,7 +233,7 @@ Uni _zintercard(K... keys) { if (keys.length < 2) { throw new IllegalArgumentException("Need at least two keys"); } - RedisCommand cmd = RedisCommand.of(ZINTERCARD) + RedisCommand cmd = RedisCommand.of(Command.ZINTERCARD) .put(keys.length); for (K key : keys) { @@ -254,7 +250,7 @@ Uni _zintercard(long limit, K... keys) { throw new IllegalArgumentException("Need at least two keys"); } positive(limit, "limit"); - RedisCommand cmd = RedisCommand.of(ZINTERCARD) + RedisCommand cmd = RedisCommand.of(Command.ZINTERCARD) .put(keys.length); for (K key : keys) { @@ -301,7 +297,7 @@ Uni _zlexcount(K key, Range range) { Uni _zmpopMin(K... keys) { notNullOrEmpty(keys, "keys"); doesNotContainNull(keys, "keys"); - RedisCommand cmd = RedisCommand.of(ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MIN"); + RedisCommand cmd = RedisCommand.of(Command.ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MIN"); return execute(cmd); } @@ -309,15 +305,15 @@ Uni _zmpopMin(int count, K... keys) { notNullOrEmpty(keys, "keys"); doesNotContainNull(keys, "keys"); positive(count, "count"); - RedisCommand cmd = RedisCommand.of(ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MIN").put("COUNT") - .put(count); + RedisCommand cmd = RedisCommand.of(Command.ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MIN") + .put("COUNT").put(count); return execute(cmd); } Uni _zmpopMax(K... keys) { notNullOrEmpty(keys, "keys"); doesNotContainNull(keys, "keys"); - RedisCommand cmd = RedisCommand.of(ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MAX"); + RedisCommand cmd = RedisCommand.of(Command.ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MAX"); return execute(cmd); } @@ -325,8 +321,8 @@ Uni _zmpopMax(int count, K... keys) { notNullOrEmpty(keys, "keys"); doesNotContainNull(keys, "keys"); positive(count, "count"); - RedisCommand cmd = RedisCommand.of(ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MAX").put("COUNT") - .put(count); + RedisCommand cmd = RedisCommand.of(Command.ZMPOP).put(keys.length).putAll(marshaller.encode(keys)).put("MAX") + .put("COUNT").put(count); return execute(cmd); } @@ -335,7 +331,7 @@ Uni _bzmpopMin(Duration timeout, K... keys) { doesNotContainNull(keys, "keys"); validate(timeout, "timeout"); - RedisCommand cmd = RedisCommand.of(BZMPOP).put(timeout.toSeconds()) + RedisCommand cmd = RedisCommand.of(Command.BZMPOP).put(timeout.toSeconds()) .put(keys.length).putAll(marshaller.encode(keys)).put("MIN"); return execute(cmd); } @@ -345,7 +341,7 @@ Uni _bzmpopMin(Duration timeout, int count, K... keys) { doesNotContainNull(keys, "keys"); validate(timeout, "timeout"); - RedisCommand cmd = RedisCommand.of(BZMPOP).put(timeout.toSeconds()) + RedisCommand cmd = RedisCommand.of(Command.BZMPOP).put(timeout.toSeconds()) .put(keys.length).putAll(marshaller.encode(keys)).put("MIN").put("COUNT").put(count); return execute(cmd); } @@ -355,7 +351,7 @@ Uni _bzmpopMax(Duration timeout, K... keys) { doesNotContainNull(keys, "keys"); validate(timeout, "timeout"); - RedisCommand cmd = RedisCommand.of(BZMPOP).put(timeout.toSeconds()) + RedisCommand cmd = RedisCommand.of(Command.BZMPOP).put(timeout.toSeconds()) .put(keys.length).putAll(marshaller.encode(keys)).put("MAX"); return execute(cmd); } @@ -365,7 +361,7 @@ Uni _bzmpopMax(Duration timeout, int count, K... keys) { doesNotContainNull(keys, "keys"); validate(timeout, "timeout"); - RedisCommand cmd = RedisCommand.of(BZMPOP).put(timeout.toSeconds()) + RedisCommand cmd = RedisCommand.of(Command.BZMPOP).put(timeout.toSeconds()) .put(keys.length).putAll(marshaller.encode(keys)).put("MAX").put("COUNT").put(count); return execute(cmd); } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java index fd741433e0156..be4ca05428d9f 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/AbstractStringCommands.java @@ -19,8 +19,6 @@ class AbstractStringCommands extends AbstractRedisCommands { protected final Type typeOfValue; - public static final Command LCS = Command.create("lcs"); - AbstractStringCommands(RedisCommandExecutor redis, Type k, Type v) { super(redis, new Marshaller(k, v)); this.typeOfValue = v; @@ -254,13 +252,13 @@ Uni _lcs(K key1, K key2) { nonNull(key1, "key1"); nonNull(key2, "key2"); - return execute(RedisCommand.of(LCS).put(marshaller.encode(key1)).put(marshaller.encode(key2))); + return execute(RedisCommand.of(Command.LCS).put(marshaller.encode(key1)).put(marshaller.encode(key2))); } Uni _lcsLength(K key1, K key2) { nonNull(key1, "key1"); nonNull(key2, "key2"); - return execute(RedisCommand.of(LCS).put(marshaller.encode(key1)).put(marshaller.encode(key2)).put("LEN")); + return execute(RedisCommand.of(Command.LCS).put(marshaller.encode(key1)).put(marshaller.encode(key2)).put("LEN")); } } diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CustomCommandsTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CustomCommandsTest.java index 1f6f8d25f26c9..b24cb697d01c0 100644 --- a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CustomCommandsTest.java +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CustomCommandsTest.java @@ -34,21 +34,20 @@ public void clear() { @Test void testWithMutinyCommand() { - Command cmd = Command.create("hset"); - Response response = ds.execute("hset", key, "field", "hello"); + Response response = ds.execute(Command.HSET, key, "field", "hello"); Assertions.assertThat(response).isNotNull(); Assertions.assertThat(ds.hash(String.class, String.class, String.class).hget(key, "field")).isEqualTo("hello"); } @Test void testBare() { - Command cmd = Command.create("hset"); + Command cmd = Command.HSET; redis.send(Request.cmd(cmd).arg("my-key").arg("my-field").arg("value")).await().indefinitely(); } @Test void testWithBareCommand() { - io.vertx.redis.client.Command cmd = io.vertx.redis.client.Command.create("hset"); + io.vertx.redis.client.Command cmd = io.vertx.redis.client.Command.HSET; ds.execute(cmd, key, "field", "hello-bare"); Assertions.assertThat(ds.hash(String.class, String.class, String.class).hget(key, "field")).isEqualTo("hello-bare"); @@ -56,7 +55,7 @@ void testWithBareCommand() { @Test void testCommandInTransaction() { - TransactionResult result = ds.withTransaction(tx -> tx.execute("hset", key, "a", "b")); + TransactionResult result = ds.withTransaction(tx -> tx.execute(Command.HSET, key, "a", "b")); Assertions.assertThat(ds.hash(String.class, String.class, String.class).hget(key, "a")).isEqualTo("b"); Assertions.assertThat(result.size()).isEqualTo(1); } From 04c98fdd85e9a62ad9b485301481cb90858068b5 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Thu, 19 Oct 2023 14:59:15 +0200 Subject: [PATCH 2/2] Redis: normalize results of `Command.create()` When the `Command.create()` method is used to create a `Command` instance for a known command (not recommended, but also not forbidden), it returns a generic instance that doesn't know anything about where the keys are in the command. Such generic instance is unusable with Redis cluster, because the target node will be selected randomly, not based on the key, and there's high chance such command will result in the `MOVED` redirect. With this commit, we normalize all results of `Command.create()` so that a pre-existing static instance for known commands is used. This is key-aware and works with Redis cluster. This commit adapts a fix submitted to Vert.x Redis client. When we upgrade to a fixed Vert.x Redis client, this commit should be reverted. --- .../redis/runtime/datasource/CommandMap.java | 412 ++++++++++++++++++ .../ReactiveRedisDataSourceImpl.java | 4 +- ...ctiveTransactionalRedisDataSourceImpl.java | 4 +- .../runtime/datasource/RedisCommand.java | 1 + .../datasource/CommandNormalizationTest.java | 27 ++ 5 files changed, 446 insertions(+), 2 deletions(-) create mode 100644 extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/CommandMap.java create mode 100644 extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CommandNormalizationTest.java diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/CommandMap.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/CommandMap.java new file mode 100644 index 0000000000000..9450d0e838774 --- /dev/null +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/CommandMap.java @@ -0,0 +1,412 @@ +package io.quarkus.redis.runtime.datasource; + +import java.util.HashMap; +import java.util.Map; + +// mostly copied from Vert.x Redis client PR: https://github.com/vert-x3/vertx-redis-client/pull/414 +// should be removed when upgrading to Vert.x Redis client which incorporates that PR, +// together with calls to `normalize` which will be a noop at that time +// (see the commit that introduced this class, that can basically be reverted) +class CommandMap { + static io.vertx.mutiny.redis.client.Command normalize(io.vertx.mutiny.redis.client.Command command) { + if (command == null) { + return null; + } + io.vertx.redis.client.Command known = getKnownCommand(command.getDelegate().toString()); + return known != null ? io.vertx.mutiny.redis.client.Command.newInstance(known) : command; + } + + static io.vertx.redis.client.Command normalize(io.vertx.redis.client.Command command) { + if (command == null) { + return null; + } + io.vertx.redis.client.Command known = getKnownCommand(command.toString()); + return known != null ? known : command; + } + + // --- + + private static final Map KNOWN_COMMANDS = new HashMap<>(); + + static io.vertx.redis.client.Command getKnownCommand(String command) { + return command == null ? null : KNOWN_COMMANDS.get(command.toLowerCase()); + } + + // this block is auto-generated + static { + KNOWN_COMMANDS.put("acl", io.vertx.redis.client.Command.ACL); + KNOWN_COMMANDS.put("append", io.vertx.redis.client.Command.APPEND); + KNOWN_COMMANDS.put("asking", io.vertx.redis.client.Command.ASKING); + KNOWN_COMMANDS.put("auth", io.vertx.redis.client.Command.AUTH); + KNOWN_COMMANDS.put("bf.add", io.vertx.redis.client.Command.BF_ADD); + KNOWN_COMMANDS.put("bf.debug", io.vertx.redis.client.Command.BF_DEBUG); + KNOWN_COMMANDS.put("bf.exists", io.vertx.redis.client.Command.BF_EXISTS); + KNOWN_COMMANDS.put("bf.info", io.vertx.redis.client.Command.BF_INFO); + KNOWN_COMMANDS.put("bf.insert", io.vertx.redis.client.Command.BF_INSERT); + KNOWN_COMMANDS.put("bf.loadchunk", io.vertx.redis.client.Command.BF_LOADCHUNK); + KNOWN_COMMANDS.put("bf.madd", io.vertx.redis.client.Command.BF_MADD); + KNOWN_COMMANDS.put("bf.mexists", io.vertx.redis.client.Command.BF_MEXISTS); + KNOWN_COMMANDS.put("bf.reserve", io.vertx.redis.client.Command.BF_RESERVE); + KNOWN_COMMANDS.put("bf.scandump", io.vertx.redis.client.Command.BF_SCANDUMP); + KNOWN_COMMANDS.put("bgrewriteaof", io.vertx.redis.client.Command.BGREWRITEAOF); + KNOWN_COMMANDS.put("bgsave", io.vertx.redis.client.Command.BGSAVE); + KNOWN_COMMANDS.put("bitcount", io.vertx.redis.client.Command.BITCOUNT); + KNOWN_COMMANDS.put("bitfield", io.vertx.redis.client.Command.BITFIELD); + KNOWN_COMMANDS.put("bitfield_ro", io.vertx.redis.client.Command.BITFIELD_RO); + KNOWN_COMMANDS.put("bitop", io.vertx.redis.client.Command.BITOP); + KNOWN_COMMANDS.put("bitpos", io.vertx.redis.client.Command.BITPOS); + KNOWN_COMMANDS.put("blmove", io.vertx.redis.client.Command.BLMOVE); + KNOWN_COMMANDS.put("blmpop", io.vertx.redis.client.Command.BLMPOP); + KNOWN_COMMANDS.put("blpop", io.vertx.redis.client.Command.BLPOP); + KNOWN_COMMANDS.put("brpop", io.vertx.redis.client.Command.BRPOP); + KNOWN_COMMANDS.put("brpoplpush", io.vertx.redis.client.Command.BRPOPLPUSH); + KNOWN_COMMANDS.put("bzmpop", io.vertx.redis.client.Command.BZMPOP); + KNOWN_COMMANDS.put("bzpopmax", io.vertx.redis.client.Command.BZPOPMAX); + KNOWN_COMMANDS.put("bzpopmin", io.vertx.redis.client.Command.BZPOPMIN); + KNOWN_COMMANDS.put("cf.add", io.vertx.redis.client.Command.CF_ADD); + KNOWN_COMMANDS.put("cf.addnx", io.vertx.redis.client.Command.CF_ADDNX); + KNOWN_COMMANDS.put("cf.compact", io.vertx.redis.client.Command.CF_COMPACT); + KNOWN_COMMANDS.put("cf.count", io.vertx.redis.client.Command.CF_COUNT); + KNOWN_COMMANDS.put("cf.debug", io.vertx.redis.client.Command.CF_DEBUG); + KNOWN_COMMANDS.put("cf.del", io.vertx.redis.client.Command.CF_DEL); + KNOWN_COMMANDS.put("cf.exists", io.vertx.redis.client.Command.CF_EXISTS); + KNOWN_COMMANDS.put("cf.info", io.vertx.redis.client.Command.CF_INFO); + KNOWN_COMMANDS.put("cf.insert", io.vertx.redis.client.Command.CF_INSERT); + KNOWN_COMMANDS.put("cf.insertnx", io.vertx.redis.client.Command.CF_INSERTNX); + KNOWN_COMMANDS.put("cf.loadchunk", io.vertx.redis.client.Command.CF_LOADCHUNK); + KNOWN_COMMANDS.put("cf.mexists", io.vertx.redis.client.Command.CF_MEXISTS); + KNOWN_COMMANDS.put("cf.reserve", io.vertx.redis.client.Command.CF_RESERVE); + KNOWN_COMMANDS.put("cf.scandump", io.vertx.redis.client.Command.CF_SCANDUMP); + KNOWN_COMMANDS.put("client", io.vertx.redis.client.Command.CLIENT); + KNOWN_COMMANDS.put("cluster", io.vertx.redis.client.Command.CLUSTER); + KNOWN_COMMANDS.put("cms.incrby", io.vertx.redis.client.Command.CMS_INCRBY); + KNOWN_COMMANDS.put("cms.info", io.vertx.redis.client.Command.CMS_INFO); + KNOWN_COMMANDS.put("cms.initbydim", io.vertx.redis.client.Command.CMS_INITBYDIM); + KNOWN_COMMANDS.put("cms.initbyprob", io.vertx.redis.client.Command.CMS_INITBYPROB); + KNOWN_COMMANDS.put("cms.merge", io.vertx.redis.client.Command.CMS_MERGE); + KNOWN_COMMANDS.put("cms.query", io.vertx.redis.client.Command.CMS_QUERY); + KNOWN_COMMANDS.put("command", io.vertx.redis.client.Command.COMMAND); + KNOWN_COMMANDS.put("config", io.vertx.redis.client.Command.CONFIG); + KNOWN_COMMANDS.put("copy", io.vertx.redis.client.Command.COPY); + KNOWN_COMMANDS.put("dbsize", io.vertx.redis.client.Command.DBSIZE); + KNOWN_COMMANDS.put("debug", io.vertx.redis.client.Command.DEBUG); + KNOWN_COMMANDS.put("decr", io.vertx.redis.client.Command.DECR); + KNOWN_COMMANDS.put("decrby", io.vertx.redis.client.Command.DECRBY); + KNOWN_COMMANDS.put("del", io.vertx.redis.client.Command.DEL); + KNOWN_COMMANDS.put("discard", io.vertx.redis.client.Command.DISCARD); + KNOWN_COMMANDS.put("dump", io.vertx.redis.client.Command.DUMP); + KNOWN_COMMANDS.put("echo", io.vertx.redis.client.Command.ECHO); + KNOWN_COMMANDS.put("eval", io.vertx.redis.client.Command.EVAL); + KNOWN_COMMANDS.put("eval_ro", io.vertx.redis.client.Command.EVAL_RO); + KNOWN_COMMANDS.put("evalsha", io.vertx.redis.client.Command.EVALSHA); + KNOWN_COMMANDS.put("evalsha_ro", io.vertx.redis.client.Command.EVALSHA_RO); + KNOWN_COMMANDS.put("exec", io.vertx.redis.client.Command.EXEC); + KNOWN_COMMANDS.put("exists", io.vertx.redis.client.Command.EXISTS); + KNOWN_COMMANDS.put("expire", io.vertx.redis.client.Command.EXPIRE); + KNOWN_COMMANDS.put("expireat", io.vertx.redis.client.Command.EXPIREAT); + KNOWN_COMMANDS.put("expiretime", io.vertx.redis.client.Command.EXPIRETIME); + KNOWN_COMMANDS.put("failover", io.vertx.redis.client.Command.FAILOVER); + KNOWN_COMMANDS.put("fcall", io.vertx.redis.client.Command.FCALL); + KNOWN_COMMANDS.put("fcall_ro", io.vertx.redis.client.Command.FCALL_RO); + KNOWN_COMMANDS.put("flushall", io.vertx.redis.client.Command.FLUSHALL); + KNOWN_COMMANDS.put("flushdb", io.vertx.redis.client.Command.FLUSHDB); + KNOWN_COMMANDS.put("ft._aliasaddifnx", io.vertx.redis.client.Command.FT__ALIASADDIFNX); + KNOWN_COMMANDS.put("ft._aliasdelifx", io.vertx.redis.client.Command.FT__ALIASDELIFX); + KNOWN_COMMANDS.put("ft._alterifnx", io.vertx.redis.client.Command.FT__ALTERIFNX); + KNOWN_COMMANDS.put("ft._createifnx", io.vertx.redis.client.Command.FT__CREATEIFNX); + KNOWN_COMMANDS.put("ft._dropifx", io.vertx.redis.client.Command.FT__DROPIFX); + KNOWN_COMMANDS.put("ft._dropindexifx", io.vertx.redis.client.Command.FT__DROPINDEXIFX); + KNOWN_COMMANDS.put("ft._list", io.vertx.redis.client.Command.FT__LIST); + KNOWN_COMMANDS.put("ft.add", io.vertx.redis.client.Command.FT_ADD); + KNOWN_COMMANDS.put("ft.aggregate", io.vertx.redis.client.Command.FT_AGGREGATE); + KNOWN_COMMANDS.put("ft.aliasadd", io.vertx.redis.client.Command.FT_ALIASADD); + KNOWN_COMMANDS.put("ft.aliasdel", io.vertx.redis.client.Command.FT_ALIASDEL); + KNOWN_COMMANDS.put("ft.aliasupdate", io.vertx.redis.client.Command.FT_ALIASUPDATE); + KNOWN_COMMANDS.put("ft.alter", io.vertx.redis.client.Command.FT_ALTER); + KNOWN_COMMANDS.put("ft.config", io.vertx.redis.client.Command.FT_CONFIG); + KNOWN_COMMANDS.put("ft.create", io.vertx.redis.client.Command.FT_CREATE); + KNOWN_COMMANDS.put("ft.cursor", io.vertx.redis.client.Command.FT_CURSOR); + KNOWN_COMMANDS.put("ft.debug", io.vertx.redis.client.Command.FT_DEBUG); + KNOWN_COMMANDS.put("ft.del", io.vertx.redis.client.Command.FT_DEL); + KNOWN_COMMANDS.put("ft.dictadd", io.vertx.redis.client.Command.FT_DICTADD); + KNOWN_COMMANDS.put("ft.dictdel", io.vertx.redis.client.Command.FT_DICTDEL); + KNOWN_COMMANDS.put("ft.dictdump", io.vertx.redis.client.Command.FT_DICTDUMP); + KNOWN_COMMANDS.put("ft.drop", io.vertx.redis.client.Command.FT_DROP); + KNOWN_COMMANDS.put("ft.dropindex", io.vertx.redis.client.Command.FT_DROPINDEX); + KNOWN_COMMANDS.put("ft.explain", io.vertx.redis.client.Command.FT_EXPLAIN); + KNOWN_COMMANDS.put("ft.explaincli", io.vertx.redis.client.Command.FT_EXPLAINCLI); + KNOWN_COMMANDS.put("ft.get", io.vertx.redis.client.Command.FT_GET); + KNOWN_COMMANDS.put("ft.info", io.vertx.redis.client.Command.FT_INFO); + KNOWN_COMMANDS.put("ft.mget", io.vertx.redis.client.Command.FT_MGET); + KNOWN_COMMANDS.put("ft.profile", io.vertx.redis.client.Command.FT_PROFILE); + KNOWN_COMMANDS.put("ft.safeadd", io.vertx.redis.client.Command.FT_SAFEADD); + KNOWN_COMMANDS.put("ft.search", io.vertx.redis.client.Command.FT_SEARCH); + KNOWN_COMMANDS.put("ft.spellcheck", io.vertx.redis.client.Command.FT_SPELLCHECK); + KNOWN_COMMANDS.put("ft.sugadd", io.vertx.redis.client.Command.FT_SUGADD); + KNOWN_COMMANDS.put("ft.sugdel", io.vertx.redis.client.Command.FT_SUGDEL); + KNOWN_COMMANDS.put("ft.sugget", io.vertx.redis.client.Command.FT_SUGGET); + KNOWN_COMMANDS.put("ft.suglen", io.vertx.redis.client.Command.FT_SUGLEN); + KNOWN_COMMANDS.put("ft.synadd", io.vertx.redis.client.Command.FT_SYNADD); + KNOWN_COMMANDS.put("ft.syndump", io.vertx.redis.client.Command.FT_SYNDUMP); + KNOWN_COMMANDS.put("ft.synupdate", io.vertx.redis.client.Command.FT_SYNUPDATE); + KNOWN_COMMANDS.put("ft.tagvals", io.vertx.redis.client.Command.FT_TAGVALS); + KNOWN_COMMANDS.put("function", io.vertx.redis.client.Command.FUNCTION); + KNOWN_COMMANDS.put("geoadd", io.vertx.redis.client.Command.GEOADD); + KNOWN_COMMANDS.put("geodist", io.vertx.redis.client.Command.GEODIST); + KNOWN_COMMANDS.put("geohash", io.vertx.redis.client.Command.GEOHASH); + KNOWN_COMMANDS.put("geopos", io.vertx.redis.client.Command.GEOPOS); + KNOWN_COMMANDS.put("georadius", io.vertx.redis.client.Command.GEORADIUS); + KNOWN_COMMANDS.put("georadius_ro", io.vertx.redis.client.Command.GEORADIUS_RO); + KNOWN_COMMANDS.put("georadiusbymember", io.vertx.redis.client.Command.GEORADIUSBYMEMBER); + KNOWN_COMMANDS.put("georadiusbymember_ro", io.vertx.redis.client.Command.GEORADIUSBYMEMBER_RO); + KNOWN_COMMANDS.put("geosearch", io.vertx.redis.client.Command.GEOSEARCH); + KNOWN_COMMANDS.put("geosearchstore", io.vertx.redis.client.Command.GEOSEARCHSTORE); + KNOWN_COMMANDS.put("get", io.vertx.redis.client.Command.GET); + KNOWN_COMMANDS.put("getbit", io.vertx.redis.client.Command.GETBIT); + KNOWN_COMMANDS.put("getdel", io.vertx.redis.client.Command.GETDEL); + KNOWN_COMMANDS.put("getex", io.vertx.redis.client.Command.GETEX); + KNOWN_COMMANDS.put("getrange", io.vertx.redis.client.Command.GETRANGE); + KNOWN_COMMANDS.put("getset", io.vertx.redis.client.Command.GETSET); + KNOWN_COMMANDS.put("graph.bulk", io.vertx.redis.client.Command.GRAPH_BULK); + KNOWN_COMMANDS.put("graph.config", io.vertx.redis.client.Command.GRAPH_CONFIG); + KNOWN_COMMANDS.put("graph.debug", io.vertx.redis.client.Command.GRAPH_DEBUG); + KNOWN_COMMANDS.put("graph.delete", io.vertx.redis.client.Command.GRAPH_DELETE); + KNOWN_COMMANDS.put("graph.explain", io.vertx.redis.client.Command.GRAPH_EXPLAIN); + KNOWN_COMMANDS.put("graph.list", io.vertx.redis.client.Command.GRAPH_LIST); + KNOWN_COMMANDS.put("graph.profile", io.vertx.redis.client.Command.GRAPH_PROFILE); + KNOWN_COMMANDS.put("graph.query", io.vertx.redis.client.Command.GRAPH_QUERY); + KNOWN_COMMANDS.put("graph.ro_query", io.vertx.redis.client.Command.GRAPH_RO_QUERY); + KNOWN_COMMANDS.put("graph.slowlog", io.vertx.redis.client.Command.GRAPH_SLOWLOG); + KNOWN_COMMANDS.put("hdel", io.vertx.redis.client.Command.HDEL); + KNOWN_COMMANDS.put("hello", io.vertx.redis.client.Command.HELLO); + KNOWN_COMMANDS.put("hexists", io.vertx.redis.client.Command.HEXISTS); + KNOWN_COMMANDS.put("hget", io.vertx.redis.client.Command.HGET); + KNOWN_COMMANDS.put("hgetall", io.vertx.redis.client.Command.HGETALL); + KNOWN_COMMANDS.put("hincrby", io.vertx.redis.client.Command.HINCRBY); + KNOWN_COMMANDS.put("hincrbyfloat", io.vertx.redis.client.Command.HINCRBYFLOAT); + KNOWN_COMMANDS.put("hkeys", io.vertx.redis.client.Command.HKEYS); + KNOWN_COMMANDS.put("hlen", io.vertx.redis.client.Command.HLEN); + KNOWN_COMMANDS.put("hmget", io.vertx.redis.client.Command.HMGET); + KNOWN_COMMANDS.put("hmset", io.vertx.redis.client.Command.HMSET); + KNOWN_COMMANDS.put("hrandfield", io.vertx.redis.client.Command.HRANDFIELD); + KNOWN_COMMANDS.put("hscan", io.vertx.redis.client.Command.HSCAN); + KNOWN_COMMANDS.put("hset", io.vertx.redis.client.Command.HSET); + KNOWN_COMMANDS.put("hsetnx", io.vertx.redis.client.Command.HSETNX); + KNOWN_COMMANDS.put("hstrlen", io.vertx.redis.client.Command.HSTRLEN); + KNOWN_COMMANDS.put("hvals", io.vertx.redis.client.Command.HVALS); + KNOWN_COMMANDS.put("incr", io.vertx.redis.client.Command.INCR); + KNOWN_COMMANDS.put("incrby", io.vertx.redis.client.Command.INCRBY); + KNOWN_COMMANDS.put("incrbyfloat", io.vertx.redis.client.Command.INCRBYFLOAT); + KNOWN_COMMANDS.put("info", io.vertx.redis.client.Command.INFO); + KNOWN_COMMANDS.put("json.arrappend", io.vertx.redis.client.Command.JSON_ARRAPPEND); + KNOWN_COMMANDS.put("json.arrindex", io.vertx.redis.client.Command.JSON_ARRINDEX); + KNOWN_COMMANDS.put("json.arrinsert", io.vertx.redis.client.Command.JSON_ARRINSERT); + KNOWN_COMMANDS.put("json.arrlen", io.vertx.redis.client.Command.JSON_ARRLEN); + KNOWN_COMMANDS.put("json.arrpop", io.vertx.redis.client.Command.JSON_ARRPOP); + KNOWN_COMMANDS.put("json.arrtrim", io.vertx.redis.client.Command.JSON_ARRTRIM); + KNOWN_COMMANDS.put("json.clear", io.vertx.redis.client.Command.JSON_CLEAR); + KNOWN_COMMANDS.put("json.debug", io.vertx.redis.client.Command.JSON_DEBUG); + KNOWN_COMMANDS.put("json.del", io.vertx.redis.client.Command.JSON_DEL); + KNOWN_COMMANDS.put("json.forget", io.vertx.redis.client.Command.JSON_FORGET); + KNOWN_COMMANDS.put("json.get", io.vertx.redis.client.Command.JSON_GET); + KNOWN_COMMANDS.put("json.mget", io.vertx.redis.client.Command.JSON_MGET); + KNOWN_COMMANDS.put("json.numincrby", io.vertx.redis.client.Command.JSON_NUMINCRBY); + KNOWN_COMMANDS.put("json.nummultby", io.vertx.redis.client.Command.JSON_NUMMULTBY); + KNOWN_COMMANDS.put("json.numpowby", io.vertx.redis.client.Command.JSON_NUMPOWBY); + KNOWN_COMMANDS.put("json.objkeys", io.vertx.redis.client.Command.JSON_OBJKEYS); + KNOWN_COMMANDS.put("json.objlen", io.vertx.redis.client.Command.JSON_OBJLEN); + KNOWN_COMMANDS.put("json.resp", io.vertx.redis.client.Command.JSON_RESP); + KNOWN_COMMANDS.put("json.set", io.vertx.redis.client.Command.JSON_SET); + KNOWN_COMMANDS.put("json.strappend", io.vertx.redis.client.Command.JSON_STRAPPEND); + KNOWN_COMMANDS.put("json.strlen", io.vertx.redis.client.Command.JSON_STRLEN); + KNOWN_COMMANDS.put("json.toggle", io.vertx.redis.client.Command.JSON_TOGGLE); + KNOWN_COMMANDS.put("json.type", io.vertx.redis.client.Command.JSON_TYPE); + KNOWN_COMMANDS.put("keys", io.vertx.redis.client.Command.KEYS); + KNOWN_COMMANDS.put("lastsave", io.vertx.redis.client.Command.LASTSAVE); + KNOWN_COMMANDS.put("latency", io.vertx.redis.client.Command.LATENCY); + KNOWN_COMMANDS.put("lcs", io.vertx.redis.client.Command.LCS); + KNOWN_COMMANDS.put("lindex", io.vertx.redis.client.Command.LINDEX); + KNOWN_COMMANDS.put("linsert", io.vertx.redis.client.Command.LINSERT); + KNOWN_COMMANDS.put("llen", io.vertx.redis.client.Command.LLEN); + KNOWN_COMMANDS.put("lmove", io.vertx.redis.client.Command.LMOVE); + KNOWN_COMMANDS.put("lmpop", io.vertx.redis.client.Command.LMPOP); + KNOWN_COMMANDS.put("lolwut", io.vertx.redis.client.Command.LOLWUT); + KNOWN_COMMANDS.put("lpop", io.vertx.redis.client.Command.LPOP); + KNOWN_COMMANDS.put("lpos", io.vertx.redis.client.Command.LPOS); + KNOWN_COMMANDS.put("lpush", io.vertx.redis.client.Command.LPUSH); + KNOWN_COMMANDS.put("lpushx", io.vertx.redis.client.Command.LPUSHX); + KNOWN_COMMANDS.put("lrange", io.vertx.redis.client.Command.LRANGE); + KNOWN_COMMANDS.put("lrem", io.vertx.redis.client.Command.LREM); + KNOWN_COMMANDS.put("lset", io.vertx.redis.client.Command.LSET); + KNOWN_COMMANDS.put("ltrim", io.vertx.redis.client.Command.LTRIM); + KNOWN_COMMANDS.put("memory", io.vertx.redis.client.Command.MEMORY); + KNOWN_COMMANDS.put("mget", io.vertx.redis.client.Command.MGET); + KNOWN_COMMANDS.put("migrate", io.vertx.redis.client.Command.MIGRATE); + KNOWN_COMMANDS.put("module", io.vertx.redis.client.Command.MODULE); + KNOWN_COMMANDS.put("monitor", io.vertx.redis.client.Command.MONITOR); + KNOWN_COMMANDS.put("move", io.vertx.redis.client.Command.MOVE); + KNOWN_COMMANDS.put("mset", io.vertx.redis.client.Command.MSET); + KNOWN_COMMANDS.put("msetnx", io.vertx.redis.client.Command.MSETNX); + KNOWN_COMMANDS.put("multi", io.vertx.redis.client.Command.MULTI); + KNOWN_COMMANDS.put("object", io.vertx.redis.client.Command.OBJECT); + KNOWN_COMMANDS.put("persist", io.vertx.redis.client.Command.PERSIST); + KNOWN_COMMANDS.put("pexpire", io.vertx.redis.client.Command.PEXPIRE); + KNOWN_COMMANDS.put("pexpireat", io.vertx.redis.client.Command.PEXPIREAT); + KNOWN_COMMANDS.put("pexpiretime", io.vertx.redis.client.Command.PEXPIRETIME); + KNOWN_COMMANDS.put("pfadd", io.vertx.redis.client.Command.PFADD); + KNOWN_COMMANDS.put("pfcount", io.vertx.redis.client.Command.PFCOUNT); + KNOWN_COMMANDS.put("pfdebug", io.vertx.redis.client.Command.PFDEBUG); + KNOWN_COMMANDS.put("pfmerge", io.vertx.redis.client.Command.PFMERGE); + KNOWN_COMMANDS.put("pfselftest", io.vertx.redis.client.Command.PFSELFTEST); + KNOWN_COMMANDS.put("ping", io.vertx.redis.client.Command.PING); + KNOWN_COMMANDS.put("psetex", io.vertx.redis.client.Command.PSETEX); + KNOWN_COMMANDS.put("psubscribe", io.vertx.redis.client.Command.PSUBSCRIBE); + KNOWN_COMMANDS.put("psync", io.vertx.redis.client.Command.PSYNC); + KNOWN_COMMANDS.put("pttl", io.vertx.redis.client.Command.PTTL); + KNOWN_COMMANDS.put("publish", io.vertx.redis.client.Command.PUBLISH); + KNOWN_COMMANDS.put("pubsub", io.vertx.redis.client.Command.PUBSUB); + KNOWN_COMMANDS.put("punsubscribe", io.vertx.redis.client.Command.PUNSUBSCRIBE); + KNOWN_COMMANDS.put("quit", io.vertx.redis.client.Command.QUIT); + KNOWN_COMMANDS.put("randomkey", io.vertx.redis.client.Command.RANDOMKEY); + KNOWN_COMMANDS.put("readonly", io.vertx.redis.client.Command.READONLY); + KNOWN_COMMANDS.put("readwrite", io.vertx.redis.client.Command.READWRITE); + KNOWN_COMMANDS.put("rename", io.vertx.redis.client.Command.RENAME); + KNOWN_COMMANDS.put("renamenx", io.vertx.redis.client.Command.RENAMENX); + KNOWN_COMMANDS.put("replconf", io.vertx.redis.client.Command.REPLCONF); + KNOWN_COMMANDS.put("replicaof", io.vertx.redis.client.Command.REPLICAOF); + KNOWN_COMMANDS.put("reset", io.vertx.redis.client.Command.RESET); + KNOWN_COMMANDS.put("restore", io.vertx.redis.client.Command.RESTORE); + KNOWN_COMMANDS.put("restore-asking", io.vertx.redis.client.Command.RESTORE_ASKING); + KNOWN_COMMANDS.put("role", io.vertx.redis.client.Command.ROLE); + KNOWN_COMMANDS.put("rpop", io.vertx.redis.client.Command.RPOP); + KNOWN_COMMANDS.put("rpoplpush", io.vertx.redis.client.Command.RPOPLPUSH); + KNOWN_COMMANDS.put("rpush", io.vertx.redis.client.Command.RPUSH); + KNOWN_COMMANDS.put("rpushx", io.vertx.redis.client.Command.RPUSHX); + KNOWN_COMMANDS.put("sadd", io.vertx.redis.client.Command.SADD); + KNOWN_COMMANDS.put("save", io.vertx.redis.client.Command.SAVE); + KNOWN_COMMANDS.put("scan", io.vertx.redis.client.Command.SCAN); + KNOWN_COMMANDS.put("scard", io.vertx.redis.client.Command.SCARD); + KNOWN_COMMANDS.put("script", io.vertx.redis.client.Command.SCRIPT); + KNOWN_COMMANDS.put("sdiff", io.vertx.redis.client.Command.SDIFF); + KNOWN_COMMANDS.put("sdiffstore", io.vertx.redis.client.Command.SDIFFSTORE); + KNOWN_COMMANDS.put("select", io.vertx.redis.client.Command.SELECT); + KNOWN_COMMANDS.put("set", io.vertx.redis.client.Command.SET); + KNOWN_COMMANDS.put("setbit", io.vertx.redis.client.Command.SETBIT); + KNOWN_COMMANDS.put("setex", io.vertx.redis.client.Command.SETEX); + KNOWN_COMMANDS.put("setnx", io.vertx.redis.client.Command.SETNX); + KNOWN_COMMANDS.put("setrange", io.vertx.redis.client.Command.SETRANGE); + KNOWN_COMMANDS.put("shutdown", io.vertx.redis.client.Command.SHUTDOWN); + KNOWN_COMMANDS.put("sinter", io.vertx.redis.client.Command.SINTER); + KNOWN_COMMANDS.put("sintercard", io.vertx.redis.client.Command.SINTERCARD); + KNOWN_COMMANDS.put("sinterstore", io.vertx.redis.client.Command.SINTERSTORE); + KNOWN_COMMANDS.put("sismember", io.vertx.redis.client.Command.SISMEMBER); + KNOWN_COMMANDS.put("slaveof", io.vertx.redis.client.Command.SLAVEOF); + KNOWN_COMMANDS.put("slowlog", io.vertx.redis.client.Command.SLOWLOG); + KNOWN_COMMANDS.put("smembers", io.vertx.redis.client.Command.SMEMBERS); + KNOWN_COMMANDS.put("smismember", io.vertx.redis.client.Command.SMISMEMBER); + KNOWN_COMMANDS.put("smove", io.vertx.redis.client.Command.SMOVE); + KNOWN_COMMANDS.put("sort", io.vertx.redis.client.Command.SORT); + KNOWN_COMMANDS.put("sort_ro", io.vertx.redis.client.Command.SORT_RO); + KNOWN_COMMANDS.put("spop", io.vertx.redis.client.Command.SPOP); + KNOWN_COMMANDS.put("spublish", io.vertx.redis.client.Command.SPUBLISH); + KNOWN_COMMANDS.put("srandmember", io.vertx.redis.client.Command.SRANDMEMBER); + KNOWN_COMMANDS.put("srem", io.vertx.redis.client.Command.SREM); + KNOWN_COMMANDS.put("sscan", io.vertx.redis.client.Command.SSCAN); + KNOWN_COMMANDS.put("ssubscribe", io.vertx.redis.client.Command.SSUBSCRIBE); + KNOWN_COMMANDS.put("strlen", io.vertx.redis.client.Command.STRLEN); + KNOWN_COMMANDS.put("subscribe", io.vertx.redis.client.Command.SUBSCRIBE); + KNOWN_COMMANDS.put("substr", io.vertx.redis.client.Command.SUBSTR); + KNOWN_COMMANDS.put("sunion", io.vertx.redis.client.Command.SUNION); + KNOWN_COMMANDS.put("sunionstore", io.vertx.redis.client.Command.SUNIONSTORE); + KNOWN_COMMANDS.put("sunsubscribe", io.vertx.redis.client.Command.SUNSUBSCRIBE); + KNOWN_COMMANDS.put("swapdb", io.vertx.redis.client.Command.SWAPDB); + KNOWN_COMMANDS.put("sync", io.vertx.redis.client.Command.SYNC); + KNOWN_COMMANDS.put("time", io.vertx.redis.client.Command.TIME); + KNOWN_COMMANDS.put("timeseries.clusterset", io.vertx.redis.client.Command.TIMESERIES_CLUSTERSET); + KNOWN_COMMANDS.put("timeseries.clustersetfromshard", io.vertx.redis.client.Command.TIMESERIES_CLUSTERSETFROMSHARD); + KNOWN_COMMANDS.put("timeseries.hello", io.vertx.redis.client.Command.TIMESERIES_HELLO); + KNOWN_COMMANDS.put("timeseries.infocluster", io.vertx.redis.client.Command.TIMESERIES_INFOCLUSTER); + KNOWN_COMMANDS.put("timeseries.innercommunication", io.vertx.redis.client.Command.TIMESERIES_INNERCOMMUNICATION); + KNOWN_COMMANDS.put("timeseries.networktest", io.vertx.redis.client.Command.TIMESERIES_NETWORKTEST); + KNOWN_COMMANDS.put("timeseries.refreshcluster", io.vertx.redis.client.Command.TIMESERIES_REFRESHCLUSTER); + KNOWN_COMMANDS.put("topk.add", io.vertx.redis.client.Command.TOPK_ADD); + KNOWN_COMMANDS.put("topk.count", io.vertx.redis.client.Command.TOPK_COUNT); + KNOWN_COMMANDS.put("topk.incrby", io.vertx.redis.client.Command.TOPK_INCRBY); + KNOWN_COMMANDS.put("topk.info", io.vertx.redis.client.Command.TOPK_INFO); + KNOWN_COMMANDS.put("topk.list", io.vertx.redis.client.Command.TOPK_LIST); + KNOWN_COMMANDS.put("topk.query", io.vertx.redis.client.Command.TOPK_QUERY); + KNOWN_COMMANDS.put("topk.reserve", io.vertx.redis.client.Command.TOPK_RESERVE); + KNOWN_COMMANDS.put("touch", io.vertx.redis.client.Command.TOUCH); + KNOWN_COMMANDS.put("ts.add", io.vertx.redis.client.Command.TS_ADD); + KNOWN_COMMANDS.put("ts.alter", io.vertx.redis.client.Command.TS_ALTER); + KNOWN_COMMANDS.put("ts.create", io.vertx.redis.client.Command.TS_CREATE); + KNOWN_COMMANDS.put("ts.createrule", io.vertx.redis.client.Command.TS_CREATERULE); + KNOWN_COMMANDS.put("ts.decrby", io.vertx.redis.client.Command.TS_DECRBY); + KNOWN_COMMANDS.put("ts.del", io.vertx.redis.client.Command.TS_DEL); + KNOWN_COMMANDS.put("ts.deleterule", io.vertx.redis.client.Command.TS_DELETERULE); + KNOWN_COMMANDS.put("ts.get", io.vertx.redis.client.Command.TS_GET); + KNOWN_COMMANDS.put("ts.incrby", io.vertx.redis.client.Command.TS_INCRBY); + KNOWN_COMMANDS.put("ts.info", io.vertx.redis.client.Command.TS_INFO); + KNOWN_COMMANDS.put("ts.madd", io.vertx.redis.client.Command.TS_MADD); + KNOWN_COMMANDS.put("ts.mget", io.vertx.redis.client.Command.TS_MGET); + KNOWN_COMMANDS.put("ts.mrange", io.vertx.redis.client.Command.TS_MRANGE); + KNOWN_COMMANDS.put("ts.mrevrange", io.vertx.redis.client.Command.TS_MREVRANGE); + KNOWN_COMMANDS.put("ts.queryindex", io.vertx.redis.client.Command.TS_QUERYINDEX); + KNOWN_COMMANDS.put("ts.range", io.vertx.redis.client.Command.TS_RANGE); + KNOWN_COMMANDS.put("ts.revrange", io.vertx.redis.client.Command.TS_REVRANGE); + KNOWN_COMMANDS.put("ttl", io.vertx.redis.client.Command.TTL); + KNOWN_COMMANDS.put("type", io.vertx.redis.client.Command.TYPE); + KNOWN_COMMANDS.put("unlink", io.vertx.redis.client.Command.UNLINK); + KNOWN_COMMANDS.put("unsubscribe", io.vertx.redis.client.Command.UNSUBSCRIBE); + KNOWN_COMMANDS.put("unwatch", io.vertx.redis.client.Command.UNWATCH); + KNOWN_COMMANDS.put("wait", io.vertx.redis.client.Command.WAIT); + KNOWN_COMMANDS.put("watch", io.vertx.redis.client.Command.WATCH); + KNOWN_COMMANDS.put("xack", io.vertx.redis.client.Command.XACK); + KNOWN_COMMANDS.put("xadd", io.vertx.redis.client.Command.XADD); + KNOWN_COMMANDS.put("xautoclaim", io.vertx.redis.client.Command.XAUTOCLAIM); + KNOWN_COMMANDS.put("xclaim", io.vertx.redis.client.Command.XCLAIM); + KNOWN_COMMANDS.put("xdel", io.vertx.redis.client.Command.XDEL); + KNOWN_COMMANDS.put("xgroup", io.vertx.redis.client.Command.XGROUP); + KNOWN_COMMANDS.put("xinfo", io.vertx.redis.client.Command.XINFO); + KNOWN_COMMANDS.put("xlen", io.vertx.redis.client.Command.XLEN); + KNOWN_COMMANDS.put("xpending", io.vertx.redis.client.Command.XPENDING); + KNOWN_COMMANDS.put("xrange", io.vertx.redis.client.Command.XRANGE); + KNOWN_COMMANDS.put("xread", io.vertx.redis.client.Command.XREAD); + KNOWN_COMMANDS.put("xreadgroup", io.vertx.redis.client.Command.XREADGROUP); + KNOWN_COMMANDS.put("xrevrange", io.vertx.redis.client.Command.XREVRANGE); + KNOWN_COMMANDS.put("xsetid", io.vertx.redis.client.Command.XSETID); + KNOWN_COMMANDS.put("xtrim", io.vertx.redis.client.Command.XTRIM); + KNOWN_COMMANDS.put("zadd", io.vertx.redis.client.Command.ZADD); + KNOWN_COMMANDS.put("zcard", io.vertx.redis.client.Command.ZCARD); + KNOWN_COMMANDS.put("zcount", io.vertx.redis.client.Command.ZCOUNT); + KNOWN_COMMANDS.put("zdiff", io.vertx.redis.client.Command.ZDIFF); + KNOWN_COMMANDS.put("zdiffstore", io.vertx.redis.client.Command.ZDIFFSTORE); + KNOWN_COMMANDS.put("zincrby", io.vertx.redis.client.Command.ZINCRBY); + KNOWN_COMMANDS.put("zinter", io.vertx.redis.client.Command.ZINTER); + KNOWN_COMMANDS.put("zintercard", io.vertx.redis.client.Command.ZINTERCARD); + KNOWN_COMMANDS.put("zinterstore", io.vertx.redis.client.Command.ZINTERSTORE); + KNOWN_COMMANDS.put("zlexcount", io.vertx.redis.client.Command.ZLEXCOUNT); + KNOWN_COMMANDS.put("zmpop", io.vertx.redis.client.Command.ZMPOP); + KNOWN_COMMANDS.put("zmscore", io.vertx.redis.client.Command.ZMSCORE); + KNOWN_COMMANDS.put("zpopmax", io.vertx.redis.client.Command.ZPOPMAX); + KNOWN_COMMANDS.put("zpopmin", io.vertx.redis.client.Command.ZPOPMIN); + KNOWN_COMMANDS.put("zrandmember", io.vertx.redis.client.Command.ZRANDMEMBER); + KNOWN_COMMANDS.put("zrange", io.vertx.redis.client.Command.ZRANGE); + KNOWN_COMMANDS.put("zrangebylex", io.vertx.redis.client.Command.ZRANGEBYLEX); + KNOWN_COMMANDS.put("zrangebyscore", io.vertx.redis.client.Command.ZRANGEBYSCORE); + KNOWN_COMMANDS.put("zrangestore", io.vertx.redis.client.Command.ZRANGESTORE); + KNOWN_COMMANDS.put("zrank", io.vertx.redis.client.Command.ZRANK); + KNOWN_COMMANDS.put("zrem", io.vertx.redis.client.Command.ZREM); + KNOWN_COMMANDS.put("zremrangebylex", io.vertx.redis.client.Command.ZREMRANGEBYLEX); + KNOWN_COMMANDS.put("zremrangebyrank", io.vertx.redis.client.Command.ZREMRANGEBYRANK); + KNOWN_COMMANDS.put("zremrangebyscore", io.vertx.redis.client.Command.ZREMRANGEBYSCORE); + KNOWN_COMMANDS.put("zrevrange", io.vertx.redis.client.Command.ZREVRANGE); + KNOWN_COMMANDS.put("zrevrangebylex", io.vertx.redis.client.Command.ZREVRANGEBYLEX); + KNOWN_COMMANDS.put("zrevrangebyscore", io.vertx.redis.client.Command.ZREVRANGEBYSCORE); + KNOWN_COMMANDS.put("zrevrank", io.vertx.redis.client.Command.ZREVRANK); + KNOWN_COMMANDS.put("zscan", io.vertx.redis.client.Command.ZSCAN); + KNOWN_COMMANDS.put("zscore", io.vertx.redis.client.Command.ZSCORE); + KNOWN_COMMANDS.put("zunion", io.vertx.redis.client.Command.ZUNION); + KNOWN_COMMANDS.put("zunionstore", io.vertx.redis.client.Command.ZUNIONSTORE); + } +} diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java index 0908b98ac0487..20004e141ed1e 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveRedisDataSourceImpl.java @@ -190,12 +190,13 @@ public static OptimisticLockingTransactionResult toTransactionResult(Resp @Override public Uni execute(String command, String... args) { nonNull(command, "command"); - return execute(Command.create(command), args); + return execute(CommandMap.normalize(Command.create(command)), args); } @Override public Uni execute(Command command, String... args) { nonNull(command, "command"); + command = CommandMap.normalize(command); Request request = Request.cmd(command); for (String arg : args) { request.arg(arg); @@ -206,6 +207,7 @@ public Uni execute(Command command, String... args) { @Override public Uni execute(io.vertx.redis.client.Command command, String... args) { nonNull(command, "command"); + command = CommandMap.normalize(command); Request request = Request.newInstance(io.vertx.redis.client.Request.cmd(command)); for (String arg : args) { request.arg(arg); diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java index df630d203eb35..e23c9a6a3f0eb 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactiveTransactionalRedisDataSourceImpl.java @@ -177,7 +177,7 @@ public ReactiveTransactionalTimeSeriesCommands timeseries(Class redisK @Override public Uni execute(String command, String... args) { nonNull(command, "command"); - return execute(Command.create(command), args); + return execute(CommandMap.normalize(Command.create(command)), args); } @Override @@ -185,6 +185,7 @@ public Uni execute(Command command, String... args) { nonNull(command, "command"); tx.enqueue(r -> r); // identity + command = CommandMap.normalize(command); RedisCommand c = RedisCommand.of(command).putAll(Arrays.asList(args)); return reactive.execute(c.toRequest()) @@ -201,6 +202,7 @@ public Uni execute(Command command, String... args) { @Override public Uni execute(io.vertx.redis.client.Command command, String... args) { nonNull(command, "command"); + command = CommandMap.normalize(command); return execute(new Command(command), args); } } diff --git a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/RedisCommand.java b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/RedisCommand.java index 06be66cecb734..43f8e39abdaeb 100644 --- a/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/RedisCommand.java +++ b/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/RedisCommand.java @@ -13,6 +13,7 @@ public class RedisCommand { private final Request request; private RedisCommand(Command command) { + command = CommandMap.normalize(command); this.request = Request.cmd(command); } diff --git a/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CommandNormalizationTest.java b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CommandNormalizationTest.java new file mode 100644 index 0000000000000..e333a00fc62fe --- /dev/null +++ b/extensions/redis-client/runtime/src/test/java/io/quarkus/redis/datasource/CommandNormalizationTest.java @@ -0,0 +1,27 @@ +package io.quarkus.redis.datasource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.charset.StandardCharsets; + +import org.junit.jupiter.api.Test; + +import io.quarkus.redis.runtime.datasource.RedisCommand; +import io.vertx.redis.client.impl.CommandImpl; +import io.vertx.redis.client.impl.RequestImpl; + +public class CommandNormalizationTest { + @Test + void test() { + RequestImpl req = (RequestImpl) RedisCommand.of(io.vertx.mutiny.redis.client.Command.create("hset")) + .put("key").put("field").put("value").toRequest().getDelegate(); + CommandImpl cmd = (CommandImpl) req.command(); + assertEquals("hset", cmd.toString()); + assertNotEquals(-1, cmd.getArity()); + assertFalse(cmd.needsGetKeys()); + assertEquals(1, req.keys().size()); + assertEquals("key", new String(req.keys().get(0), StandardCharsets.UTF_8)); + } +}