From 20c34ecff572cae97ded99108af83700656d46df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Sep 2026 03:40:29 +0000 Subject: [PATCH 1/9] IGNITE-29046 Bump redis.clients:jedis from 2.9.0 to 8.0.1 --- modules/clients/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/clients/pom.xml b/modules/clients/pom.xml index 578c898d9c3e3..649e79c28e915 100644 --- a/modules/clients/pom.xml +++ b/modules/clients/pom.xml @@ -50,7 +50,7 @@ redis.clients jedis - 2.9.0 + 8.0.1 test From 5df4ae32cbf64277952ff3311dcea1ba4789f53b Mon Sep 17 00:00:00 2001 From: zstan Date: Thu, 10 Sep 2026 09:51:59 +0300 Subject: [PATCH 2/9] jedis fix --- .../redis/RedisProtocolStringSelfTest.java | 99 +++++++------------ .../processors/rest/GridRestCommand.java | 5 +- .../processors/rest/GridRestProcessor.java | 3 + .../server/GridRedisClientCommandHandler.java | 84 ++++++++++++++++ .../protocols/tcp/redis/GridRedisCommand.java | 4 +- .../tcp/redis/GridRedisNioListener.java | 3 + 6 files changed, 132 insertions(+), 66 deletions(-) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java index c1d5e08416fa6..4e3108e1a71de 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java @@ -26,16 +26,15 @@ import org.junit.Test; import redis.clients.jedis.Jedis; import redis.clients.jedis.exceptions.JedisDataException; +import redis.clients.jedis.params.SetParams; /** * Tests for String commands of Redis protocol. */ public class RedisProtocolStringSelfTest extends RedisCommonAbstractTest { - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testGet() throws Exception { + public void testGet() { try (Jedis jedis = pool.getResource()) { jcache().put("getKey1", "getVal1"); @@ -55,11 +54,9 @@ public void testGet() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testGetSet() throws Exception { + public void testGetSet() { try (Jedis jedis = pool.getResource()) { jcache().put("getSetKey1", "1"); @@ -79,11 +76,9 @@ public void testGetSet() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testMGet() throws Exception { + public void testMGet() { try (Jedis jedis = pool.getResource()) { jcache().put("getKey1", "getVal1"); jcache().put("getKey2", 0); @@ -99,19 +94,15 @@ public void testMGet() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testMGetDirectOrder() throws Exception { + public void testMGetDirectOrder() { testMGetOrder(true); } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testMGetReverseOrder() throws Exception { + public void testMGetReverseOrder() t{ testMGetOrder(false); } @@ -153,11 +144,9 @@ public void testMGetOrder(boolean directOrder) { } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testMGetDuplicates() throws Exception { + public void testMGetDuplicates() { try (Jedis jedis = pool.getResource()) { jcache().put("key-A", "value-A"); jcache().put("key-B", "value-B"); @@ -188,14 +177,14 @@ public void testSet() throws Exception { Assert.assertEquals("b0", jcache().get("setKey2")); // test options. - jedis.set("setKey1", "2", "nx"); - jedis.set("setKey3", "3", "nx", "px", EXPIRE_MS); + jedis.set("setKey1", "2", SetParams.setParams().nx()); + jedis.set("setKey3", "3", SetParams.setParams().nx().px(EXPIRE_MS)); Assert.assertEquals("1", jcache().get("setKey1")); Assert.assertEquals("3", jcache().get("setKey3")); - jedis.set("setKey1", "2", "xx", "ex", EXPIRE_SEC); - jedis.set("setKey4", "4", "xx"); + jedis.set("setKey1", "2", SetParams.setParams().xx().ex(EXPIRE_SEC)); + jedis.set("setKey4", "4", SetParams.setParams().xx()); Assert.assertEquals("2", jcache().get("setKey1")); Assert.assertNull(jcache().get("setKey4")); @@ -208,11 +197,9 @@ public void testSet() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testMSet() throws Exception { + public void testMSet() { try (Jedis jedis = pool.getResource()) { jedis.mset("setKey1", "1", "setKey2", "2"); @@ -221,11 +208,9 @@ public void testMSet() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testIncrDecr() throws Exception { + public void testIncrDecr() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals(1, (long)jedis.incr("newKeyIncr")); Assert.assertEquals(-1, (long)jedis.decr("newKeyDecr")); @@ -305,11 +290,9 @@ public void testIncrDecr() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testIncrDecrBy() throws Exception { + public void testIncrDecrBy() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals(2, (long)jedis.incrBy("newKeyIncrBy", 2)); Assert.assertEquals(-2, (long)jedis.decrBy("newKeyDecrBy", 2)); @@ -362,11 +345,9 @@ public void testIncrDecrBy() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testAppend() throws Exception { + public void testAppend() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals(5, (long)jedis.append("appendKey1", "Hello")); Assert.assertEquals(12, (long)jedis.append("appendKey1", " World!")); @@ -384,11 +365,9 @@ public void testAppend() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testStrlen() throws Exception { + public void testStrlen() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals(0, (long)jedis.strlen("strlenKeyNonExisting")); @@ -409,11 +388,9 @@ public void testStrlen() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testSetRange() throws Exception { + public void testSetRange() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals(0, (long)jedis.setrange("setRangeKey1", 0, "")); @@ -458,11 +435,9 @@ public void testSetRange() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testGetRange() throws Exception { + public void testGetRange() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals("", jedis.getrange("getRangeKeyNonExisting", 0, 0)); @@ -486,11 +461,9 @@ public void testGetRange() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testDel() throws Exception { + public void testDel() { jcache().put("delKey1", "abc"); jcache().put("delKey2", "abcd"); try (Jedis jedis = pool.getResource()) { @@ -500,11 +473,9 @@ public void testDel() throws Exception { } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testExists() throws Exception { + public void testExists() { jcache().put("existsKey1", "abc"); jcache().put("existsKey2", "abcd"); try (Jedis jedis = pool.getResource()) { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java index 368a2c3b767db..032026e04ee59 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java @@ -223,7 +223,10 @@ public enum GridRestCommand { WARM_UP("warmup"), /** probe. */ - PROBE("probe"); + PROBE("probe"), + + /** Client info. */ + CLIENT("client"); /** Enum values. */ private static final GridRestCommand[] VALS = values(); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index e417ede2f6e99..e9b1fc1736267 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.auth.AuthenticationCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.beforeStart.NodeStateBeforeStartCommandHandler; +import org.apache.ignite.internal.processors.rest.handlers.server.GridClientInfoCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cluster.GridBaselineCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cluster.GridChangeClusterStateCommandHandler; @@ -557,6 +558,7 @@ public GridRestProcessor(GridKernalContext ctx) { addHandler(new MemoryMetricsCommandHandler(ctx)); addHandler(new NodeStateBeforeStartCommandHandler(ctx)); addHandler(new GridProbeCommandHandler(ctx)); + addHandler(new GridClientInfoCommandHandler(ctx)); // Start protocols. startTcpProtocol(); @@ -955,6 +957,7 @@ private void authorize(GridRestRequest req) throws SecurityException { case REMOVE_USER: case UPDATE_USER: case PROBE: + case CLIENT: break; default: diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java new file mode 100644 index 0000000000000..fa5fd2f602331 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.rest.handlers.redis.server; + +import java.nio.ByteBuffer; +import java.util.Collection; +import java.util.List; +import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.processors.rest.GridRestCommand; +import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler; +import org.apache.ignite.internal.processors.rest.GridRestResponse; +import org.apache.ignite.internal.processors.rest.handlers.redis.GridRedisRestCommandHandler; +import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisCommand; +import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisMessage; +import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisProtocolParser; +import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest; +import org.apache.ignite.internal.processors.rest.request.GridRestRequest; +import org.apache.ignite.internal.util.typedef.internal.U; + +import static org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisCommand.CLIENT; + +/** + * Redis CLIENT command handler. + */ +public class GridRedisClientCommandHandler extends GridRedisRestCommandHandler { + /** Supported commands. */ + private static final Collection SUPPORTED_COMMANDS = U.sealList( + CLIENT + ); + + /** + * Handler constructor. + * + * @param log Logger to use. + * @param hnd Rest handler. + * @param ctx Kernal context. + */ + public GridRedisClientCommandHandler(IgniteLogger log, GridRestProtocolHandler hnd, GridKernalContext ctx) { + super(log, hnd, ctx); + } + + /** {@inheritDoc} */ + @Override public Collection supportedCommands() { + return SUPPORTED_COMMANDS; + } + + /** {@inheritDoc} */ + @Override public GridRestRequest asRestRequest(GridRedisMessage msg) throws IgniteCheckedException { + assert msg != null; + + GridRestCacheRequest restReq = new GridRestCacheRequest(); + + restReq.clientId(msg.clientId()); + restReq.command(GridRestCommand.CLIENT); + restReq.cacheName(msg.cacheName()); + + return restReq; + } + + /** {@inheritDoc} */ + @Override public ByteBuffer makeResponse(final GridRestResponse restRes, List params) { + if (restRes.getResponse() == null) + return GridRedisProtocolParser.toInteger("0"); + + return GridRedisProtocolParser.toInteger(String.valueOf(restRes.getResponse())); + } +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java index bc32fb49ee4ae..e9c44dd00b7f6 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java @@ -78,7 +78,9 @@ public enum GridRedisCommand { /** FLUSHDB. */ FLUSHDB("FLUSHDB"), /** FLUSHALL. */ - FLUSHALL("FLUSHALL"); + FLUSHALL("FLUSHALL"), + /** CLIENT. */ + CLIENT("CLIENT"); /** String for command. */ private final String cmd; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java index 955eed9f2c8f8..d580039c5a86a 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java @@ -40,6 +40,8 @@ import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisMSetCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisSetCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisSetRangeCommandHandler; +import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisClientCommandHandler; +import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisClientCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisStrlenCommandHandler; import org.apache.ignite.internal.util.nio.GridNioServerListenerAdapter; import org.apache.ignite.internal.util.nio.GridNioSession; @@ -92,6 +94,7 @@ public GridRedisNioListener(IgniteLogger log, GridRestProtocolHandler hnd, GridK // server commands. addCommandHandler(new GridRedisDbSizeCommandHandler(log, hnd, ctx)); addCommandHandler(new GridRedisFlushCommandHandler(log, hnd, ctx)); + addCommandHandler(new GridRedisClientCommandHandler(log, hnd, ctx)); } /** From d48711c3a534796b89138944592f9466a9492606 Mon Sep 17 00:00:00 2001 From: zstan Date: Thu, 10 Sep 2026 10:04:17 +0300 Subject: [PATCH 3/9] add file --- .../server/GridClientInfoCommandHandler.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java new file mode 100644 index 0000000000000..c048ccd46886c --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.rest.handlers.server; + +import java.util.Collection; +import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.processors.rest.GridRestCommand; +import org.apache.ignite.internal.processors.rest.GridRestResponse; +import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandlerAdapter; +import org.apache.ignite.internal.processors.rest.request.GridRestRequest; +import org.apache.ignite.internal.util.future.GridFinishedFuture; +import org.apache.ignite.internal.util.typedef.internal.U; + +import static org.apache.ignite.internal.processors.rest.GridRestCommand.CLIENT; + +/** + * Command handler for CLIENT command (returns client info). + */ +public class GridClientInfoCommandHandler extends GridRestCommandHandlerAdapter { + /** Supported commands. */ + private static final Collection SUPPORTED_COMMANDS = U.sealList(CLIENT); + + /** + * @param ctx Context. + */ + public GridClientInfoCommandHandler(GridKernalContext ctx) { + super(ctx); + } + + /** {@inheritDoc} */ + @Override public Collection supportedCommands() { + return SUPPORTED_COMMANDS; + } + + /** {@inheritDoc} */ + @Override public IgniteInternalFuture handleAsync(GridRestRequest req) { + assert CLIENT == req.command(); + + GridRestResponse res = new GridRestResponse(); + + res.setResponse(0); + + return new GridFinishedFuture<>(res); + } +} \ No newline at end of file From 8cd2ebb04374adc19467c701810bf3e9be7d2635 Mon Sep 17 00:00:00 2001 From: zstan Date: Thu, 10 Sep 2026 11:02:03 +0300 Subject: [PATCH 4/9] fix --- .../rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java index 4e3108e1a71de..90f22820a59cd 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java @@ -102,7 +102,7 @@ public void testMGetDirectOrder() { /** */ @Test - public void testMGetReverseOrder() t{ + public void testMGetReverseOrder() { testMGetOrder(false); } From c81d005c34f6f4bfc1399131306b76c7afee877c Mon Sep 17 00:00:00 2001 From: zstan Date: Thu, 10 Sep 2026 11:50:41 +0300 Subject: [PATCH 5/9] style --- .../ignite/internal/processors/rest/GridRestProcessor.java | 2 +- .../handlers/redis/server/GridRedisClientCommandHandler.java | 2 +- .../rest/protocols/tcp/redis/GridRedisNioListener.java | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java index e9b1fc1736267..f7bd2dbf30c13 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestProcessor.java @@ -47,7 +47,6 @@ import org.apache.ignite.internal.processors.rest.handlers.GridRestCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.auth.AuthenticationCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.beforeStart.NodeStateBeforeStartCommandHandler; -import org.apache.ignite.internal.processors.rest.handlers.server.GridClientInfoCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cluster.GridBaselineCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.cluster.GridChangeClusterStateCommandHandler; @@ -58,6 +57,7 @@ import org.apache.ignite.internal.processors.rest.handlers.memory.MemoryMetricsCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.probe.GridProbeCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.query.QueryCommandHandler; +import org.apache.ignite.internal.processors.rest.handlers.server.GridClientInfoCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.task.GridTaskCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.top.GridTopologyCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.user.UserActionCommandHandler; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java index fa5fd2f602331..2522709de60d7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java @@ -81,4 +81,4 @@ public GridRedisClientCommandHandler(IgniteLogger log, GridRestProtocolHandler h return GridRedisProtocolParser.toInteger(String.valueOf(restRes.getResponse())); } -} \ No newline at end of file +} diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java index d580039c5a86a..1922c0f608302 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java @@ -29,6 +29,7 @@ import org.apache.ignite.internal.processors.rest.handlers.redis.key.GridRedisDelCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.key.GridRedisExistsCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.key.GridRedisExpireCommandHandler; +import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisClientCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisDbSizeCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisFlushCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisAppendCommandHandler; @@ -40,8 +41,6 @@ import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisMSetCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisSetCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisSetRangeCommandHandler; -import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisClientCommandHandler; -import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisClientCommandHandler; import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisStrlenCommandHandler; import org.apache.ignite.internal.util.nio.GridNioServerListenerAdapter; import org.apache.ignite.internal.util.nio.GridNioSession; From 01c74f209819a513f64acbbfd16fe7490749f7a6 Mon Sep 17 00:00:00 2001 From: zstan Date: Thu, 10 Sep 2026 13:05:03 +0300 Subject: [PATCH 6/9] fix --- .../rest/handlers/server/GridClientInfoCommandHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java index c048ccd46886c..bd7ef382bb968 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/server/GridClientInfoCommandHandler.java @@ -58,4 +58,4 @@ public GridClientInfoCommandHandler(GridKernalContext ctx) { return new GridFinishedFuture<>(res); } -} \ No newline at end of file +} From 42bd1ae476da88e9d79fedf6edbec2b2e5c854d9 Mon Sep 17 00:00:00 2001 From: zstan Date: Fri, 11 Sep 2026 14:16:54 +0300 Subject: [PATCH 7/9] fix after review --- .../handlers/redis/server/GridRedisClientCommandHandler.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java index 2522709de60d7..e9cfd928d58c3 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java @@ -76,9 +76,6 @@ public GridRedisClientCommandHandler(IgniteLogger log, GridRestProtocolHandler h /** {@inheritDoc} */ @Override public ByteBuffer makeResponse(final GridRestResponse restRes, List params) { - if (restRes.getResponse() == null) - return GridRedisProtocolParser.toInteger("0"); - - return GridRedisProtocolParser.toInteger(String.valueOf(restRes.getResponse())); + return GridRedisProtocolParser.oKString(); } } From e40500ef5bf1c740dd2443689cb5e665ff10854b Mon Sep 17 00:00:00 2001 From: zstan Date: Fri, 11 Sep 2026 20:11:12 +0300 Subject: [PATCH 8/9] nao-it suggestions --- .../redis/RedisProtocolConnectSelfTest.java | 50 ++++++--- .../server/GridRedisClientCommandHandler.java | 100 +++++++++++------- .../tcp/redis/GridRedisNioListener.java | 2 +- 3 files changed, 102 insertions(+), 50 deletions(-) diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolConnectSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolConnectSelfTest.java index b22f823042fb6..16c0e76ee8030 100644 --- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolConnectSelfTest.java +++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolConnectSelfTest.java @@ -18,9 +18,11 @@ package org.apache.ignite.internal.processors.rest.protocols.tcp.redis; import org.apache.commons.lang3.RandomStringUtils; +import org.apache.ignite.testframework.GridTestUtils; import org.junit.Assert; import org.junit.Test; import redis.clients.jedis.Jedis; +import redis.clients.jedis.exceptions.JedisDataException; import static org.apache.ignite.internal.util.IgniteUtils.KB; @@ -28,31 +30,25 @@ * Tests for Connection commands of Redis protocol. */ public class RedisProtocolConnectSelfTest extends RedisCommonAbstractTest { - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testPing() throws Exception { + public void testPing() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals("PONG", jedis.ping()); } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testEcho() throws Exception { + public void testEcho() { try (Jedis jedis = pool.getResource()) { Assert.assertEquals("Hello, grid!", jedis.echo("Hello, grid!")); } } - /** - * @throws Exception If failed. - */ + /** */ @Test - public void testSelect() throws Exception { + public void testSelect() { try (Jedis jedis = pool.getResource()) { // connected to cache with index 0 jedis.set("k0", "v0"); @@ -78,6 +74,36 @@ public void testSelect() throws Exception { } } + /** */ + @Test + public void testClient() { + try (Jedis jedis = pool.getResource()) { + Assert.assertNull(jedis.clientGetname()); + + Assert.assertEquals("OK", jedis.clientSetname("test-client")); + Assert.assertEquals("test-client", jedis.clientGetname()); + + // The name is connection-scoped. + try (Jedis jedis2 = pool.getResource()) { + Assert.assertNull(jedis2.clientGetname()); + } + + Assert.assertEquals("test-client", jedis.clientGetname()); + } + } + + /** */ + @Test + public void testClientUnknownSubcommand() { + try (Jedis jedis = pool.getResource()) { + GridTestUtils.assertThrows(log, () -> jedis.clientUnpause(), JedisDataException.class, + "Unknown subcommand 'UNPAUSE' for 'client' command"); + + // The connection is still usable. + Assert.assertEquals("PONG", jedis.ping()); + } + } + /** */ @Test public void testSetGetLongString() { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java index e9cfd928d58c3..80745b7865179 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java @@ -17,44 +17,35 @@ package org.apache.ignite.internal.processors.rest.handlers.redis.server; -import java.nio.ByteBuffer; import java.util.Collection; -import java.util.List; -import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.IgniteLogger; -import org.apache.ignite.internal.GridKernalContext; -import org.apache.ignite.internal.processors.rest.GridRestCommand; -import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler; -import org.apache.ignite.internal.processors.rest.GridRestResponse; -import org.apache.ignite.internal.processors.rest.handlers.redis.GridRedisRestCommandHandler; +import org.apache.ignite.internal.IgniteInternalFuture; +import org.apache.ignite.internal.processors.rest.handlers.redis.GridRedisCommandHandler; import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisCommand; import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisMessage; import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisProtocolParser; -import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest; -import org.apache.ignite.internal.processors.rest.request.GridRestRequest; +import org.apache.ignite.internal.util.future.GridFinishedFuture; +import org.apache.ignite.internal.util.nio.GridNioSession; +import org.apache.ignite.internal.util.nio.GridNioSessionMetaKey; +import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.U; import static org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisCommand.CLIENT; /** * Redis CLIENT command handler. + *

+ * CLIENT is a connection-scoped command container, so it is handled locally, without a REST round trip. + * Only the subcommands that carry no cluster-wide state are supported, the rest are answered with an error. */ -public class GridRedisClientCommandHandler extends GridRedisRestCommandHandler { +public class GridRedisClientCommandHandler implements GridRedisCommandHandler { /** Supported commands. */ - private static final Collection SUPPORTED_COMMANDS = U.sealList( - CLIENT - ); - - /** - * Handler constructor. - * - * @param log Logger to use. - * @param hnd Rest handler. - * @param ctx Kernal context. - */ - public GridRedisClientCommandHandler(IgniteLogger log, GridRestProtocolHandler hnd, GridKernalContext ctx) { - super(log, hnd, ctx); - } + private static final Collection SUPPORTED_COMMANDS = U.sealList(CLIENT); + + /** Session metadata key for the name set by CLIENT SETNAME. */ + private static final int CLIENT_NAME_META_KEY = GridNioSessionMetaKey.nextUniqueKey(); + + /** Position of the first argument of a CLIENT subcommand. */ + private static final int ARG_POS = 2; /** {@inheritDoc} */ @Override public Collection supportedCommands() { @@ -62,20 +53,55 @@ public GridRedisClientCommandHandler(IgniteLogger log, GridRestProtocolHandler h } /** {@inheritDoc} */ - @Override public GridRestRequest asRestRequest(GridRedisMessage msg) throws IgniteCheckedException { + @Override public IgniteInternalFuture handleAsync(GridNioSession ses, GridRedisMessage msg) { assert msg != null; - GridRestCacheRequest restReq = new GridRestCacheRequest(); + String subCmd = msg.key(); - restReq.clientId(msg.clientId()); - restReq.command(GridRestCommand.CLIENT); - restReq.cacheName(msg.cacheName()); + if (F.isEmpty(subCmd)) { + msg.setResponse(GridRedisProtocolParser.toGenericError( + "wrong number of arguments for 'client' command")); - return restReq; - } + return new GridFinishedFuture<>(msg); + } - /** {@inheritDoc} */ - @Override public ByteBuffer makeResponse(final GridRestResponse restRes, List params) { - return GridRedisProtocolParser.oKString(); + switch (subCmd.toUpperCase()) { + case "SETNAME": { + String name = msg.aux(ARG_POS); + + if (name == null || name.indexOf(' ') >= 0 || name.indexOf('\n') >= 0) + msg.setResponse(GridRedisProtocolParser.toGenericError( + "Client names cannot contain spaces, newlines or special characters.")); + else { + ses.addMeta(CLIENT_NAME_META_KEY, name); + + msg.setResponse(GridRedisProtocolParser.oKString()); + } + + break; + } + + case "GETNAME": { + String name = ses.meta(CLIENT_NAME_META_KEY); + + msg.setResponse(name == null + ? GridRedisProtocolParser.nil() + : GridRedisProtocolParser.toBulkString(name)); + + break; + } + + case "SETINFO": + // The library name and version announced by a driver: accepted and ignored. + msg.setResponse(GridRedisProtocolParser.oKString()); + + break; + + default: + msg.setResponse(GridRedisProtocolParser.toGenericError( + "Unknown subcommand '" + subCmd + "' for 'client' command")); + } + + return new GridFinishedFuture<>(msg); } -} +} \ No newline at end of file diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java index 1922c0f608302..4b6337955ba0c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java @@ -93,7 +93,7 @@ public GridRedisNioListener(IgniteLogger log, GridRestProtocolHandler hnd, GridK // server commands. addCommandHandler(new GridRedisDbSizeCommandHandler(log, hnd, ctx)); addCommandHandler(new GridRedisFlushCommandHandler(log, hnd, ctx)); - addCommandHandler(new GridRedisClientCommandHandler(log, hnd, ctx)); + addCommandHandler(new GridRedisClientCommandHandler()); } /** From c3a90fb871c22f0c746e5cea0e30a1dbe446a352 Mon Sep 17 00:00:00 2001 From: zstan Date: Fri, 11 Sep 2026 20:23:46 +0300 Subject: [PATCH 9/9] new line check --- .../handlers/redis/server/GridRedisClientCommandHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java index 80745b7865179..e9b14dd5b6256 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/server/GridRedisClientCommandHandler.java @@ -104,4 +104,4 @@ public class GridRedisClientCommandHandler implements GridRedisCommandHandler { return new GridFinishedFuture<>(msg); } -} \ No newline at end of file +}