From 16e2b0dc73122caec5484e8fc5015abbff9ee800 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 1 Mar 2022 14:41:06 +0100 Subject: [PATCH 1/6] Prepare 7.0 branch #2029 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 027b2e3070..5ca48a2634 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ io.lettuce lettuce-core - 6.2.0.BUILD-SNAPSHOT + 7.0.0.BUILD-SNAPSHOT jar Lettuce From 2b8f3be0aad2ace28de1da2ebcab828df551deef Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 1 Mar 2022 14:42:20 +0100 Subject: [PATCH 2/6] Remove connection-related methods from commands API #2027 --- README.md | 8 +- .../core/AbstractRedisAsyncCommands.java | 21 --- .../io/lettuce/core/AbstractRedisClient.java | 2 +- .../core/AbstractRedisReactiveCommands.java | 21 --- .../lettuce/core/RedisAsyncCommandsImpl.java | 1 - .../io/lettuce/core/RedisChannelHandler.java | 2 +- .../io/lettuce/core/RedisChannelWriter.java | 2 +- .../core/RedisReactiveCommandsImpl.java | 1 - .../{internal => api}/AsyncCloseable.java | 2 +- .../lettuce/core/api/StatefulConnection.java | 1 - .../api/async/BaseRedisAsyncCommands.java | 25 ---- .../core/api/async/RedisAsyncCommands.java | 6 - .../reactive/BaseRedisReactiveCommands.java | 25 ---- .../api/reactive/RedisReactiveCommands.java | 6 - .../core/api/sync/BaseRedisCommands.java | 10 -- .../lettuce/core/api/sync/RedisCommands.java | 6 - ...RedisAdvancedClusterAsyncCommandsImpl.java | 13 +- ...isAdvancedClusterReactiveCommandsImpl.java | 25 +--- .../RedisClusterPubSubAsyncCommandsImpl.java | 2 +- .../RedisAdvancedClusterAsyncCommands.java | 6 - .../api/async/RedisClusterAsyncCommands.java | 9 -- .../RedisAdvancedClusterReactiveCommands.java | 6 - .../RedisClusterReactiveCommands.java | 9 -- .../sync/RedisAdvancedClusterCommands.java | 6 - .../api/sync/RedisClusterCommands.java | 9 -- .../internal/AsyncConnectionProvider.java | 2 + .../core/masterreplica/Connections.java | 9 +- .../core/masterreplica/ResumeAfter.java | 2 +- .../SentinelTopologyRefresh.java | 2 +- .../api/async/RedisPubSubAsyncCommands.java | 6 - .../reactive/RedisPubSubReactiveCommands.java | 6 - .../pubsub/api/sync/RedisPubSubCommands.java | 6 - .../RedisSentinelAsyncCommandsImpl.java | 8 +- .../RedisSentinelReactiveCommandsImpl.java | 1 - .../api/async/RedisSentinelAsyncCommands.java | 15 +- .../RedisSentinelReactiveCommands.java | 17 +-- .../api/sync/RedisSentinelCommands.java | 10 -- .../io/lettuce/core/support/AsyncPool.java | 2 +- .../core/support/ConnectionWrapping.java | 2 +- .../coroutines/BaseRedisCoroutinesCommands.kt | 21 --- .../BaseRedisCoroutinesCommandsImpl.kt | 6 - .../RedisSentinelCoroutinesCommands.kt | 8 +- .../RedisSentinelCoroutinesCommandsImpl.kt | 2 - .../lettuce/core/api/BaseRedisCommands.java | 27 ---- .../redis/extensibility/LettuceGeoDemo.java | 12 +- ...MyExtendedRedisClientIntegrationTests.java | 2 +- ...dedRedisClusterClientIntegrationTests.java | 2 +- .../lettuce/core/AbstractRedisClientTest.java | 19 ++- .../core/AsyncConnectionIntegrationTests.java | 18 +-- .../lettuce/core/ClientIntegrationTests.java | 34 ++--- .../core/ClientOptionsIntegrationTests.java | 104 +++++++------- .../core/ConnectMethodsIntegrationTests.java | 60 +++----- .../ConnectionCommandIntegrationTests.java | 106 ++++++++------- .../core/CustomCodecIntegrationTests.java | 86 +++++++----- .../ReactiveConnectionIntegrationTests.java | 27 ++-- .../io/lettuce/core/RedisClientUnitTests.java | 11 +- .../core/ScanStreamIntegrationTests.java | 8 +- .../io/lettuce/core/SslIntegrationTests.java | 70 +++++----- ...AdvancedClusterClientIntegrationTests.java | 22 ++- ...vancedClusterReactiveIntegrationTests.java | 17 ++- .../io/lettuce/core/cluster/ClusterSetup.java | 22 +-- .../core/cluster/ClusterTestHelper.java | 16 ++- .../NodeSelectionAsyncIntegrationTests.java | 7 +- .../NodeSelectionSyncIntegrationTests.java | 25 ++-- .../RedisClusterClientIntegrationTests.java | 80 +++++------ .../core/cluster/RedisClusterSetupTest.java | 128 ++++++++++-------- .../RedisClusterStressScenariosTest.java | 41 ++++-- .../ListClusterCommandIntegrationTests.java | 5 +- ...lusterReactiveCommandIntegrationTests.java | 2 +- ...usterPubSubConnectionIntegrationTests.java | 10 +- .../TopologyRefreshIntegrationTests.java | 68 ++++++---- .../commands/BitCommandIntegrationTests.java | 16 +-- .../CustomCommandIntegrationTests.java | 8 +- .../commands/ListCommandIntegrationTests.java | 8 +- ...OnlyOnceServerCommandIntegrationTests.java | 31 +++-- .../ServerCommandIntegrationTests.java | 26 ++-- .../TransactionCommandIntegrationTests.java | 17 ++- ...CustomReactiveCommandIntegrationTests.java | 7 +- .../ListReactiveCommandIntegrationTests.java | 2 +- ...ServerReactiveCommandIntegrationTests.java | 22 ++- .../ListTxCommandIntegrationTests.java | 2 +- .../ReactiveTypeAdaptionIntegrationTests.java | 4 +- .../RedisCommandsAsyncIntegrationTests.java | 7 +- ...RedisCommandsBatchingIntegrationTests.java | 17 ++- .../RedisCommandsIntegrationTests.java | 15 +- ...RedisCommandsReactiveIntegrationTests.java | 13 +- .../RedisCommandsSyncIntegrationTests.java | 7 +- .../CustomCommandIntegrationTests.java | 21 +-- .../core/masterreplica/MasterReplicaTest.java | 48 ++++--- .../StaticMasterReplicaTest.java | 52 ++++--- .../core/masterslave/MasterSlaveTest.java | 48 ++++--- .../masterslave/StaticMasterSlaveTest.java | 52 ++++--- .../ConnectionFailureIntegrationTests.java | 63 +++++---- .../core/pubsub/PubSubCommandTest.java | 86 +++++++----- .../core/pubsub/PubSubReactiveTest.java | 99 +++++++------- .../core/reliability/AtLeastOnceTest.java | 128 ++++++++++-------- .../core/reliability/AtMostOnceTest.java | 20 +-- .../SentinelCommandIntegrationTests.java | 34 ++--- .../SentinelConnectionIntegrationTests.java | 70 +++------- ...SentinelServerCommandIntegrationTests.java | 7 +- ...ConnectionPoolSupportIntegrationTests.java | 22 +-- ...ConnectionPoolSupportIntegrationTests.java | 26 ++-- .../lettuce/core/support/InjectedClient.java | 12 +- .../io/lettuce/test/LettuceExtension.java | 21 ++- 104 files changed, 1133 insertions(+), 1256 deletions(-) rename src/main/java/io/lettuce/core/{internal => api}/AsyncCloseable.java (97%) diff --git a/README.md b/README.md index b1d42b2e32..a4327b2a40 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ Basic Usage ```java RedisClient client = RedisClient.create("redis://localhost"); StatefulRedisConnection connection = client.connect(); -RedisStringCommands sync = connection.sync(); +RedisStringCommands sync = connection.sync(); String value = sync.get("key"); ``` @@ -135,9 +135,9 @@ Pub/Sub ------- ```java -RedisPubSubCommands connection = client.connectPubSub().sync(); -connection.getStatefulConnection().addListener(new RedisPubSubListener() { ... }) -connection.subscribe("channel") +StatefulRedisPubSubConnection connection = client.connectPubSub(); +connection.addListener(new RedisPubSubListener() { ... }) +connection.sync().subscribe("channel") ``` Cloud Provider Compatibility diff --git a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java index 7819883cf5..43238afcf6 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java @@ -747,11 +747,6 @@ public RedisFuture expireat(K key, Instant timestamp) { return expireat(key, timestamp.toEpochMilli() / 1000); } - @Override - public void flushCommands() { - connection.flushCommands(); - } - @Override public RedisFuture flushall() { return dispatch(commandBuilder.flushall()); @@ -1111,11 +1106,6 @@ public RedisFuture info(String section) { return dispatch(commandBuilder.info(section)); } - @Override - public boolean isOpen() { - return connection.isOpen(); - } - @Override public RedisFuture> keys(K pattern) { return dispatch(commandBuilder.keys(pattern)); @@ -1417,11 +1407,6 @@ public RedisFuture replicaofNoOne() { return dispatch(commandBuilder.replicaofNoOne()); } - @Override - public void reset() { - getConnection().reset(); - } - @Override public RedisFuture restore(K key, long ttl, byte[] value) { return dispatch(commandBuilder.restore(key, value, RestoreArgs.Builder.ttl(ttl))); @@ -1586,12 +1571,6 @@ public RedisFuture setGet(K key, V value, SetArgs setArgs) { return dispatch(commandBuilder.setGet(key, value, setArgs)); } - @Override - public void setAutoFlushCommands(boolean autoFlush) { - connection.setAutoFlushCommands(autoFlush); - } - - @Override public void setTimeout(Duration timeout) { connection.setTimeout(timeout); } diff --git a/src/main/java/io/lettuce/core/AbstractRedisClient.java b/src/main/java/io/lettuce/core/AbstractRedisClient.java index 6dd5bf65cc..c89f2ed2b0 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisClient.java +++ b/src/main/java/io/lettuce/core/AbstractRedisClient.java @@ -31,11 +31,11 @@ import java.util.concurrent.atomic.AtomicInteger; import reactor.core.publisher.Mono; +import io.lettuce.core.api.AsyncCloseable; import io.lettuce.core.event.command.CommandListener; import io.lettuce.core.event.connection.ConnectEvent; import io.lettuce.core.event.connection.ConnectionCreatedEvent; import io.lettuce.core.event.jfr.EventRecorder; -import io.lettuce.core.internal.AsyncCloseable; import io.lettuce.core.internal.Exceptions; import io.lettuce.core.internal.Futures; import io.lettuce.core.internal.LettuceAssert; diff --git a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java index 276fe7bee2..55e6cb8a3a 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java @@ -805,11 +805,6 @@ public Mono expireat(K key, Instant timestamp) { return expireat(key, timestamp.toEpochMilli() / 1000); } - @Override - public void flushCommands() { - connection.flushCommands(); - } - @Override public Mono flushall() { return createMono(commandBuilder::flushall); @@ -1172,7 +1167,6 @@ public Mono info(String section) { return createMono(() -> commandBuilder.info(section)); } - @Override public boolean isOpen() { return connection.isOpen(); } @@ -1492,11 +1486,6 @@ public Mono replicaofNoOne() { return createMono(() -> commandBuilder.replicaofNoOne()); } - @Override - public void reset() { - getConnection().reset(); - } - @Override public Mono restore(K key, long ttl, byte[] value) { return createMono(() -> commandBuilder.restore(key, value, RestoreArgs.Builder.ttl(ttl))); @@ -1661,16 +1650,6 @@ public Mono setGet(K key, V value, SetArgs setArgs) { return createMono(() -> commandBuilder.setGet(key, value, setArgs)); } - @Override - public void setAutoFlushCommands(boolean autoFlush) { - connection.setAutoFlushCommands(autoFlush); - } - - @Override - public void setTimeout(Duration timeout) { - connection.setTimeout(timeout); - } - @Override public Mono setbit(K key, long offset, int value) { return createMono(() -> commandBuilder.setbit(key, offset, value)); diff --git a/src/main/java/io/lettuce/core/RedisAsyncCommandsImpl.java b/src/main/java/io/lettuce/core/RedisAsyncCommandsImpl.java index 6bbdec83c8..93744123f4 100644 --- a/src/main/java/io/lettuce/core/RedisAsyncCommandsImpl.java +++ b/src/main/java/io/lettuce/core/RedisAsyncCommandsImpl.java @@ -41,7 +41,6 @@ public RedisAsyncCommandsImpl(StatefulRedisConnection connection, RedisCod super(connection, codec); } - @Override public StatefulRedisConnection getStatefulConnection() { return (StatefulRedisConnection) super.getConnection(); } diff --git a/src/main/java/io/lettuce/core/RedisChannelHandler.java b/src/main/java/io/lettuce/core/RedisChannelHandler.java index 01ed85c5bc..e47ff2bd2b 100644 --- a/src/main/java/io/lettuce/core/RedisChannelHandler.java +++ b/src/main/java/io/lettuce/core/RedisChannelHandler.java @@ -25,8 +25,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import io.lettuce.core.api.AsyncCloseable; import io.lettuce.core.api.StatefulConnection; -import io.lettuce.core.internal.AsyncCloseable; import io.lettuce.core.internal.LettuceAssert; import io.lettuce.core.protocol.CommandExpiryWriter; import io.lettuce.core.protocol.CommandWrapper; diff --git a/src/main/java/io/lettuce/core/RedisChannelWriter.java b/src/main/java/io/lettuce/core/RedisChannelWriter.java index d5e8c1e5c4..769b74b017 100644 --- a/src/main/java/io/lettuce/core/RedisChannelWriter.java +++ b/src/main/java/io/lettuce/core/RedisChannelWriter.java @@ -19,7 +19,7 @@ import java.util.Collection; import java.util.concurrent.CompletableFuture; -import io.lettuce.core.internal.AsyncCloseable; +import io.lettuce.core.api.AsyncCloseable; import io.lettuce.core.protocol.ConnectionFacade; import io.lettuce.core.protocol.RedisCommand; import io.lettuce.core.resource.ClientResources; diff --git a/src/main/java/io/lettuce/core/RedisReactiveCommandsImpl.java b/src/main/java/io/lettuce/core/RedisReactiveCommandsImpl.java index c92f433ea2..1c341934d0 100644 --- a/src/main/java/io/lettuce/core/RedisReactiveCommandsImpl.java +++ b/src/main/java/io/lettuce/core/RedisReactiveCommandsImpl.java @@ -41,7 +41,6 @@ public RedisReactiveCommandsImpl(StatefulRedisConnection connection, Redis super(connection, codec); } - @Override public StatefulRedisConnection getStatefulConnection() { return (StatefulRedisConnection) super.getConnection(); } diff --git a/src/main/java/io/lettuce/core/internal/AsyncCloseable.java b/src/main/java/io/lettuce/core/api/AsyncCloseable.java similarity index 97% rename from src/main/java/io/lettuce/core/internal/AsyncCloseable.java rename to src/main/java/io/lettuce/core/api/AsyncCloseable.java index aed31450c4..2372cd0d61 100644 --- a/src/main/java/io/lettuce/core/internal/AsyncCloseable.java +++ b/src/main/java/io/lettuce/core/api/AsyncCloseable.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.lettuce.core.internal; +package io.lettuce.core.api; import java.util.concurrent.CompletableFuture; diff --git a/src/main/java/io/lettuce/core/api/StatefulConnection.java b/src/main/java/io/lettuce/core/api/StatefulConnection.java index 73bc1fc3d5..851f6b2e60 100644 --- a/src/main/java/io/lettuce/core/api/StatefulConnection.java +++ b/src/main/java/io/lettuce/core/api/StatefulConnection.java @@ -21,7 +21,6 @@ import io.lettuce.core.ClientOptions; import io.lettuce.core.RedisConnectionStateListener; -import io.lettuce.core.internal.AsyncCloseable; import io.lettuce.core.protocol.RedisCommand; import io.lettuce.core.resource.ClientResources; diff --git a/src/main/java/io/lettuce/core/api/async/BaseRedisAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/BaseRedisAsyncCommands.java index b0d9a20e4b..0cc725d179 100644 --- a/src/main/java/io/lettuce/core/api/async/BaseRedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/BaseRedisAsyncCommands.java @@ -149,29 +149,4 @@ public interface BaseRedisAsyncCommands { */ RedisFuture dispatch(ProtocolKeyword type, CommandOutput output, CommandArgs args); - /** - * @return {@code true} if the connection is open (connected and not closed). - */ - boolean isOpen(); - - /** - * Reset the command state. Queued commands will be canceled and the internal state will be reset. This is useful when the - * internal state machine gets out of sync with the connection. - */ - void reset(); - - /** - * Disable or enable auto-flush behavior. Default is {@code true}. If autoFlushCommands is disabled, multiple commands can - * be issued without writing them actually to the transport. Commands are buffered until a {@link #flushCommands()} is - * issued. After calling {@link #flushCommands()} commands are sent to the transport and executed by Redis. - * - * @param autoFlush state of autoFlush. - */ - void setAutoFlushCommands(boolean autoFlush); - - /** - * Flush pending commands. This commands forces a flush on the channel and can be used to buffer ("pipeline") commands to - * achieve batching. No-op if channel is not connected. - */ - void flushCommands(); } diff --git a/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java index b1726c1153..fce5f4c84e 100644 --- a/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java @@ -16,7 +16,6 @@ package io.lettuce.core.api.async; import io.lettuce.core.RedisFuture; -import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands; /** @@ -69,9 +68,4 @@ public interface RedisAsyncCommands extends BaseRedisAsyncCommands, */ RedisFuture swapdb(int db1, int db2); - /** - * @return the underlying connection. - */ - StatefulRedisConnection getStatefulConnection(); - } diff --git a/src/main/java/io/lettuce/core/api/reactive/BaseRedisReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/BaseRedisReactiveCommands.java index 89e42d9062..fe96b5bb30 100644 --- a/src/main/java/io/lettuce/core/api/reactive/BaseRedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/BaseRedisReactiveCommands.java @@ -149,29 +149,4 @@ public interface BaseRedisReactiveCommands { */ Flux dispatch(ProtocolKeyword type, CommandOutput output, CommandArgs args); - /** - * @return {@code true} if the connection is open (connected and not closed). - */ - boolean isOpen(); - - /** - * Reset the command state. Queued commands will be canceled and the internal state will be reset. This is useful when the - * internal state machine gets out of sync with the connection. - */ - void reset(); - - /** - * Disable or enable auto-flush behavior. Default is {@code true}. If autoFlushCommands is disabled, multiple commands can - * be issued without writing them actually to the transport. Commands are buffered until a {@link #flushCommands()} is - * issued. After calling {@link #flushCommands()} commands are sent to the transport and executed by Redis. - * - * @param autoFlush state of autoFlush. - */ - void setAutoFlushCommands(boolean autoFlush); - - /** - * Flush pending commands. This commands forces a flush on the channel and can be used to buffer ("pipeline") commands to - * achieve batching. No-op if channel is not connected. - */ - void flushCommands(); } diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java index d0c10a3db5..308071ef73 100644 --- a/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java @@ -16,7 +16,6 @@ package io.lettuce.core.api.reactive; import reactor.core.publisher.Mono; -import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.cluster.api.reactive.RedisClusterReactiveCommands; /** @@ -69,9 +68,4 @@ public interface RedisReactiveCommands extends BaseRedisReactiveCommands swapdb(int db1, int db2); - /** - * @return the underlying connection. - */ - StatefulRedisConnection getStatefulConnection(); - } diff --git a/src/main/java/io/lettuce/core/api/sync/BaseRedisCommands.java b/src/main/java/io/lettuce/core/api/sync/BaseRedisCommands.java index ebfe80a871..4bc08d9ee2 100644 --- a/src/main/java/io/lettuce/core/api/sync/BaseRedisCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/BaseRedisCommands.java @@ -148,14 +148,4 @@ public interface BaseRedisCommands { */ T dispatch(ProtocolKeyword type, CommandOutput output, CommandArgs args); - /** - * @return {@code true} if the connection is open (connected and not closed). - */ - boolean isOpen(); - - /** - * Reset the command state. Queued commands will be canceled and the internal state will be reset. This is useful when the - * internal state machine gets out of sync with the connection. - */ - void reset(); } diff --git a/src/main/java/io/lettuce/core/api/sync/RedisCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisCommands.java index 419b299c3c..26f219c75f 100644 --- a/src/main/java/io/lettuce/core/api/sync/RedisCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/RedisCommands.java @@ -15,7 +15,6 @@ */ package io.lettuce.core.api.sync; -import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.cluster.api.sync.RedisClusterCommands; /** @@ -68,9 +67,4 @@ public interface RedisCommands extends BaseRedisCommands, RedisAclCo */ String swapdb(int db1, int db2); - /** - * @return the underlying connection. - */ - StatefulRedisConnection getStatefulConnection(); - } diff --git a/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterAsyncCommandsImpl.java b/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterAsyncCommandsImpl.java index 40e828d5c7..12f8ded49c 100644 --- a/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterAsyncCommandsImpl.java +++ b/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterAsyncCommandsImpl.java @@ -110,21 +110,13 @@ public RedisFuture clientSetname(K name) { CompletableFuture> byNodeId = getConnectionAsync(redisClusterNode.getNodeId()); executions.put("NodeId: " + redisClusterNode.getNodeId(), byNodeId.thenCompose(c -> { - - if (c.isOpen()) { - return c.clientSetname(name); - } - return ok; + return c.clientSetname(name); })); CompletableFuture> byHost = getConnectionAsync(uri.getHost(), uri.getPort()); executions.put("HostAndPort: " + redisClusterNode.getNodeId(), byHost.thenCompose(c -> { - - if (c.isOpen()) { - return c.clientSetname(name); - } - return ok; + return c.clientSetname(name); })); } @@ -508,7 +500,6 @@ private CompletableFuture> getConnectionAsync(St .thenApply(StatefulRedisConnection::async); } - @Override public StatefulRedisClusterConnection getStatefulConnection() { return (StatefulRedisClusterConnection) super.getConnection(); } diff --git a/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterReactiveCommandsImpl.java b/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterReactiveCommandsImpl.java index 71ed5a0296..8f14b7edc8 100644 --- a/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterReactiveCommandsImpl.java +++ b/src/main/java/io/lettuce/core/cluster/RedisAdvancedClusterReactiveCommandsImpl.java @@ -34,17 +34,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import io.lettuce.core.AbstractRedisReactiveCommands; -import io.lettuce.core.FlushMode; -import io.lettuce.core.GeoArgs; -import io.lettuce.core.GeoWithin; -import io.lettuce.core.KeyScanCursor; -import io.lettuce.core.KeyValue; -import io.lettuce.core.RedisException; -import io.lettuce.core.RedisURI; -import io.lettuce.core.ScanArgs; -import io.lettuce.core.ScanCursor; -import io.lettuce.core.StreamScanCursor; +import io.lettuce.core.*; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.reactive.RedisKeyReactiveCommands; import io.lettuce.core.api.reactive.RedisScriptingReactiveCommands; @@ -113,22 +103,14 @@ public Mono clientSetname(K name) { Mono> byNodeId = getConnectionReactive(redisClusterNode.getNodeId()); publishers.add(byNodeId.flatMap(conn -> { - - if (conn.isOpen()) { - return conn.clientSetname(name); - } - return Mono.empty(); + return conn.clientSetname(name); })); Mono> byHost = getConnectionReactive(redisClusterNode.getUri().getHost(), redisClusterNode.getUri().getPort()); publishers.add(byHost.flatMap(conn -> { - - if (conn.isOpen()) { - return conn.clientSetname(name); - } - return Mono.empty(); + return conn.clientSetname(name); })); } @@ -459,7 +441,6 @@ private Mono> getConnectionReactive(String ho .map(StatefulRedisConnection::reactive); } - @Override public StatefulRedisClusterConnection getStatefulConnection() { return (StatefulRedisClusterConnection) super.getConnection(); } diff --git a/src/main/java/io/lettuce/core/cluster/RedisClusterPubSubAsyncCommandsImpl.java b/src/main/java/io/lettuce/core/cluster/RedisClusterPubSubAsyncCommandsImpl.java index 0673058dac..85361c7274 100644 --- a/src/main/java/io/lettuce/core/cluster/RedisClusterPubSubAsyncCommandsImpl.java +++ b/src/main/java/io/lettuce/core/cluster/RedisClusterPubSubAsyncCommandsImpl.java @@ -108,7 +108,7 @@ private static class StaticPubSubAsyncNodeSelection private final ClusterDistributionChannelWriter writer; @SuppressWarnings("unchecked") - public StaticPubSubAsyncNodeSelection(StatefulRedisClusterPubSubConnection globalConnection, + public StaticPubSubAsyncNodeSelection(StatefulRedisClusterPubSubConnection globalConnection, Predicate selector) { this.redisClusterNodes = globalConnection.getPartitions().stream().filter(selector).collect(Collectors.toList()); diff --git a/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java index 42316e9308..7f7e44cc78 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java @@ -31,7 +31,6 @@ import io.lettuce.core.api.async.RedisStringAsyncCommands; import io.lettuce.core.cluster.ClusterClientOptions; import io.lettuce.core.cluster.api.NodeSelectionSupport; -import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.models.partitions.RedisClusterNode; import io.lettuce.core.output.KeyStreamingChannel; @@ -67,11 +66,6 @@ public interface RedisAdvancedClusterAsyncCommands extends RedisClusterAsy */ RedisClusterAsyncCommands getConnection(String host, int port); - /** - * @return the underlying connection. - */ - StatefulRedisClusterConnection getStatefulConnection(); - /** * Select all upstream nodes. * diff --git a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java index ef8e3309c8..418fae1572 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java @@ -15,7 +15,6 @@ */ package io.lettuce.core.cluster.api.async; -import java.time.Duration; import java.util.List; import java.util.Map; @@ -38,14 +37,6 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< RedisScriptingAsyncCommands, RedisServerAsyncCommands, RedisSetAsyncCommands, RedisSortedSetAsyncCommands, RedisStreamAsyncCommands, RedisStringAsyncCommands { - /** - * Set the default timeout for operations. A zero timeout value indicates to not time out. - * - * @param timeout the timeout value - * @since 5.0 - */ - void setTimeout(Duration timeout); - /** * The asking command is required after a {@code -ASK} redirection. The client should issue {@code ASKING} before to * actually send the command to the target instance. See the Redis Cluster specification for more information. diff --git a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisAdvancedClusterReactiveCommands.java b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisAdvancedClusterReactiveCommands.java index cb0c154889..0690cbbb3b 100644 --- a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisAdvancedClusterReactiveCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisAdvancedClusterReactiveCommands.java @@ -29,7 +29,6 @@ import io.lettuce.core.api.reactive.RedisServerReactiveCommands; import io.lettuce.core.api.reactive.RedisStringReactiveCommands; import io.lettuce.core.cluster.ClusterClientOptions; -import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.output.KeyStreamingChannel; /** @@ -63,11 +62,6 @@ public interface RedisAdvancedClusterReactiveCommands extends RedisCluster */ RedisClusterReactiveCommands getConnection(String host, int port); - /** - * @return the underlying connection. - */ - StatefulRedisClusterConnection getStatefulConnection(); - /** * Delete one or more keys with pipelining. Cross-slot keys will result in multiple calls to the particular cluster nodes. * diff --git a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java index ea1d3405d9..69f0a537c0 100644 --- a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java @@ -15,7 +15,6 @@ */ package io.lettuce.core.cluster.api.reactive; -import java.time.Duration; import java.util.Map; import reactor.core.publisher.Flux; @@ -40,14 +39,6 @@ public interface RedisClusterReactiveCommands RedisSetReactiveCommands, RedisSortedSetReactiveCommands, RedisStreamReactiveCommands, RedisStringReactiveCommands { - /** - * Set the default timeout for operations. A zero timeout value indicates to not time out. - * - * @param timeout the timeout value - * @since 5.0 - */ - void setTimeout(Duration timeout); - /** * The asking command is required after a {@code -ASK} redirection. The client should issue {@code ASKING} before to * actually send the command to the target instance. See the Redis Cluster specification for more information. diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java index e1f9cf745b..d8302f6ccc 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/RedisAdvancedClusterCommands.java @@ -30,7 +30,6 @@ import io.lettuce.core.api.sync.RedisStringCommands; import io.lettuce.core.cluster.ClusterClientOptions; import io.lettuce.core.cluster.api.NodeSelectionSupport; -import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.models.partitions.RedisClusterNode; import io.lettuce.core.output.KeyStreamingChannel; @@ -64,11 +63,6 @@ public interface RedisAdvancedClusterCommands extends RedisClusterCommands */ RedisClusterCommands getConnection(String host, int port); - /** - * @return the underlying connection. - */ - StatefulRedisClusterConnection getStatefulConnection(); - /** * Select all upstream nodes. * diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java index df82a057f4..471ea9f19c 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java @@ -15,7 +15,6 @@ */ package io.lettuce.core.cluster.api.sync; -import java.time.Duration; import java.util.List; import io.lettuce.core.Range; @@ -37,14 +36,6 @@ public interface RedisClusterCommands RedisSetCommands, RedisSortedSetCommands, RedisStreamCommands, RedisStringCommands { - /** - * Set the default timeout for operations. A zero timeout value indicates to not time out. - * - * @param timeout the timeout value - * @since 5.0 - */ - void setTimeout(Duration timeout); - /** * The asking command is required after a {@code -ASK} redirection. The client should issue {@code ASKING} before to * actually send the command to the target instance. See the Redis Cluster specification for more information. diff --git a/src/main/java/io/lettuce/core/internal/AsyncConnectionProvider.java b/src/main/java/io/lettuce/core/internal/AsyncConnectionProvider.java index 9cfe96f986..9852807ab7 100644 --- a/src/main/java/io/lettuce/core/internal/AsyncConnectionProvider.java +++ b/src/main/java/io/lettuce/core/internal/AsyncConnectionProvider.java @@ -28,6 +28,8 @@ import java.util.function.Consumer; import java.util.function.Function; +import io.lettuce.core.api.AsyncCloseable; + /** * Non-blocking provider for connection objects. This connection provider is typed with a connection type and connection key * type. diff --git a/src/main/java/io/lettuce/core/masterreplica/Connections.java b/src/main/java/io/lettuce/core/masterreplica/Connections.java index 8df866b9cb..a471f3df52 100644 --- a/src/main/java/io/lettuce/core/masterreplica/Connections.java +++ b/src/main/java/io/lettuce/core/masterreplica/Connections.java @@ -16,7 +16,12 @@ package io.lettuce.core.masterreplica; import java.time.Duration; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ScheduledExecutorService; @@ -27,9 +32,9 @@ import reactor.util.function.Tuple2; import io.lettuce.core.RedisConnectionException; import io.lettuce.core.RedisURI; +import io.lettuce.core.api.AsyncCloseable; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.codec.StringCodec; -import io.lettuce.core.internal.AsyncCloseable; import io.lettuce.core.internal.Futures; import io.lettuce.core.models.role.RedisNodeDescription; import io.lettuce.core.output.StatusOutput; diff --git a/src/main/java/io/lettuce/core/masterreplica/ResumeAfter.java b/src/main/java/io/lettuce/core/masterreplica/ResumeAfter.java index 58f5e192a5..fd8149a4aa 100644 --- a/src/main/java/io/lettuce/core/masterreplica/ResumeAfter.java +++ b/src/main/java/io/lettuce/core/masterreplica/ResumeAfter.java @@ -18,7 +18,7 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import reactor.core.publisher.Mono; -import io.lettuce.core.internal.AsyncCloseable; +import io.lettuce.core.api.AsyncCloseable; /** * Utility to resume a {@link org.reactivestreams.Publisher} after termination. diff --git a/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyRefresh.java b/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyRefresh.java index 631b30dfa6..1b59e85d8d 100644 --- a/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyRefresh.java +++ b/src/main/java/io/lettuce/core/masterreplica/SentinelTopologyRefresh.java @@ -38,9 +38,9 @@ import io.lettuce.core.ConnectionFuture; import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; +import io.lettuce.core.api.AsyncCloseable; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.event.jfr.EventRecorder; -import io.lettuce.core.internal.AsyncCloseable; import io.lettuce.core.internal.Futures; import io.lettuce.core.internal.LettuceLists; import io.lettuce.core.pubsub.RedisPubSubAdapter; diff --git a/src/main/java/io/lettuce/core/pubsub/api/async/RedisPubSubAsyncCommands.java b/src/main/java/io/lettuce/core/pubsub/api/async/RedisPubSubAsyncCommands.java index d754dd046b..299f057de2 100644 --- a/src/main/java/io/lettuce/core/pubsub/api/async/RedisPubSubAsyncCommands.java +++ b/src/main/java/io/lettuce/core/pubsub/api/async/RedisPubSubAsyncCommands.java @@ -17,7 +17,6 @@ import io.lettuce.core.RedisFuture; import io.lettuce.core.api.async.RedisAsyncCommands; -import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; /** * Asynchronous and thread-safe Redis PubSub API. @@ -61,9 +60,4 @@ public interface RedisPubSubAsyncCommands extends RedisAsyncCommands */ RedisFuture unsubscribe(K... channels); - /** - * @return the underlying connection. - */ - StatefulRedisPubSubConnection getStatefulConnection(); - } diff --git a/src/main/java/io/lettuce/core/pubsub/api/reactive/RedisPubSubReactiveCommands.java b/src/main/java/io/lettuce/core/pubsub/api/reactive/RedisPubSubReactiveCommands.java index 1f49922daa..360e9edd69 100644 --- a/src/main/java/io/lettuce/core/pubsub/api/reactive/RedisPubSubReactiveCommands.java +++ b/src/main/java/io/lettuce/core/pubsub/api/reactive/RedisPubSubReactiveCommands.java @@ -19,7 +19,6 @@ import reactor.core.publisher.FluxSink; import reactor.core.publisher.Mono; import io.lettuce.core.api.reactive.RedisReactiveCommands; -import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; /** * Asynchronous and thread-safe Redis PubSub API. @@ -112,9 +111,4 @@ public interface RedisPubSubReactiveCommands extends RedisReactiveCommands */ Mono unsubscribe(K... channels); - /** - * @return the underlying connection. - */ - StatefulRedisPubSubConnection getStatefulConnection(); - } diff --git a/src/main/java/io/lettuce/core/pubsub/api/sync/RedisPubSubCommands.java b/src/main/java/io/lettuce/core/pubsub/api/sync/RedisPubSubCommands.java index 066747d0a8..19e36a3d7d 100644 --- a/src/main/java/io/lettuce/core/pubsub/api/sync/RedisPubSubCommands.java +++ b/src/main/java/io/lettuce/core/pubsub/api/sync/RedisPubSubCommands.java @@ -16,7 +16,6 @@ package io.lettuce.core.pubsub.api.sync; import io.lettuce.core.api.sync.RedisCommands; -import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; /** * Synchronous and thread-safe Redis PubSub API. @@ -56,9 +55,4 @@ public interface RedisPubSubCommands extends RedisCommands { */ void unsubscribe(K... channels); - /** - * @return the underlying connection. - */ - StatefulRedisPubSubConnection getStatefulConnection(); - } diff --git a/src/main/java/io/lettuce/core/sentinel/RedisSentinelAsyncCommandsImpl.java b/src/main/java/io/lettuce/core/sentinel/RedisSentinelAsyncCommandsImpl.java index 877a3b396e..d73252e29d 100644 --- a/src/main/java/io/lettuce/core/sentinel/RedisSentinelAsyncCommandsImpl.java +++ b/src/main/java/io/lettuce/core/sentinel/RedisSentinelAsyncCommandsImpl.java @@ -25,7 +25,11 @@ import io.lettuce.core.codec.RedisCodec; import io.lettuce.core.internal.LettuceAssert; import io.lettuce.core.output.CommandOutput; -import io.lettuce.core.protocol.*; +import io.lettuce.core.protocol.AsyncCommand; +import io.lettuce.core.protocol.Command; +import io.lettuce.core.protocol.CommandArgs; +import io.lettuce.core.protocol.ProtocolKeyword; +import io.lettuce.core.protocol.RedisCommand; import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection; import io.lettuce.core.sentinel.api.async.RedisSentinelAsyncCommands; @@ -171,12 +175,10 @@ public void close() { connection.close(); } - @Override public boolean isOpen() { return connection.isOpen(); } - @Override public StatefulRedisSentinelConnection getStatefulConnection() { return (StatefulRedisSentinelConnection) connection; } diff --git a/src/main/java/io/lettuce/core/sentinel/RedisSentinelReactiveCommandsImpl.java b/src/main/java/io/lettuce/core/sentinel/RedisSentinelReactiveCommandsImpl.java index 750e839c35..83de9c75b9 100644 --- a/src/main/java/io/lettuce/core/sentinel/RedisSentinelReactiveCommandsImpl.java +++ b/src/main/java/io/lettuce/core/sentinel/RedisSentinelReactiveCommandsImpl.java @@ -171,7 +171,6 @@ public boolean isOpen() { return getStatefulConnection().isOpen(); } - @Override public StatefulRedisSentinelConnection getStatefulConnection() { return (StatefulRedisSentinelConnection) super.getConnection(); } diff --git a/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java b/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java index 2e98ddb2db..6889adc760 100644 --- a/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java +++ b/src/main/java/io/lettuce/core/sentinel/api/async/RedisSentinelAsyncCommands.java @@ -15,15 +15,15 @@ */ package io.lettuce.core.sentinel.api.async; -import java.util.Map; -import java.util.List; import java.net.SocketAddress; +import java.util.List; +import java.util.Map; + import io.lettuce.core.KillArgs; import io.lettuce.core.RedisFuture; import io.lettuce.core.output.CommandOutput; import io.lettuce.core.protocol.CommandArgs; import io.lettuce.core.protocol.ProtocolKeyword; -import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection; /** * Asynchronous executed commands for Redis Sentinel. @@ -204,13 +204,4 @@ public interface RedisSentinelAsyncCommands { */ RedisFuture dispatch(ProtocolKeyword type, CommandOutput output, CommandArgs args); - /** - * @return {@code true} if the connection is open (connected and not closed). - */ - boolean isOpen(); - - /** - * @return the underlying connection. - */ - StatefulRedisSentinelConnection getStatefulConnection(); } diff --git a/src/main/java/io/lettuce/core/sentinel/api/reactive/RedisSentinelReactiveCommands.java b/src/main/java/io/lettuce/core/sentinel/api/reactive/RedisSentinelReactiveCommands.java index 6cbf828216..1e72c4dc42 100644 --- a/src/main/java/io/lettuce/core/sentinel/api/reactive/RedisSentinelReactiveCommands.java +++ b/src/main/java/io/lettuce/core/sentinel/api/reactive/RedisSentinelReactiveCommands.java @@ -15,15 +15,15 @@ */ package io.lettuce.core.sentinel.api.reactive; -import java.util.Map; import java.net.SocketAddress; +import java.util.Map; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; import io.lettuce.core.KillArgs; import io.lettuce.core.output.CommandOutput; import io.lettuce.core.protocol.CommandArgs; import io.lettuce.core.protocol.ProtocolKeyword; -import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; /** * Reactive executed commands for Redis Sentinel. @@ -204,13 +204,4 @@ public interface RedisSentinelReactiveCommands { */ Flux dispatch(ProtocolKeyword type, CommandOutput output, CommandArgs args); - /** - * @return {@code true} if the connection is open (connected and not closed). - */ - boolean isOpen(); - - /** - * @return the underlying connection. - */ - StatefulRedisSentinelConnection getStatefulConnection(); } diff --git a/src/main/java/io/lettuce/core/sentinel/api/sync/RedisSentinelCommands.java b/src/main/java/io/lettuce/core/sentinel/api/sync/RedisSentinelCommands.java index c5706a33f1..5248b0be88 100644 --- a/src/main/java/io/lettuce/core/sentinel/api/sync/RedisSentinelCommands.java +++ b/src/main/java/io/lettuce/core/sentinel/api/sync/RedisSentinelCommands.java @@ -23,7 +23,6 @@ import io.lettuce.core.output.CommandOutput; import io.lettuce.core.protocol.CommandArgs; import io.lettuce.core.protocol.ProtocolKeyword; -import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection; /** * Synchronous executed commands for Redis Sentinel. @@ -204,13 +203,4 @@ public interface RedisSentinelCommands { */ T dispatch(ProtocolKeyword type, CommandOutput output, CommandArgs args); - /** - * @return {@code true} if the connection is open (connected and not closed). - */ - boolean isOpen(); - - /** - * @return the underlying connection. - */ - StatefulRedisSentinelConnection getStatefulConnection(); } diff --git a/src/main/java/io/lettuce/core/support/AsyncPool.java b/src/main/java/io/lettuce/core/support/AsyncPool.java index f2f5c89c2d..4e5c3d2a35 100644 --- a/src/main/java/io/lettuce/core/support/AsyncPool.java +++ b/src/main/java/io/lettuce/core/support/AsyncPool.java @@ -18,7 +18,7 @@ import java.io.Closeable; import java.util.concurrent.CompletableFuture; -import io.lettuce.core.internal.AsyncCloseable; +import io.lettuce.core.api.AsyncCloseable; /** * Interface declaring non-blocking object pool methods allowing to {@link #acquire()} and {@link #release(Object)} objects. All diff --git a/src/main/java/io/lettuce/core/support/ConnectionWrapping.java b/src/main/java/io/lettuce/core/support/ConnectionWrapping.java index 142a0e6f9e..8999d79a98 100644 --- a/src/main/java/io/lettuce/core/support/ConnectionWrapping.java +++ b/src/main/java/io/lettuce/core/support/ConnectionWrapping.java @@ -23,9 +23,9 @@ import java.util.concurrent.ConcurrentHashMap; import io.lettuce.core.RedisException; +import io.lettuce.core.api.AsyncCloseable; import io.lettuce.core.api.StatefulConnection; import io.lettuce.core.internal.AbstractInvocationHandler; -import io.lettuce.core.internal.AsyncCloseable; /** * Utility to wrap pooled connections for return-on-close. diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt index 62e86109b5..1edb422858 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt @@ -149,26 +149,5 @@ interface BaseRedisCoroutinesCommands { */ fun dispatch(type: ProtocolKeyword, output: CommandOutput, args: CommandArgs): Flow - /** - * - * @return @code true} if the connection is open (connected and not closed). - */ - fun isOpen(): Boolean - - /** - * Disable or enable auto-flush behavior. Default is `true`. If autoFlushCommands is disabled, multiple commands can - * be issued without writing them actually to the transport. Commands are buffered until a [flushCommands] is - * issued. After calling [flushCommands] commands are sent to the transport and executed by Redis. - * - * @param autoFlush state of autoFlush. - */ - fun setAutoFlushCommands(autoFlush: Boolean) - - /** - * Flush pending commands. This commands forces a flush on the channel and can be used to buffer ("pipeline") commands to - * achieve batching. No-op if channel is not connected. - */ - fun flushCommands() - } diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt index 76c1f21f0e..f446b1e3d0 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt @@ -67,11 +67,5 @@ internal class BaseRedisCoroutinesCommandsImpl(internal val op override fun dispatch(type: ProtocolKeyword, output: CommandOutput, args: CommandArgs): Flow = ops.dispatch(type, output, args).asFlow() - override fun isOpen(): Boolean = ops.isOpen - - override fun setAutoFlushCommands(autoFlush: Boolean) = ops.setAutoFlushCommands(autoFlush) - - override fun flushCommands() = ops.flushCommands() - } diff --git a/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommands.kt index 9411b57587..07bd18a231 100644 --- a/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommands.kt @@ -21,8 +21,8 @@ import io.lettuce.core.KillArgs import io.lettuce.core.output.CommandOutput import io.lettuce.core.protocol.CommandArgs import io.lettuce.core.protocol.ProtocolKeyword -import java.net.SocketAddress import kotlinx.coroutines.flow.Flow +import java.net.SocketAddress /** * Coroutine executed commands for Redis Sentinel. @@ -204,11 +204,5 @@ interface RedisSentinelCoroutinesCommands { */ fun dispatch(type: ProtocolKeyword, output: CommandOutput, args: CommandArgs): Flow - /** - * - * @return @code true} if the connection is open (connected and not closed). - */ - fun isOpen(): Boolean - } diff --git a/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommandsImpl.kt index da56de496d..0473a88d8e 100644 --- a/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/sentinel/api/coroutines/RedisSentinelCoroutinesCommandsImpl.kt @@ -80,7 +80,5 @@ internal class RedisSentinelCoroutinesCommandsImpl(internal va override fun dispatch(type: ProtocolKeyword, output: CommandOutput, args: CommandArgs): Flow = ops.dispatch(type, output, args).asFlow() - override fun isOpen(): Boolean = ops.isOpen - } diff --git a/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java b/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java index a9bc62efc5..aadc45bdd8 100644 --- a/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java +++ b/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java @@ -147,31 +147,4 @@ public interface BaseRedisCommands { */ T dispatch(ProtocolKeyword type, CommandOutput output, CommandArgs args); - /** - * - * @return {@code true} if the connection is open (connected and not closed). - */ - boolean isOpen(); - - /** - * Reset the command state. Queued commands will be canceled and the internal state will be reset. This is useful when the - * internal state machine gets out of sync with the connection. - */ - void reset(); - - /** - * Disable or enable auto-flush behavior. Default is {@code true}. If autoFlushCommands is disabled, multiple commands can - * be issued without writing them actually to the transport. Commands are buffered until a {@link #flushCommands()} is - * issued. After calling {@link #flushCommands()} commands are sent to the transport and executed by Redis. - * - * @param autoFlush state of autoFlush. - */ - void setAutoFlushCommands(boolean autoFlush); - - /** - * Flush pending commands. This commands forces a flush on the channel and can be used to buffer ("pipeline") commands to - * achieve batching. No-op if channel is not connected. - */ - void flushCommands(); - } diff --git a/src/test/java/biz/paluch/redis/extensibility/LettuceGeoDemo.java b/src/test/java/biz/paluch/redis/extensibility/LettuceGeoDemo.java index 3843a3cac4..711b00c449 100644 --- a/src/test/java/biz/paluch/redis/extensibility/LettuceGeoDemo.java +++ b/src/test/java/biz/paluch/redis/extensibility/LettuceGeoDemo.java @@ -18,7 +18,12 @@ import java.util.List; import java.util.Set; -import io.lettuce.core.*; +import io.lettuce.core.GeoArgs; +import io.lettuce.core.GeoCoordinates; +import io.lettuce.core.GeoWithin; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; public class LettuceGeoDemo { @@ -26,7 +31,8 @@ public class LettuceGeoDemo { public static void main(String[] args) { RedisClient redisClient = RedisClient.create(RedisURI.Builder.redis("localhost", 6379).build()); - RedisCommands redis = redisClient.connect().sync(); + StatefulRedisConnection connection = redisClient.connect(); + RedisCommands redis = connection.sync(); String key = "my-geo-set"; redis.geoadd(key, 8.6638775, 49.5282537, "Weinheim", 8.3796281, 48.9978127, "Office tower", 8.665351, 49.553302, @@ -59,7 +65,7 @@ public static void main(String[] args) { GeoCoordinates weinheimGeopos = geopos.get(0); System.out.println("Coordinates: " + weinheimGeopos.getX() + "/" + weinheimGeopos.getY()); - redis.getStatefulConnection().close(); + connection.close(); redisClient.shutdown(); } } diff --git a/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClientIntegrationTests.java b/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClientIntegrationTests.java index dc3e706fd7..069ae8644c 100644 --- a/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClientIntegrationTests.java +++ b/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClientIntegrationTests.java @@ -65,7 +65,7 @@ void testPubsub() throws Exception { StatefulRedisPubSubConnection connection = client.connectPubSub(); RedisPubSubAsyncCommands commands = connection.async(); assertThat(commands).isInstanceOf(RedisPubSubAsyncCommandsImpl.class); - assertThat(commands.getStatefulConnection()).isInstanceOf(MyPubSubConnection.class); + assertThat(connection).isInstanceOf(MyPubSubConnection.class); commands.set("key", "value").get(); connection.close(); } diff --git a/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClusterClientIntegrationTests.java b/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClusterClientIntegrationTests.java index aa6a73b8b8..3c22876511 100644 --- a/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClusterClientIntegrationTests.java +++ b/src/test/java/biz/paluch/redis/extensibility/MyExtendedRedisClusterClientIntegrationTests.java @@ -65,7 +65,7 @@ void testConnection() throws Exception { RedisAdvancedClusterAsyncCommands commands = connection.async(); assertThat(commands).isInstanceOf(RedisAdvancedClusterAsyncCommandsImpl.class); - assertThat(commands.getStatefulConnection()).isInstanceOf(MyRedisClusterConnection.class); + assertThat(connection).isInstanceOf(MyRedisClusterConnection.class); commands.set("key", "value").get(); diff --git a/src/test/java/io/lettuce/core/AbstractRedisClientTest.java b/src/test/java/io/lettuce/core/AbstractRedisClientTest.java index 63d794ab7b..25d1a95ff1 100644 --- a/src/test/java/io/lettuce/core/AbstractRedisClientTest.java +++ b/src/test/java/io/lettuce/core/AbstractRedisClientTest.java @@ -19,6 +19,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.test.resource.DefaultRedisClient; import io.lettuce.test.resource.TestClientResources; @@ -30,6 +31,8 @@ public abstract class AbstractRedisClientTest extends TestSupport { protected static RedisClient client; + + protected StatefulRedisConnection connection; protected RedisCommands redis; @BeforeAll @@ -42,15 +45,19 @@ private static RedisClient newRedisClient() { return RedisClient.create(TestClientResources.get(), RedisURI.Builder.redis(host, port).build()); } - protected RedisCommands connect() { - RedisCommands connect = client.connect().sync(); - return connect; + protected StatefulRedisConnection connect() { + return client.connect(); + } + + protected RedisCommands getCommands() { + return connection.sync(); } @BeforeEach public void openConnection() throws Exception { client.setOptions(ClientOptions.builder().build()); - redis = connect(); + connection = connect(); + redis = getCommands(); boolean scriptRunning; do { @@ -73,8 +80,8 @@ public void openConnection() throws Exception { @AfterEach public void closeConnection() throws Exception { - if (redis != null) { - redis.getStatefulConnection().close(); + if (connection != null) { + connection.close(); } } } diff --git a/src/test/java/io/lettuce/core/AsyncConnectionIntegrationTests.java b/src/test/java/io/lettuce/core/AsyncConnectionIntegrationTests.java index 2e3e1ea826..2142f086e9 100644 --- a/src/test/java/io/lettuce/core/AsyncConnectionIntegrationTests.java +++ b/src/test/java/io/lettuce/core/AsyncConnectionIntegrationTests.java @@ -15,7 +15,7 @@ */ package io.lettuce.core; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import java.time.Duration; import java.util.ArrayList; @@ -98,12 +98,13 @@ void futureListener() { TestFutures.awaitOrTimeout(futures); - RedisAsyncCommands connection = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); - Long len = TestFutures.getOrTimeout(connection.llen(key)); + Long len = TestFutures.getOrTimeout(async.llen(key)); assertThat(len.intValue()).isEqualTo(1000); - RedisFuture> sort = connection.sort(key); + RedisFuture> sort = async.sort(key); assertThat(sort.isCancelled()).isFalse(); sort.thenRun(listener); @@ -113,7 +114,7 @@ void futureListener() { assertThat(run).hasSize(1); - connection.getStatefulConnection().close(); + connection.close(); } @Test @@ -128,16 +129,17 @@ public void run() { } }; - RedisAsyncCommands connection = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); - RedisFuture set = connection.set(key, value); + RedisFuture set = async.set(key, value); TestFutures.awaitOrTimeout(set); set.thenRun(listener); assertThat(run).hasSize(1); - connection.getStatefulConnection().close(); + connection.close(); } @Test diff --git a/src/test/java/io/lettuce/core/ClientIntegrationTests.java b/src/test/java/io/lettuce/core/ClientIntegrationTests.java index 23ad34efe8..b9defe64db 100644 --- a/src/test/java/io/lettuce/core/ClientIntegrationTests.java +++ b/src/test/java/io/lettuce/core/ClientIntegrationTests.java @@ -44,12 +44,15 @@ class ClientIntegrationTests extends TestSupport { private final RedisClient client; + + private final StatefulRedisConnection connection; private final RedisCommands redis; @Inject ClientIntegrationTests(RedisClient client, StatefulRedisConnection connection) { this.client = client; this.redis = connection.sync(); + this.connection = connection; this.redis.flushall(); } @@ -61,32 +64,13 @@ void close(@New StatefulRedisConnection connection) { assertThatThrownBy(() -> connection.sync().get(key)).isInstanceOf(RedisException.class); } - @Test - void statefulConnectionFromSync() { - assertThat(redis.getStatefulConnection().sync()).isSameAs(redis); - } - - @Test - void statefulConnectionFromAsync() { - RedisAsyncCommands async = client.connect().async(); - assertThat(async.getStatefulConnection().async()).isSameAs(async); - async.getStatefulConnection().close(); - } - - @Test - void statefulConnectionFromReactive() { - RedisAsyncCommands async = client.connect().async(); - assertThat(async.getStatefulConnection().reactive().getStatefulConnection()).isSameAs(async.getStatefulConnection()); - async.getStatefulConnection().close(); - } - @Test void timeout() { - redis.setTimeout(Duration.ofNanos(100)); + connection.setTimeout(Duration.ofNanos(100)); assertThatThrownBy(() -> redis.blpop(1, "unknown")).isInstanceOf(RedisCommandTimeoutException.class); - redis.setTimeout(Duration.ofSeconds(60)); + connection.setTimeout(Duration.ofSeconds(60)); } @Test @@ -128,10 +112,10 @@ public void onRedisDisconnected(RedisChannelHandler connection) { MyListener listener = new MyListener(); - redis.getStatefulConnection().addListener(listener); + connection.addListener(listener); redis.quit(); - Wait.untilTrue(redis::isOpen).waitOrTimeout(); + Wait.untilTrue(connection::isOpen).waitOrTimeout(); assertThat(listener.connect).hasValueGreaterThan(0); assertThat(listener.disconnect).hasValueGreaterThan(0); @@ -206,7 +190,7 @@ void reset() { RedisAsyncCommands async = connection.async(); connection.sync().set(key, value); - async.reset(); + connection.reset(); connection.sync().set(key, value); connection.sync().flushall(); @@ -217,7 +201,7 @@ void reset() { assertThat(eval.isDone()).isFalse(); assertThat(eval.isCancelled()).isFalse(); - async.reset(); + connection.reset(); Wait.untilTrue(eval::isCancelled).waitOrTimeout(); diff --git a/src/test/java/io/lettuce/core/ClientOptionsIntegrationTests.java b/src/test/java/io/lettuce/core/ClientOptionsIntegrationTests.java index da42f635e8..11f2d8d8f9 100644 --- a/src/test/java/io/lettuce/core/ClientOptionsIntegrationTests.java +++ b/src/test/java/io/lettuce/core/ClientOptionsIntegrationTests.java @@ -15,12 +15,8 @@ */ package io.lettuce.core; -import static io.lettuce.test.ConnectionTestUtil.getChannel; -import static io.lettuce.test.ConnectionTestUtil.getConnectionWatchdog; -import static io.lettuce.test.ConnectionTestUtil.getStack; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.fail; +import static io.lettuce.test.ConnectionTestUtil.*; +import static org.assertj.core.api.Assertions.*; import java.net.ServerSocket; import java.time.Duration; @@ -35,7 +31,6 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import io.lettuce.test.condition.EnabledOnCommand; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import io.lettuce.core.api.StatefulRedisConnection; @@ -43,11 +38,17 @@ import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.output.StatusOutput; -import io.lettuce.core.protocol.*; +import io.lettuce.core.protocol.AsyncCommand; +import io.lettuce.core.protocol.Command; +import io.lettuce.core.protocol.CommandArgs; +import io.lettuce.core.protocol.CommandType; +import io.lettuce.core.protocol.ConnectionWatchdog; +import io.lettuce.core.protocol.ProtocolVersion; import io.lettuce.test.LettuceExtension; import io.lettuce.test.TestFutures; import io.lettuce.test.Wait; import io.lettuce.test.WithPassword; +import io.lettuce.test.condition.EnabledOnCommand; import io.lettuce.test.settings.TestSettings; import io.netty.channel.Channel; @@ -113,8 +114,7 @@ void requestQueueSizeAppliedForReconnect() { client.setOptions(ClientOptions.builder().requestQueueSize(10).build()); - RedisAsyncCommands connection = client.connect().async(); - testHitRequestQueueLimit(connection); + testHitRequestQueueLimit(client.connect()); } @Test @@ -125,8 +125,9 @@ void testHitRequestQueueLimitReconnectWithAuthCommand() { client.setOptions(ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false) .requestQueueSize(10).build()); - RedisAsyncCommands connection = client.connect().async(); - connection.auth(passwd); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); + async.auth(passwd); testHitRequestQueueLimit(connection); }); } @@ -140,8 +141,9 @@ void testHitRequestQueueLimitReconnectWithAuthUsernamePasswordCommand() { client.setOptions(ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false) .requestQueueSize(10).build()); - RedisAsyncCommands connection = client.connect().async(); - connection.auth(username, passwd); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); + async.auth(username, passwd); testHitRequestQueueLimit(connection); }); } @@ -155,8 +157,7 @@ void testHitRequestQueueLimitReconnectWithUriAuth() { RedisURI redisURI = RedisURI.create(host, port); redisURI.setPassword(passwd); - RedisAsyncCommands connection = client.connect(redisURI).async(); - testHitRequestQueueLimit(connection); + testHitRequestQueueLimit(client.connect(redisURI)); }); } @@ -170,24 +171,23 @@ void testHitRequestQueueLimitReconnectWithUriAuthPingCommand() { RedisURI redisURI = RedisURI.create(host, port); redisURI.setPassword(passwd); - RedisAsyncCommands connection = client.connect(redisURI).async(); - testHitRequestQueueLimit(connection); + testHitRequestQueueLimit(client.connect(redisURI)); }); } - private void testHitRequestQueueLimit(RedisAsyncCommands connection) { + private void testHitRequestQueueLimit(StatefulRedisConnection connection) { - ConnectionWatchdog watchdog = getConnectionWatchdog(connection.getStatefulConnection()); + ConnectionWatchdog watchdog = getConnectionWatchdog(connection); watchdog.setListenOnChannelInactive(false); - connection.quit(); + connection.async().quit(); - Wait.untilTrue(() -> !connection.getStatefulConnection().isOpen()).waitOrTimeout(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); List> pings = new ArrayList<>(); for (int i = 0; i < 10; i++) { - pings.add(connection.ping()); + pings.add(connection.async().ping()); } watchdog.setListenOnChannelInactive(true); @@ -197,7 +197,7 @@ private void testHitRequestQueueLimit(RedisAsyncCommands connect assertThat(TestFutures.getOrTimeout(ping)).isEqualTo("PONG"); } - connection.getStatefulConnection().close(); + connection.close(); } @Test @@ -242,16 +242,17 @@ void disconnectedWithoutReconnect() { client.setOptions(ClientOptions.builder().autoReconnect(false).build()); - RedisAsyncCommands connection = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); - connection.quit(); - Wait.untilTrue(() -> !connection.getStatefulConnection().isOpen()).waitOrTimeout(); + async.quit(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); try { - connection.get(key); + async.get(key); } catch (Exception e) { assertThat(e).isInstanceOf(RedisException.class).hasMessageContaining("not connected"); } finally { - connection.getStatefulConnection().close(); + connection.close(); } } @@ -261,17 +262,18 @@ void disconnectedRejectCommands() { client.setOptions( ClientOptions.builder().disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS).build()); - RedisAsyncCommands connection = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); - getConnectionWatchdog(connection.getStatefulConnection()).setListenOnChannelInactive(false); - connection.quit(); - Wait.untilTrue(() -> !connection.getStatefulConnection().isOpen()).waitOrTimeout(); + getConnectionWatchdog(connection).setListenOnChannelInactive(false); + async.quit(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); try { - connection.get(key); + async.get(key); } catch (Exception e) { assertThat(e).isInstanceOf(RedisException.class).hasMessageContaining("not connected"); } finally { - connection.getStatefulConnection().close(); + connection.close(); } } @@ -281,12 +283,13 @@ void disconnectedAcceptCommands() { client.setOptions(ClientOptions.builder().autoReconnect(false) .disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS).build()); - RedisAsyncCommands connection = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); - connection.quit(); - Wait.untilTrue(() -> !connection.getStatefulConnection().isOpen()).waitOrTimeout(); - connection.get(key); - connection.getStatefulConnection().close(); + async.quit(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); + async.get(key); + connection.close(); } @Test @@ -294,13 +297,14 @@ void disconnectedAcceptCommands() { void pingBeforeConnect(StatefulRedisConnection sharedConnection) { sharedConnection.sync().set(key, value); - RedisCommands connection = client.connect().sync(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); try { - String result = connection.get(key); + String result = sync.get(key); assertThat(result).isEqualTo(value); } finally { - connection.getStatefulConnection().close(); + connection.close(); } } @@ -328,13 +332,14 @@ void connectWithAuthentication() { WithPassword.run(client, () -> { RedisURI redisURI = RedisURI.Builder.redis(host, port).withPassword(passwd).build(); - RedisCommands connection = client.connect(redisURI).sync(); + StatefulRedisConnection connection = client.connect(redisURI); + RedisCommands sync = connection.sync(); try { - String result = connection.info(); + String result = sync.info(); assertThat(result).contains("memory"); } finally { - connection.getStatefulConnection().close(); + connection.close(); } }); } @@ -368,13 +373,14 @@ void sslAndAuthentication() { RedisURI redisURI = RedisURI.Builder.redis(host, 6443).withPassword(passwd).withVerifyPeer(false).withSsl(true) .build(); - RedisCommands connection = client.connect(redisURI).sync(); + StatefulRedisConnection connection = client.connect(redisURI); + RedisCommands sync = connection.sync(); try { - String result = connection.info(); + String result = sync.info(); assertThat(result).contains("memory"); } finally { - connection.getStatefulConnection().close(); + connection.close(); } }); diff --git a/src/test/java/io/lettuce/core/ConnectMethodsIntegrationTests.java b/src/test/java/io/lettuce/core/ConnectMethodsIntegrationTests.java index 3b330140a5..7cffabd943 100644 --- a/src/test/java/io/lettuce/core/ConnectMethodsIntegrationTests.java +++ b/src/test/java/io/lettuce/core/ConnectMethodsIntegrationTests.java @@ -20,9 +20,11 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.cluster.RedisClusterClient; import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.api.async.AsyncNodeSelection; +import io.lettuce.core.cluster.pubsub.StatefulRedisClusterPubSubConnection; import io.lettuce.test.LettuceExtension; /** @@ -48,12 +50,16 @@ void standaloneSync() { @Test void standaloneAsync() { - redisClient.connect().async().getStatefulConnection().close(); + StatefulRedisConnection connection = redisClient.connect(); + connection.async(); + connection.close(); } @Test void standaloneReactive() { - redisClient.connect().reactive().getStatefulConnection().close(); + StatefulRedisConnection connection = redisClient.connect(); + connection.reactive(); + connection.close(); } @Test @@ -63,60 +69,36 @@ void standaloneStateful() { // PubSub @Test - void pubsubSync() { - redisClient.connectPubSub().close(); - } - - @Test - void pubsubAsync() { - redisClient.connectPubSub().close(); - } - - @Test - void pubsubReactive() { - redisClient.connectPubSub().close(); - } - - @Test - void pubsubStateful() { + void pubsub() { redisClient.connectPubSub().close(); } // Sentinel @Test - void sentinelSync() { - redisClient.connectSentinel().sync().getStatefulConnection().close(); - } - - @Test - void sentinelAsync() { - redisClient.connectSentinel().async().getStatefulConnection().close(); - } - - @Test - void sentinelReactive() { - redisClient.connectSentinel().reactive().getStatefulConnection().close(); - } - - @Test - void sentinelStateful() { + void sentinel() { redisClient.connectSentinel().close(); } // Cluster @Test void clusterSync() { - clusterClient.connect().sync().getStatefulConnection().close(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + connection.sync(); + connection.close(); } @Test void clusterAsync() { - clusterClient.connect().async().getStatefulConnection().close(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + connection.async(); + connection.close(); } @Test void clusterReactive() { - clusterClient.connect().reactive().getStatefulConnection().close(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + connection.reactive(); + connection.close(); } @Test @@ -131,7 +113,9 @@ void clusterPubSubSync() { @Test void clusterPubSubAsync() { - clusterClient.connectPubSub().async().getStatefulConnection().close(); + StatefulRedisClusterPubSubConnection connection = clusterClient.connectPubSub(); + connection.async(); + connection.close(); } @Test diff --git a/src/test/java/io/lettuce/core/ConnectionCommandIntegrationTests.java b/src/test/java/io/lettuce/core/ConnectionCommandIntegrationTests.java index 93843bcdfb..0b1f58c634 100644 --- a/src/test/java/io/lettuce/core/ConnectionCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/ConnectionCommandIntegrationTests.java @@ -31,7 +31,11 @@ import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.internal.LettuceStrings; import io.lettuce.core.protocol.ProtocolVersion; -import io.lettuce.test.*; +import io.lettuce.test.Delay; +import io.lettuce.test.LettuceExtension; +import io.lettuce.test.TestFutures; +import io.lettuce.test.Wait; +import io.lettuce.test.WithPassword; import io.lettuce.test.condition.EnabledOnCommand; /** @@ -43,11 +47,14 @@ class ConnectionCommandIntegrationTests extends TestSupport { private final RedisClient client; + + private final StatefulRedisConnection connection; private final RedisCommands redis; @Inject ConnectionCommandIntegrationTests(RedisClient client, StatefulRedisConnection connection) { this.client = client; + this.connection = connection; this.redis = connection.sync(); } @@ -71,9 +78,10 @@ void auth() { assertThat(connection.set(key, value)).isEqualTo("OK"); RedisURI redisURI = RedisURI.Builder.redis(host, port).withDatabase(2).withPassword(passwd).build(); - RedisCommands authConnection = client.connect(redisURI).sync(); - authConnection.ping(); - authConnection.getStatefulConnection().close(); + try (StatefulRedisConnection authConnection = client.connect(redisURI)) { + RedisCommands sync = authConnection.sync(); + sync.ping(); + } }); } @@ -103,9 +111,11 @@ void authWithUsername() { assertThat(connection.del("cached:demo")).isEqualTo(1); RedisURI redisURI = RedisURI.Builder.redis(host, port).withDatabase(2).withPassword(passwd).build(); - RedisCommands authConnection = client.connect(redisURI).sync(); - authConnection.ping(); - authConnection.getStatefulConnection().close(); + RedisCommands sync; + try (StatefulRedisConnection authConnection = client.connect(redisURI)) { + sync = authConnection.sync(); + sync.ping(); + } }); } @@ -117,17 +127,15 @@ void resp2HandShakeWithUsernamePassword() { RedisClient clientResp2 = RedisClient.create(redisURI); clientResp2.setOptions( ClientOptions.builder().pingBeforeActivateConnection(false).protocolVersion(ProtocolVersion.RESP2).build()); - RedisCommands connTestResp2 = null; + StatefulRedisConnection connTestResp2 = null; try { - connTestResp2 = clientResp2.connect().sync(); - assertThat(redis.ping()).isEqualTo("PONG"); + connTestResp2 = clientResp2.connect(); + assertThat(connTestResp2.sync().ping()).isEqualTo("PONG"); } catch (Exception e) { } finally { assertThat(connTestResp2).isNotNull(); - if (connTestResp2 != null) { - connTestResp2.getStatefulConnection().close(); - } + connTestResp2.close(); } clientResp2.shutdown(); } @@ -167,15 +175,16 @@ void authReconnect() { client.setOptions( ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false).build()); - RedisCommands connection = client.connect().sync(); - assertThat(connection.auth(passwd)).isEqualTo("OK"); - assertThat(connection.set(key, value)).isEqualTo("OK"); - connection.quit(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); + assertThat(sync.auth(passwd)).isEqualTo("OK"); + assertThat(sync.set(key, value)).isEqualTo("OK"); + sync.quit(); Delay.delay(Duration.ofMillis(100)); - assertThat(connection.get(key)).isEqualTo(value); + assertThat(sync.get(key)).isEqualTo(value); - connection.getStatefulConnection().close(); + connection.close(); }); } @@ -186,23 +195,24 @@ void authReconnectRedis6() { client.setOptions( ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false).build()); - RedisCommands connection = client.connect().sync(); - assertThat(connection.auth(passwd)).isEqualTo("OK"); - assertThat(connection.set(key, value)).isEqualTo("OK"); - connection.quit(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); + assertThat(sync.auth(passwd)).isEqualTo("OK"); + assertThat(sync.set(key, value)).isEqualTo("OK"); + sync.quit(); Delay.delay(Duration.ofMillis(100)); - assertThat(connection.get(key)).isEqualTo(value); + assertThat(sync.get(key)).isEqualTo(value); // reconnect with username/password - assertThat(connection.auth(username, passwd)).isEqualTo("OK"); - assertThat(connection.set(key, value)).isEqualTo("OK"); - connection.quit(); + assertThat(sync.auth(username, passwd)).isEqualTo("OK"); + assertThat(sync.set(key, value)).isEqualTo("OK"); + sync.quit(); Delay.delay(Duration.ofMillis(100)); - assertThat(connection.get(key)).isEqualTo(value); + assertThat(sync.get(key)).isEqualTo(value); - connection.getStatefulConnection().close(); + connection.close(); }); } @@ -212,7 +222,7 @@ void selectReconnect() { redis.set(key, value); redis.quit(); - Wait.untilTrue(redis::isOpen).waitOrTimeout(); + Wait.untilTrue(connection::isOpen).waitOrTimeout(); assertThat(redis.get(key)).isEqualTo(value); } @@ -220,23 +230,23 @@ void selectReconnect() { void getSetReconnect() { redis.set(key, value); redis.quit(); - Wait.untilTrue(redis::isOpen).waitOrTimeout(); + Wait.untilTrue(connection::isOpen).waitOrTimeout(); assertThat(redis.get(key)).isEqualTo(value); } @Test void authInvalidPassword() { - RedisAsyncCommands async = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); try { TestFutures.awaitOrTimeout(async.auth("invalid")); fail("Authenticated with invalid password"); } catch (RedisException e) { assertThat(e.getMessage()).startsWith("ERR").contains("AUTH"); - StatefulRedisConnectionImpl statefulRedisCommands = (StatefulRedisConnectionImpl) async - .getStatefulConnection(); + StatefulRedisConnectionImpl statefulRedisCommands = (StatefulRedisConnectionImpl) connection; assertThat(statefulRedisCommands.getConnectionState()).extracting("password").isNull(); } finally { - async.getStatefulConnection().close(); + connection.close(); } } @@ -247,48 +257,50 @@ void authInvalidUsernamePassword() { WithPassword.run(client, () -> { client.setOptions( ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false).build()); - RedisCommands connection = client.connect().sync(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); - assertThat(connection.auth(username, passwd)).isEqualTo("OK"); + assertThat(sync.auth(username, passwd)).isEqualTo("OK"); - assertThatThrownBy(() -> connection.auth(username, "invalid")) + assertThatThrownBy(() -> sync.auth(username, "invalid")) .hasMessageContaining("WRONGPASS invalid username-password pair"); - assertThat(connection.auth(aclUsername, aclPasswd)).isEqualTo("OK"); + assertThat(sync.auth(aclUsername, aclPasswd)).isEqualTo("OK"); - assertThatThrownBy(() -> connection.auth(aclUsername, "invalid")) + assertThatThrownBy(() -> sync.auth(aclUsername, "invalid")) .hasMessageContaining("WRONGPASS invalid username-password pair"); - connection.getStatefulConnection().close(); + connection.close(); }); } @Test @EnabledOnCommand("ACL") void authInvalidDefaultPasswordNoACL() { - RedisAsyncCommands async = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); // When the database is not secured the AUTH default invalid command returns OK try { Future auth = async.auth(username, "invalid"); assertThat(TestFutures.getOrTimeout(auth)).isEqualTo("OK"); } finally { - async.getStatefulConnection().close(); + connection.close(); } } @Test void authInvalidUsernamePasswordNoACL() { - RedisAsyncCommands async = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); try { TestFutures.awaitOrTimeout(async.select(1024)); fail("Selected invalid db index"); } catch (RedisException e) { assertThat(e.getMessage()).startsWith("ERR"); - StatefulRedisConnectionImpl statefulRedisCommands = (StatefulRedisConnectionImpl) async - .getStatefulConnection(); + StatefulRedisConnectionImpl statefulRedisCommands = (StatefulRedisConnectionImpl) connection; assertThat(statefulRedisCommands.getConnectionState()).extracting("db").isEqualTo(0); } finally { - async.getStatefulConnection().close(); + connection.close(); } } diff --git a/src/test/java/io/lettuce/core/CustomCodecIntegrationTests.java b/src/test/java/io/lettuce/core/CustomCodecIntegrationTests.java index b71299f880..908010b22d 100644 --- a/src/test/java/io/lettuce/core/CustomCodecIntegrationTests.java +++ b/src/test/java/io/lettuce/core/CustomCodecIntegrationTests.java @@ -15,9 +15,14 @@ */ package io.lettuce.core; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.*; +import static org.assertj.core.api.Assertions.*; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -34,7 +39,11 @@ import reactor.test.StepVerifier; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; -import io.lettuce.core.codec.*; +import io.lettuce.core.codec.ByteArrayCodec; +import io.lettuce.core.codec.CipherCodec; +import io.lettuce.core.codec.CompressionCodec; +import io.lettuce.core.codec.RedisCodec; +import io.lettuce.core.codec.StringCodec; import io.lettuce.test.LettuceExtension; /** @@ -96,67 +105,73 @@ void testJavaSerializerReactive() { @Test void testDeflateCompressedJavaSerializer() { - RedisCommands connection = client + StatefulRedisConnection connection = client .connect( - CompressionCodec.valueCompressor(new SerializedObjectCodec(), CompressionCodec.CompressionType.DEFLATE)) + CompressionCodec.valueCompressor(new SerializedObjectCodec(), + CompressionCodec.CompressionType.DEFLATE)); + RedisCommands sync = connection .sync(); List list = list("one", "two"); - connection.set(key, list); - assertThat(connection.get(key)).isEqualTo(list); + sync.set(key, list); + assertThat(sync.get(key)).isEqualTo(list); - connection.getStatefulConnection().close(); + connection.close(); } @Test void testGzipompressedJavaSerializer() { - RedisCommands connection = client - .connect(CompressionCodec.valueCompressor(new SerializedObjectCodec(), CompressionCodec.CompressionType.GZIP)) - .sync(); + StatefulRedisConnection connection = client + .connect(CompressionCodec.valueCompressor(new SerializedObjectCodec(), CompressionCodec.CompressionType.GZIP)); + RedisCommands sync = connection.sync(); List list = list("one", "two"); - connection.set(key, list); - assertThat(connection.get(key)).isEqualTo(list); + sync.set(key, list); + assertThat(sync.get(key)).isEqualTo(list); - connection.getStatefulConnection().close(); + connection.close(); } @Test void testEncryptedCodec() { - RedisCommands connection = client.connect(CipherCodec.forValues(StringCodec.UTF8, encrypt, decrypt)) + StatefulRedisConnection connection = client + .connect(CipherCodec.forValues(StringCodec.UTF8, encrypt, decrypt)); + RedisCommands sync = connection .sync(); - connection.set(key, "foobar"); - assertThat(connection.get(key)).isEqualTo("foobar"); + sync.set(key, "foobar"); + assertThat(sync.get(key)).isEqualTo("foobar"); - connection.getStatefulConnection().close(); + connection.close(); } @Test void testByteCodec() { - RedisCommands connection = client.connect(new ByteArrayCodec()).sync(); + StatefulRedisConnection connection = client.connect(new ByteArrayCodec()); + RedisCommands sync = connection.sync(); String value = "üöäü+#"; - connection.set(key.getBytes(), value.getBytes()); - assertThat(connection.get(key.getBytes())).isEqualTo(value.getBytes()); - connection.set(key.getBytes(), null); - assertThat(connection.get(key.getBytes())).isEqualTo(new byte[0]); + sync.set(key.getBytes(), value.getBytes()); + assertThat(sync.get(key.getBytes())).isEqualTo(value.getBytes()); + sync.set(key.getBytes(), null); + assertThat(sync.get(key.getBytes())).isEqualTo(new byte[0]); - List keys = connection.keys(key.getBytes()); + List keys = sync.keys(key.getBytes()); assertThat(keys).contains(key.getBytes()); - connection.getStatefulConnection().close(); + connection.close(); } @Test void testByteBufferCodec() { - RedisCommands connection = client.connect(new ByteBufferCodec()).sync(); + StatefulRedisConnection connection = client.connect(new ByteBufferCodec()); + RedisCommands sync = connection.sync(); String value = "üöäü+#"; ByteBuffer wrap = ByteBuffer.wrap(value.getBytes()); - connection.set(wrap, wrap); + sync.set(wrap, wrap); - List keys = connection.keys(wrap); + List keys = sync.keys(wrap); assertThat(keys).hasSize(1); ByteBuffer byteBuffer = keys.get(0); byte[] bytes = new byte[byteBuffer.remaining()]; @@ -164,23 +179,24 @@ void testByteBufferCodec() { assertThat(bytes).isEqualTo(value.getBytes()); - connection.getStatefulConnection().close(); + connection.close(); } @Test void testComposedCodec() { RedisCodec composed = RedisCodec.of(StringCodec.ASCII, new SerializedObjectCodec()); - RedisCommands connection = client.connect(composed).sync(); + StatefulRedisConnection connection = client.connect(composed); + RedisCommands sync = connection.sync(); - connection.set(key, new Person()); + sync.set(key, new Person()); - List keys = connection.keys(key); + List keys = sync.keys(key); assertThat(keys).hasSize(1); - assertThat(connection.get(key)).isInstanceOf(Person.class); + assertThat(sync.get(key)).isInstanceOf(Person.class); - connection.getStatefulConnection().close(); + connection.close(); } class SerializedObjectCodec implements RedisCodec { diff --git a/src/test/java/io/lettuce/core/ReactiveConnectionIntegrationTests.java b/src/test/java/io/lettuce/core/ReactiveConnectionIntegrationTests.java index 749d449fec..315fb85b58 100644 --- a/src/test/java/io/lettuce/core/ReactiveConnectionIntegrationTests.java +++ b/src/test/java/io/lettuce/core/ReactiveConnectionIntegrationTests.java @@ -15,9 +15,9 @@ */ package io.lettuce.core; -import static io.lettuce.core.ClientOptions.DisconnectedBehavior.REJECT_COMMANDS; +import static io.lettuce.core.ClientOptions.DisconnectedBehavior.*; import static io.lettuce.core.ScriptOutputType.INTEGER; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import java.time.Duration; import java.util.ArrayList; @@ -93,12 +93,7 @@ void fireCommandAfterObserve() { @Test void isOpen() { - assertThat(reactive.isOpen()).isTrue(); - } - - @Test - void getStatefulConnection() { - assertThat(reactive.getStatefulConnection()).isSameAs(connection); + assertThat(connection.isOpen()).isTrue(); } @Test @@ -113,7 +108,7 @@ void testCancelCommand(@New StatefulRedisConnection connection) reactive.set(key, value).subscribe(new CompletionSubscriber(result)); Delay.delay(Duration.ofMillis(50)); - reactive.reset(); + connection.reset(); assertThat(result).isEmpty(); } @@ -138,7 +133,7 @@ void testMonoMultiCancel(@New StatefulRedisConnection connection set.subscribe(new CompletionSubscriber(result)); Delay.delay(Duration.ofMillis(50)); - reactive.reset(); + connection.reset(); assertThat(result).isEmpty(); } @@ -158,7 +153,7 @@ void testFluxCancel(@New StatefulRedisConnection connection) { set.subscribe(new CompletionSubscriber(result)); Delay.delay(Duration.ofMillis(100)); - reactive.reset(); + connection.reset(); assertThat(result).isEmpty(); } @@ -185,7 +180,8 @@ void transactional(RedisClient client) throws Exception { final CountDownLatch sync = new CountDownLatch(1); - RedisReactiveCommands reactive = client.connect().reactive(); + StatefulRedisConnection connection = client.connect(); + RedisReactiveCommands reactive = connection.reactive(); reactive.multi().subscribe(multiResponse -> { reactive.set(key, "1").subscribe(); @@ -200,7 +196,7 @@ void transactional(RedisClient client) throws Exception { String result = redis.get(key); assertThat(result).isEqualTo("2"); - reactive.getStatefulConnection().close(); + connection.close(); } @Test @@ -270,7 +266,8 @@ void publishOnSchedulerTest(RedisClient client) { client.setOptions(ClientOptions.builder().publishOnScheduler(true).build()); - RedisReactiveCommands reactive = client.connect().reactive(); + StatefulRedisConnection connection = client.connect(); + RedisReactiveCommands reactive = connection.reactive(); int counter = 0; for (int i = 0; i < 1000; i++) { @@ -281,7 +278,7 @@ void publishOnSchedulerTest(RedisClient client) { assertThat(counter).isZero(); - reactive.getStatefulConnection().close(); + connection.close(); } private static Subscriber createSubscriberWithExceptionOnComplete() { diff --git a/src/test/java/io/lettuce/core/RedisClientUnitTests.java b/src/test/java/io/lettuce/core/RedisClientUnitTests.java index 3fc8228571..fc92053035 100644 --- a/src/test/java/io/lettuce/core/RedisClientUnitTests.java +++ b/src/test/java/io/lettuce/core/RedisClientUnitTests.java @@ -15,12 +15,9 @@ */ package io.lettuce.core; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; import java.io.Closeable; import java.lang.reflect.Field; @@ -32,7 +29,7 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import io.lettuce.core.internal.AsyncCloseable; +import io.lettuce.core.api.AsyncCloseable; import io.lettuce.core.resource.ClientResources; import io.lettuce.test.ReflectionTestUtils; import io.netty.util.concurrent.ImmediateEventExecutor; diff --git a/src/test/java/io/lettuce/core/ScanStreamIntegrationTests.java b/src/test/java/io/lettuce/core/ScanStreamIntegrationTests.java index 21c058a8d0..1b465ef082 100644 --- a/src/test/java/io/lettuce/core/ScanStreamIntegrationTests.java +++ b/src/test/java/io/lettuce/core/ScanStreamIntegrationTests.java @@ -64,7 +64,7 @@ void shouldScanIteratively() { ScanIterator scan = ScanIterator.scan(redis); List list = Flux.fromIterable(() -> scan).collectList().block(); - RedisReactiveCommands reactive = redis.getStatefulConnection().reactive(); + RedisReactiveCommands reactive = connection.reactive(); StepVerifier.create(ScanStream.scan(reactive, ScanArgs.Builder.limit(200)).take(250)).expectNextCount(250) .verifyComplete(); @@ -78,7 +78,7 @@ void shouldHscanIteratively() { redis.hset(key, "field-" + i, "value-" + i); } - RedisReactiveCommands reactive = redis.getStatefulConnection().reactive(); + RedisReactiveCommands reactive = connection.reactive(); StepVerifier.create(ScanStream.hscan(reactive, key, ScanArgs.Builder.limit(200)).take(250)).expectNextCount(250) .verifyComplete(); @@ -92,7 +92,7 @@ void shouldSscanIteratively() { redis.sadd(key, "value-" + i); } - RedisReactiveCommands reactive = redis.getStatefulConnection().reactive(); + RedisReactiveCommands reactive = connection.reactive(); StepVerifier.create(ScanStream.sscan(reactive, key, ScanArgs.Builder.limit(200)), 0).thenRequest(250) .expectNextCount(250).thenCancel().verify(); @@ -106,7 +106,7 @@ void shouldZscanIteratively() { redis.zadd(key, (double) i, "value-" + i); } - RedisReactiveCommands reactive = redis.getStatefulConnection().reactive(); + RedisReactiveCommands reactive = connection.reactive(); StepVerifier.create(ScanStream.zscan(reactive, key, ScanArgs.Builder.limit(200)).take(250)).expectNextCount(250) .verifyComplete(); diff --git a/src/test/java/io/lettuce/core/SslIntegrationTests.java b/src/test/java/io/lettuce/core/SslIntegrationTests.java index 7df5f66b23..48f1cf3b7d 100644 --- a/src/test/java/io/lettuce/core/SslIntegrationTests.java +++ b/src/test/java/io/lettuce/core/SslIntegrationTests.java @@ -39,7 +39,9 @@ import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.masterslave.MasterSlave; +import io.lettuce.core.masterslave.StatefulRedisMasterSlaveConnection; import io.lettuce.core.protocol.ProtocolVersion; +import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; import io.lettuce.core.pubsub.api.sync.RedisPubSubCommands; import io.lettuce.test.CanConnect; import io.lettuce.test.Delay; @@ -109,10 +111,11 @@ static void beforeClass() { @Test void standaloneWithSsl() { - RedisCommands connection = redisClient.connect(URI_NO_VERIFY).sync(); - connection.set("key", "value"); - assertThat(connection.get("key")).isEqualTo("value"); - connection.getStatefulConnection().close(); + try (StatefulRedisConnection connection = redisClient.connect(URI_NO_VERIFY)) { + RedisCommands sync = connection.sync(); + sync.set("key", "value"); + assertThat(sync.get("key")).isEqualTo("value"); + } } @Test @@ -258,11 +261,12 @@ void standaloneWithOpenSslFailsWithWrongTruststore() { @Test void regularSslWithReconnect() { - RedisCommands connection = redisClient.connect(URI_NO_VERIFY).sync(); - connection.quit(); - Delay.delay(Duration.ofMillis(200)); - assertThat(connection.ping()).isEqualTo("PONG"); - connection.getStatefulConnection().close(); + try (StatefulRedisConnection connection = redisClient.connect(URI_NO_VERIFY)) { + RedisCommands sync = connection.sync(); + sync.quit(); + Delay.delay(Duration.ofMillis(200)); + assertThat(sync.ping()).isEqualTo("PONG"); + } } @Test @@ -276,11 +280,12 @@ void sslWithVerificationWillFail() { @Test void masterSlaveWithSsl() { - RedisCommands connection = MasterSlave - .connect(redisClient, StringCodec.UTF8, MASTER_SLAVE_URIS_NO_VERIFY).sync(); - connection.set("key", "value"); - assertThat(connection.get("key")).isEqualTo("value"); - connection.getStatefulConnection().close(); + try (StatefulRedisMasterSlaveConnection connection = MasterSlave.connect(redisClient, StringCodec.UTF8, + MASTER_SLAVE_URIS_NO_VERIFY)) { + RedisCommands sync = connection.sync(); + sync.set("key", "value"); + assertThat(sync.get("key")).isEqualTo("value"); + } } @Test @@ -334,12 +339,13 @@ void masterSlaveWithJdkSslFailsWithWrongTruststore() { @Test void masterSlaveSslWithReconnect() { - RedisCommands connection = MasterSlave - .connect(redisClient, StringCodec.UTF8, MASTER_SLAVE_URIS_NO_VERIFY).sync(); - connection.quit(); - Delay.delay(Duration.ofMillis(200)); - assertThat(connection.ping()).isEqualTo("PONG"); - connection.getStatefulConnection().close(); + try (StatefulRedisMasterSlaveConnection connection = MasterSlave.connect(redisClient, StringCodec.UTF8, + MASTER_SLAVE_URIS_NO_VERIFY)) { + RedisCommands sync = connection.sync(); + sync.quit(); + Delay.delay(Duration.ofMillis(200)); + assertThat(sync.ping()).isEqualTo("PONG"); + } } @Test @@ -376,23 +382,25 @@ void masterSlaveSslWithAllInvalidHostsWillFail() { @Test void pubSubSsl() { - RedisPubSubCommands connection = redisClient.connectPubSub(URI_NO_VERIFY).sync(); - connection.subscribe("c1"); - connection.subscribe("c2"); + StatefulRedisPubSubConnection connection1 = redisClient.connectPubSub(URI_NO_VERIFY); + RedisPubSubCommands sync1 = connection1.sync(); + sync1.subscribe("c1"); + sync1.subscribe("c2"); Delay.delay(Duration.ofMillis(200)); - RedisPubSubCommands connection2 = redisClient.connectPubSub(URI_NO_VERIFY).sync(); + StatefulRedisPubSubConnection connection2 = redisClient.connectPubSub(URI_NO_VERIFY); + RedisPubSubCommands sync2 = connection2.sync(); - assertThat(connection2.pubsubChannels()).contains("c1", "c2"); - connection.quit(); + assertThat(sync2.pubsubChannels()).contains("c1", "c2"); + sync1.quit(); Delay.delay(Duration.ofMillis(200)); - Wait.untilTrue(connection::isOpen).waitOrTimeout(); - Wait.untilEquals(2, () -> connection2.pubsubChannels().size()).waitOrTimeout(); + Wait.untilTrue(connection1::isOpen).waitOrTimeout(); + Wait.untilEquals(2, () -> sync2.pubsubChannels().size()).waitOrTimeout(); - assertThat(connection2.pubsubChannels()).contains("c1", "c2"); + assertThat(sync2.pubsubChannels()).contains("c1", "c2"); - connection.getStatefulConnection().close(); - connection2.getStatefulConnection().close(); + connection1.close(); + connection2.close(); } private static RedisURI.Builder sslURIBuilder(int portOffset) { diff --git a/src/test/java/io/lettuce/core/cluster/AdvancedClusterClientIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/AdvancedClusterClientIntegrationTests.java index f5b755c8b2..8908c3e520 100644 --- a/src/test/java/io/lettuce/core/cluster/AdvancedClusterClientIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/AdvancedClusterClientIntegrationTests.java @@ -114,7 +114,7 @@ void invalidHost() { @Test void partitions() { - Partitions partitions = async.getStatefulConnection().getPartitions(); + Partitions partitions = clusterConnection.getPartitions(); assertThat(partitions).hasSize(4); } @@ -129,7 +129,7 @@ void differentConnections() { assertThat(nodeId).isNotSameAs(hostAndPort); } - StatefulRedisClusterConnection statefulConnection = async.getStatefulConnection(); + StatefulRedisClusterConnection statefulConnection = clusterConnection; for (RedisClusterNode redisClusterNode : clusterClient.getPartitions()) { StatefulRedisConnection nodeId = statefulConnection.getConnection(redisClusterNode.getNodeId()); @@ -304,7 +304,7 @@ void clientSetname() { sync.clientSetname(name); for (RedisClusterNode redisClusterNode : clusterClient.getPartitions()) { - RedisClusterCommands nodeConnection = async.getStatefulConnection().sync() + RedisClusterCommands nodeConnection = clusterConnection.sync() .getConnection(redisClusterNode.getNodeId()); assertThat(nodeConnection.clientList()).contains(name); } @@ -453,15 +453,13 @@ void shutdown() { @Test void testSync() { - RedisAdvancedClusterCommands sync = async.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.set(key, value); assertThat(sync.get(key)).isEqualTo(value); RedisClusterCommands node2Connection = sync.getConnection(ClusterTestSettings.host, ClusterTestSettings.port2); assertThat(node2Connection.get(key)).isEqualTo(value); - - assertThat(sync.getStatefulConnection()).isSameAs(async.getStatefulConnection()); } @Test @@ -544,7 +542,7 @@ void pipelining(@New StatefulRedisClusterConnection connectionUn TestFutures.awaitOrTimeout(async.get(key(0))); int iterations = 1000; - async.setAutoFlushCommands(false); + connectionUnderTest.setAutoFlushCommands(false); List> futures = new ArrayList<>(); for (int i = 0; i < iterations; i++) { futures.add(async.set(key(i), value(i))); @@ -554,7 +552,7 @@ void pipelining(@New StatefulRedisClusterConnection connectionUn assertThat(this.sync.get(key(i))).as("Key " + key(i) + " must be null").isNull(); } - async.flushCommands(); + connectionUnderTest.flushCommands(); boolean result = TestFutures.awaitOrTimeout(futures); assertThat(result).isTrue(); @@ -567,7 +565,7 @@ void pipelining(@New StatefulRedisClusterConnection connectionUn @Test void clusterScan() { - RedisAdvancedClusterCommands sync = async.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); Set allKeys = new HashSet<>(); @@ -589,7 +587,7 @@ void clusterScan() { @Test void clusterScanWithArgs() { - RedisAdvancedClusterCommands sync = async.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); Set allKeys = new HashSet<>(); @@ -612,7 +610,7 @@ void clusterScanWithArgs() { @Test void clusterScanStreaming() { - RedisAdvancedClusterCommands sync = async.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); ListStreamingAdapter adapter = new ListStreamingAdapter<>(); @@ -634,7 +632,7 @@ void clusterScanStreaming() { @Test void clusterScanStreamingWithArgs() { - RedisAdvancedClusterCommands sync = async.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); ListStreamingAdapter adapter = new ListStreamingAdapter<>(); diff --git a/src/test/java/io/lettuce/core/cluster/AdvancedClusterReactiveIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/AdvancedClusterReactiveIntegrationTests.java index 53b0101fe0..2fa26b3548 100644 --- a/src/test/java/io/lettuce/core/cluster/AdvancedClusterReactiveIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/AdvancedClusterReactiveIntegrationTests.java @@ -74,6 +74,8 @@ class AdvancedClusterReactiveIntegrationTests extends TestSupport { private static final String KEY_ON_NODE_2 = "b"; private final RedisClusterClient clusterClient; + + private final StatefulRedisClusterConnection clusterConnection; private final RedisAdvancedClusterReactiveCommands commands; private final RedisAdvancedClusterCommands syncCommands; @@ -81,6 +83,7 @@ class AdvancedClusterReactiveIntegrationTests extends TestSupport { AdvancedClusterReactiveIntegrationTests(RedisClusterClient clusterClient, StatefulRedisClusterConnection connection) { this.clusterClient = clusterClient; + this.clusterConnection = connection; this.commands = connection.reactive(); this.syncCommands = connection.sync(); } @@ -193,7 +196,7 @@ void clientSetname() { StepVerifier.create(commands.clientSetname(name)).expectNext("OK").verifyComplete(); for (RedisClusterNode redisClusterNode : clusterClient.getPartitions()) { - RedisClusterCommands nodeConnection = commands.getStatefulConnection().sync() + RedisClusterCommands nodeConnection = clusterConnection.sync() .getConnection(redisClusterNode.getNodeId()); assertThat(nodeConnection.clientList()).contains(name); } @@ -302,7 +305,7 @@ void keys() { void keysDoesNotRunIntoRaceConditions() { List> futures = new ArrayList<>(); - RedisClusterAsyncCommands async = commands.getStatefulConnection().async(); + RedisClusterAsyncCommands async = clusterConnection.async(); TestFutures.awaitOrTimeout(async.flushall()); for (int i = 0; i < 1000; i++) { @@ -377,7 +380,7 @@ void readFromReplicas() { connection.readOnly().subscribe(); commands.set(key, value).subscribe(); - NodeSelectionAsyncIntegrationTests.waitForReplication(commands.getStatefulConnection().async(), ClusterTestSettings.key, + NodeSelectionAsyncIntegrationTests.waitForReplication(clusterConnection.async(), ClusterTestSettings.key, ClusterTestSettings.port4); AtomicBoolean error = new AtomicBoolean(); @@ -393,7 +396,7 @@ void readFromReplicas() { @Test void clusterScan() { - RedisAdvancedClusterCommands sync = commands.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); Set allKeys = new HashSet<>(); @@ -416,7 +419,7 @@ void clusterScan() { @Test void clusterScanWithArgs() { - RedisAdvancedClusterCommands sync = commands.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); Set allKeys = new HashSet<>(); @@ -440,7 +443,7 @@ void clusterScanWithArgs() { @Test void clusterScanStreaming() { - RedisAdvancedClusterCommands sync = commands.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); ListStreamingAdapter adapter = new ListStreamingAdapter<>(); @@ -462,7 +465,7 @@ void clusterScanStreaming() { @Test void clusterScanStreamingWithArgs() { - RedisAdvancedClusterCommands sync = commands.getStatefulConnection().sync(); + RedisAdvancedClusterCommands sync = clusterConnection.sync(); sync.mset(KeysAndValues.MAP); ListStreamingAdapter adapter = new ListStreamingAdapter<>(); diff --git a/src/test/java/io/lettuce/core/cluster/ClusterSetup.java b/src/test/java/io/lettuce/core/cluster/ClusterSetup.java index aff06a090e..a2e62da86d 100644 --- a/src/test/java/io/lettuce/core/cluster/ClusterSetup.java +++ b/src/test/java/io/lettuce/core/cluster/ClusterSetup.java @@ -47,7 +47,8 @@ public static void setup2Masters(ClusterTestHelper clusterHelper) { clusterHelper.meet(ClusterTestSettings.host, ClusterTestSettings.port5); clusterHelper.meet(ClusterTestSettings.host, ClusterTestSettings.port6); - RedisAdvancedClusterAsyncCommands connection = clusterHelper.getClusterClient().connect().async(); + StatefulRedisClusterConnection connection = clusterHelper.getClusterClient().connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); Wait.untilTrue(() -> { clusterHelper.getClusterClient().reloadPartitions(); @@ -59,7 +60,7 @@ public static void setup2Masters(ClusterTestHelper clusterHelper) { for (RedisClusterNode partition : partitions) { if (!partition.getSlots().isEmpty()) { - RedisClusterAsyncCommands nodeConnection = connection.getConnection(partition.getNodeId()); + RedisClusterAsyncCommands nodeConnection = async.getConnection(partition.getNodeId()); for (Integer slot : partition.getSlots()) { nodeConnection.clusterDelSlots(slot); @@ -67,11 +68,11 @@ public static void setup2Masters(ClusterTestHelper clusterHelper) { } } - RedisClusterAsyncCommands node1 = connection.getConnection(ClusterTestSettings.host, + RedisClusterAsyncCommands node1 = async.getConnection(ClusterTestSettings.host, ClusterTestSettings.port5); node1.clusterAddSlots(ClusterTestSettings.createSlots(0, 12000)); - RedisClusterAsyncCommands node2 = connection.getConnection(ClusterTestSettings.host, + RedisClusterAsyncCommands node2 = async.getConnection(ClusterTestSettings.host, ClusterTestSettings.port6); node2.clusterAddSlots(ClusterTestSettings.createSlots(12000, 16384)); @@ -84,7 +85,7 @@ public static void setup2Masters(ClusterTestHelper clusterHelper) { .filter(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.UPSTREAM)).count(); }).waitOrTimeout(); - connection.getStatefulConnection().close(); + connection.close(); } /** @@ -98,21 +99,22 @@ public static void setupMasterWithReplica(ClusterTestHelper clusterHelper) { clusterHelper.meet(ClusterTestSettings.host, ClusterTestSettings.port5); clusterHelper.meet(ClusterTestSettings.host, ClusterTestSettings.port6); - RedisAdvancedClusterAsyncCommands connection = clusterHelper.getClusterClient().connect().async(); - StatefulRedisClusterConnection statefulConnection = connection.getStatefulConnection(); + StatefulRedisClusterConnection connection = clusterHelper.getClusterClient().connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); Wait.untilEquals(2, () -> { clusterHelper.getClusterClient().reloadPartitions(); return clusterHelper.getClusterClient().getPartitions().size(); }).waitOrTimeout(); - RedisClusterCommands node1 = statefulConnection + RedisClusterCommands node1 = connection .getConnection(TestSettings.hostAddr(), ClusterTestSettings.port5).sync(); node1.clusterAddSlots(ClusterTestSettings.createSlots(0, 16384)); Wait.untilTrue(clusterHelper::isStable).waitOrTimeout(); - TestFutures.awaitOrTimeout(connection.getConnection(ClusterTestSettings.host, ClusterTestSettings.port6) + TestFutures.awaitOrTimeout( + async.getConnection(ClusterTestSettings.host, ClusterTestSettings.port6) .clusterReplicate( node1.clusterMyId())); @@ -131,7 +133,7 @@ public static void setupMasterWithReplica(ClusterTestHelper clusterHelper) { .count(); }).waitOrTimeout(); - connection.getStatefulConnection().close(); + connection.close(); } private static Stream partitionStream(ClusterTestHelper clusterHelper) { diff --git a/src/test/java/io/lettuce/core/cluster/ClusterTestHelper.java b/src/test/java/io/lettuce/core/cluster/ClusterTestHelper.java index 02dcbe98cd..3cc99c39e0 100644 --- a/src/test/java/io/lettuce/core/cluster/ClusterTestHelper.java +++ b/src/test/java/io/lettuce/core/cluster/ClusterTestHelper.java @@ -26,6 +26,7 @@ import java.util.concurrent.TimeoutException; import java.util.function.Function; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.api.async.RedisServerAsyncCommands; import io.lettuce.core.api.sync.RedisCommands; @@ -41,14 +42,19 @@ class ClusterTestHelper { private final RedisClusterClient clusterClient; - private final Map> connectionCache = new HashMap<>(); + + private final Map> connectionCache = new HashMap<>(); + + private final Map> commandsCache = new HashMap<>(); public ClusterTestHelper(RedisClusterClient clusterClient, int... ports) { this.clusterClient = clusterClient; for (int port : ports) { - RedisAsyncCommands connection = clusterClient.connectToNode(new InetSocketAddress("localhost", port)).async(); + StatefulRedisConnection connection = clusterClient + .connectToNode(new InetSocketAddress("localhost", port)); connectionCache.put(port, connection); + commandsCache.put(port, connection.async()); } } @@ -58,9 +64,9 @@ public ClusterTestHelper(RedisClusterClient clusterClient, int... ports) { */ public boolean isStable() { - for (RedisAsyncCommands commands : connectionCache.values()) { + for (StatefulRedisConnection connection : connectionCache.values()) { try { - RedisCommands sync = commands.getStatefulConnection().sync(); + RedisCommands sync = connection.sync(); String info = sync.clusterInfo(); if (info != null && info.contains("cluster_state:ok")) { @@ -125,7 +131,7 @@ private void onAllConnections(Function, Futu boolean ignoreExecutionException) { List> futures = new ArrayList<>(); - for (RedisClusterAsyncCommands connection : connectionCache.values()) { + for (RedisClusterAsyncCommands connection : commandsCache.values()) { futures.add(function.apply(connection)); } diff --git a/src/test/java/io/lettuce/core/cluster/NodeSelectionAsyncIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/NodeSelectionAsyncIntegrationTests.java index 03970995a4..b620676469 100644 --- a/src/test/java/io/lettuce/core/cluster/NodeSelectionAsyncIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/NodeSelectionAsyncIntegrationTests.java @@ -61,6 +61,8 @@ class NodeSelectionAsyncIntegrationTests extends TestSupport { private final RedisClusterClient clusterClient; + + private final StatefulRedisClusterConnection connection; private final RedisAdvancedClusterAsyncCommands commands; @Inject @@ -69,6 +71,7 @@ class NodeSelectionAsyncIntegrationTests extends TestSupport { this.clusterClient = clusterClient; this.commands = connection.async(); + this.connection = connection; connection.sync().flushall(); } @@ -163,7 +166,7 @@ void testNodeSelection() { @Test void testDynamicNodeSelection() { - Partitions partitions = commands.getStatefulConnection().getPartitions(); + Partitions partitions = connection.getPartitions(); partitions.forEach(redisClusterNode -> redisClusterNode.setFlags(Collections .singleton(RedisClusterNode.NodeFlag.UPSTREAM))); @@ -235,7 +238,7 @@ void testStaticNodeSelection() { assertThat(selection.asMap()).hasSize(1); - commands.getStatefulConnection().getPartitions().getPartition(2) + connection.getPartitions().getPartition(2) .setFlags(Collections.singleton(RedisClusterNode.NodeFlag.MYSELF)); assertThat(selection.asMap()).hasSize(1); diff --git a/src/test/java/io/lettuce/core/cluster/NodeSelectionSyncIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/NodeSelectionSyncIntegrationTests.java index 4e837f4e74..6e1736e8d9 100644 --- a/src/test/java/io/lettuce/core/cluster/NodeSelectionSyncIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/NodeSelectionSyncIntegrationTests.java @@ -15,12 +15,17 @@ */ package io.lettuce.core.cluster; -import static io.lettuce.core.ScriptOutputType.STATUS; -import static org.assertj.core.api.Assertions.assertThat; +import static io.lettuce.core.ScriptOutputType.*; +import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Fail.fail; import java.time.Duration; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Vector; import javax.inject.Inject; @@ -48,6 +53,8 @@ class NodeSelectionSyncIntegrationTests extends TestSupport { private final RedisClusterClient clusterClient; + + private final StatefulRedisClusterConnection connection; private final RedisAdvancedClusterCommands commands; @Inject @@ -56,6 +63,7 @@ class NodeSelectionSyncIntegrationTests extends TestSupport { this.clusterClient = clusterClient; this.commands = connection.sync(); + this.connection = connection; connection.sync().flushall(); } @@ -112,7 +120,7 @@ void testNodeSelection() { @Test void testDynamicNodeSelection() { - Partitions partitions = commands.getStatefulConnection().getPartitions(); + Partitions partitions = connection.getPartitions(); partitions.forEach( redisClusterNode -> redisClusterNode.setFlags(Collections.singleton(RedisClusterNode.NodeFlag.UPSTREAM))); @@ -153,7 +161,7 @@ void testStaticNodeSelection() { assertThat(selection.asMap()).hasSize(1); - commands.getStatefulConnection().getPartitions().getPartition(2) + connection.getPartitions().getPartition(2) .setFlags(Collections.singleton(RedisClusterNode.NodeFlag.MYSELF)); assertThat(selection.asMap()).hasSize(1); @@ -164,10 +172,11 @@ void testStaticNodeSelection() { @Test void testAsynchronicityOfMultiNodeExecution() { - RedisAdvancedClusterCommands connection2 = clusterClient.connect().sync(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterCommands sync = connection.sync(); - connection2.setTimeout(Duration.ofSeconds(1)); - NodeSelection masters = connection2.masters(); + connection.setTimeout(Duration.ofSeconds(1)); + NodeSelection masters = sync.masters(); masters.commands().configSet("lua-time-limit", "10"); Executions eval = null; diff --git a/src/test/java/io/lettuce/core/cluster/RedisClusterClientIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/RedisClusterClientIntegrationTests.java index e2001b83a9..c383995b66 100644 --- a/src/test/java/io/lettuce/core/cluster/RedisClusterClientIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/RedisClusterClientIntegrationTests.java @@ -128,24 +128,10 @@ void after() { connection.close(); redis1.close(); - redissync1.getStatefulConnection().close(); - redissync2.getStatefulConnection().close(); - redissync3.getStatefulConnection().close(); - redissync4.getStatefulConnection().close(); - } - - @Test - void statefulConnectionFromSync() { - RedisAdvancedClusterCommands sync = clusterClient.connect().sync(); - assertThat(sync.getStatefulConnection().sync()).isSameAs(sync); - connection.close(); - } - - @Test - void statefulConnectionFromAsync() { - RedisAdvancedClusterAsyncCommands async = clusterClient.connect().async(); - assertThat(async.getStatefulConnection().async()).isSameAs(async); - connection.close(); + redis1.close(); + redis2.close(); + redis3.close(); + redis4.close(); } @Test @@ -234,13 +220,14 @@ void testClusteredOperations() { assertThatThrownBy(() -> TestFutures.awaitOrTimeout(resultMoved)).hasMessageContaining("MOVED 15495"); clusterClient.reloadPartitions(); - RedisAdvancedClusterCommands connection = clusterClient.connect().sync(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterCommands sync = connection.sync(); - assertThat(connection.set(ClusterTestSettings.KEY_A, value)).isEqualTo("OK"); - assertThat(connection.set(ClusterTestSettings.KEY_B, "myValue2")).isEqualTo("OK"); - assertThat(connection.set(ClusterTestSettings.KEY_D, "myValue2")).isEqualTo("OK"); + assertThat(sync.set(ClusterTestSettings.KEY_A, value)).isEqualTo("OK"); + assertThat(sync.set(ClusterTestSettings.KEY_B, "myValue2")).isEqualTo("OK"); + assertThat(sync.set(ClusterTestSettings.KEY_D, "myValue2")).isEqualTo("OK"); - connection.getStatefulConnection().close(); + connection.close(); } @Test @@ -266,14 +253,15 @@ void testClusterCommandRedirection() { try { clusterClient.addListener(listener); - RedisAdvancedClusterCommands connection = clusterClient.connect().sync(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterCommands sync = connection.sync(); // Command on node within the default connection - assertThat(connection.set(ClusterTestSettings.KEY_B, value)).isEqualTo("OK"); + assertThat(sync.set(ClusterTestSettings.KEY_B, value)).isEqualTo("OK"); // gets routing to node 3 - assertThat(connection.set(ClusterTestSettings.KEY_A, value)).isEqualTo("OK"); - connection.getStatefulConnection().close(); + assertThat(sync.set(ClusterTestSettings.KEY_A, value)).isEqualTo("OK"); + connection.close(); } finally { client.removeListener(listener); } @@ -291,7 +279,8 @@ void testClusterRedirection() { try { clusterClient.addListener(listener); - RedisAdvancedClusterAsyncCommands connection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); Partitions partitions = clusterClient.getPartitions(); for (RedisClusterNode partition : partitions) { @@ -303,7 +292,7 @@ void testClusterRedirection() { partitions.updateCache(); // appropriate cluster node - RedisFuture setB = connection.set(ClusterTestSettings.KEY_B, value); + RedisFuture setB = async.set(ClusterTestSettings.KEY_B, value); assertThat(setB.toCompletableFuture()).isInstanceOf(AsyncCommand.class); @@ -312,7 +301,7 @@ void testClusterRedirection() { assertThat(TestFutures.getOrTimeout(setB)).isEqualTo("OK"); // gets redirection to node 3 - RedisFuture setA = connection.set(ClusterTestSettings.KEY_A, value); + RedisFuture setA = async.set(ClusterTestSettings.KEY_A, value); assertThat((CompletionStage) setA).isInstanceOf(AsyncCommand.class); @@ -320,7 +309,7 @@ void testClusterRedirection() { assertThat(setA.getError()).isNull(); assertThat(TestFutures.getOrTimeout(setA)).isEqualTo("OK"); - connection.getStatefulConnection().close(); + connection.close(); } finally { clusterClient.removeListener(listener); } @@ -334,7 +323,8 @@ void testClusterRedirection() { void testClusterRedirectionLimit() throws Exception { clusterClient.setOptions(ClusterClientOptions.builder().maxRedirects(0).build()); - RedisAdvancedClusterAsyncCommands connection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); Partitions partitions = clusterClient.getPartitions(); for (RedisClusterNode partition : partitions) { @@ -349,27 +339,28 @@ void testClusterRedirectionLimit() throws Exception { partitions.updateCache(); // gets redirection to node 3 - RedisFuture setA = connection.set(ClusterTestSettings.KEY_A, value); + RedisFuture setA = async.set(ClusterTestSettings.KEY_A, value); assertThat(setA instanceof AsyncCommand).isTrue(); setA.await(10, TimeUnit.SECONDS); assertThat(setA.getError()).isEqualTo("MOVED 15495 127.0.0.1:7380"); - connection.getStatefulConnection().close(); + connection.close(); } @Test void closeConnection() { - RedisAdvancedClusterCommands connection = clusterClient.connect().sync(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterCommands sync = connection.sync(); - List time = connection.time(); + List time = sync.time(); assertThat(time).hasSize(2); - connection.getStatefulConnection().close(); + connection.close(); - assertThatThrownBy(connection::time).isInstanceOf(RedisException.class); + assertThatThrownBy(sync::time).isInstanceOf(RedisException.class); } @Test @@ -647,18 +638,19 @@ void testReadFromNull() { @Test void testPfmerge() { - RedisAdvancedClusterCommands connection = clusterClient.connect().sync(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterCommands sync = connection.sync(); assertThat(SlotHash.getSlot("key2660")).isEqualTo(SlotHash.getSlot("key7112")).isEqualTo(SlotHash.getSlot("key8885")); - connection.pfadd("key2660", "rand", "mat"); - connection.pfadd("key7112", "mat", "perrin"); + sync.pfadd("key2660", "rand", "mat"); + sync.pfadd("key7112", "mat", "perrin"); - connection.pfmerge("key8885", "key2660", "key7112"); + sync.pfmerge("key8885", "key2660", "key7112"); - assertThat(connection.pfcount("key8885")).isEqualTo(3); + assertThat(sync.pfcount("key8885")).isEqualTo(3); - connection.getStatefulConnection().close(); + connection.close(); } static class TestCommandListener implements CommandListener { diff --git a/src/test/java/io/lettuce/core/cluster/RedisClusterSetupTest.java b/src/test/java/io/lettuce/core/cluster/RedisClusterSetupTest.java index c6acffa316..d463d7253d 100644 --- a/src/test/java/io/lettuce/core/cluster/RedisClusterSetupTest.java +++ b/src/test/java/io/lettuce/core/cluster/RedisClusterSetupTest.java @@ -43,7 +43,8 @@ import io.lettuce.core.RedisFuture; import io.lettuce.core.RedisURI; import io.lettuce.core.TestSupport; -import io.lettuce.core.api.async.RedisAsyncCommands; +import io.lettuce.core.api.StatefulConnection; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.api.async.RedisAdvancedClusterAsyncCommands; @@ -82,7 +83,10 @@ public class RedisClusterSetupTest extends TestSupport { private static RedisClient client = DefaultRedisClient.get(); private static ClusterTestHelper clusterHelper; + private StatefulRedisConnection connection1; private RedisCommands redis1; + + private StatefulRedisConnection connection2; private RedisCommands redis2; @BeforeAll @@ -100,15 +104,17 @@ public static void shutdownClient() { @BeforeEach public void openConnection() { clusterHelper.flushdb(); - redis1 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, ClusterTestSettings.port5).build()).sync(); - redis2 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, ClusterTestSettings.port6).build()).sync(); + connection1 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, port5).build()); + redis1 = connection1.sync(); + connection2 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, ClusterTestSettings.port6).build()); + redis2 = connection2.sync(); clusterHelper.clusterReset(); } @AfterEach public void closeConnection() { - redis1.getStatefulConnection().close(); - redis2.getStatefulConnection().close(); + connection1.close(); + connection2.close(); } @Test @@ -215,13 +221,14 @@ public void clusterTopologyRefresh() { clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(PERIODIC_REFRESH_ENABLED).build()); clusterClient.reloadPartitions(); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); assertThat(clusterClient.getPartitions()).hasSize(1); ClusterSetup.setup2Masters(clusterHelper); assertThat(clusterClient.getPartitions()).hasSize(2); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -267,7 +274,7 @@ public void changeTopologyWhileOperations() throws Exception { assertThat(sync.get("t")).isEqualTo("value"); assertThat(sync.get("p")).isEqualTo("value"); - async.getStatefulConnection().close(); + connection.close(); } @Test @@ -289,7 +296,7 @@ public void slotMigrationShouldUseAsking() { assertThat(sync.get("b")).isNull(); - async.getStatefulConnection().close(); + connection.close(); } @Test @@ -297,45 +304,44 @@ public void disconnectedConnectionRejectTest() throws Exception { clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(PERIODIC_REFRESH_ENABLED) .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); clusterClient.setOptions(ClusterClientOptions.builder() .disconnectedBehavior(ClientOptions.DisconnectedBehavior.REJECT_COMMANDS).build()); ClusterSetup.setup2Masters(clusterHelper); - assertRoutedExecution(clusterConnection); + assertRoutedExecution(async); RedisClusterNode partition1 = getOwnPartition(redis1); - RedisClusterAsyncCommands node1Connection = clusterConnection.getConnection(partition1.getUri() - .getHost(), partition1.getUri().getPort()); shiftAllSlotsToNode1(); - suspendConnection(node1Connection); + suspendConnection(connection.getConnection(partition1.getUri().getHost(), partition1.getUri().getPort())); - RedisFuture set = clusterConnection.set("t", "value"); // 15891 + RedisFuture set = async.set("t", "value"); // 15891 set.await(5, TimeUnit.SECONDS); assertThatThrownBy(() -> TestFutures.awaitOrTimeout(set)).hasRootCauseInstanceOf(RedisException.class); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test public void atLeastOnceForgetNodeFailover() throws Exception { clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(PERIODIC_REFRESH_ENABLED).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); clusterClient.setOptions(ClusterClientOptions.create()); ClusterSetup.setup2Masters(clusterHelper); - assertRoutedExecution(clusterConnection); + assertRoutedExecution(async); RedisClusterNode partition1 = getOwnPartition(redis1); RedisClusterNode partition2 = getOwnPartition(redis2); - RedisClusterAsyncCommands node1Connection = clusterConnection.getConnection(partition1.getUri() - .getHost(), partition1.getUri().getPort()); - RedisClusterAsyncCommands node2Connection = clusterConnection.getConnection(partition2.getUri() + StatefulRedisConnection node2Connection = connection + .getConnection(partition2.getUri() .getHost(), partition2.getUri().getPort()); shiftAllSlotsToNode1(); @@ -344,10 +350,10 @@ public void atLeastOnceForgetNodeFailover() throws Exception { List> futures = new ArrayList<>(); - futures.add(clusterConnection.set("t", "value")); // 15891 - futures.add(clusterConnection.set("p", "value")); // 16023 + futures.add(async.set("t", "value")); // 15891 + futures.add(async.set("p", "value")); // 16023 - clusterConnection.set("A", "value").get(1, TimeUnit.SECONDS); // 6373 + async.set("A", "value").get(1, TimeUnit.SECONDS); // 6373 for (RedisFuture future : futures) { assertThat(future.isDone()).isFalse(); @@ -364,9 +370,9 @@ public void atLeastOnceForgetNodeFailover() throws Exception { Wait.untilTrue(() -> TestFutures.areAllDone(futures)).waitOrTimeout(); - assertRoutedExecution(clusterConnection); + assertRoutedExecution(async); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -439,15 +445,17 @@ public void expireStaleDefaultPubSubConnection() { public void expireStaleNodeIdConnections() { clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(PERIODIC_REFRESH_ENABLED).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); ClusterSetup.setup2Masters(clusterHelper); - PooledClusterConnectionProvider clusterConnectionProvider = getPooledClusterConnectionProvider(clusterConnection); + PooledClusterConnectionProvider clusterConnectionProvider = getPooledClusterConnectionProvider( + connection); assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(0); - assertRoutedExecution(clusterConnection); + assertRoutedExecution(async); assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(2); @@ -468,7 +476,7 @@ public void expireStaleNodeIdConnections() { Wait.untilEquals(1, () -> clusterClient.getPartitions().size()).waitOrTimeout(); Wait.untilEquals(1, () -> clusterConnectionProvider.getConnectionCount()).waitOrTimeout(); - clusterConnection.getStatefulConnection().close(); + connection.close(); } private void assertRoutedExecution(RedisClusterAsyncCommands clusterConnection) { @@ -482,15 +490,17 @@ public void doNotExpireStaleNodeIdConnections() throws Exception { clusterClient.setOptions(ClusterClientOptions.builder() .topologyRefreshOptions(ClusterTopologyRefreshOptions.builder().closeStaleConnections(false).build()).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); ClusterSetup.setup2Masters(clusterHelper); - PooledClusterConnectionProvider clusterConnectionProvider = getPooledClusterConnectionProvider(clusterConnection); + PooledClusterConnectionProvider clusterConnectionProvider = getPooledClusterConnectionProvider( + connection); assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(0); - assertRoutedExecution(clusterConnection); + assertRoutedExecution(async); assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(2); @@ -512,7 +522,7 @@ public void doNotExpireStaleNodeIdConnections() throws Exception { assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(2); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @@ -520,20 +530,22 @@ public void doNotExpireStaleNodeIdConnections() throws Exception { public void expireStaleHostAndPortConnections() throws Exception { clusterClient.setOptions(ClusterClientOptions.builder().build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); ClusterSetup.setup2Masters(clusterHelper); - final PooledClusterConnectionProvider clusterConnectionProvider = getPooledClusterConnectionProvider(clusterConnection); + final PooledClusterConnectionProvider clusterConnectionProvider = getPooledClusterConnectionProvider( + connection); assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(0); - assertRoutedExecution(clusterConnection); + assertRoutedExecution(async); assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(2); for (RedisClusterNode redisClusterNode : clusterClient.getPartitions()) { - clusterConnection.getConnection(redisClusterNode.getUri().getHost(), redisClusterNode.getUri().getPort()); - clusterConnection.getConnection(redisClusterNode.getNodeId()); + async.getConnection(redisClusterNode.getUri().getHost(), redisClusterNode.getUri().getPort()); + async.getConnection(redisClusterNode.getNodeId()); } assertThat(clusterConnectionProvider.getConnectionCount()).isEqualTo(4); @@ -557,43 +569,45 @@ public void expireStaleHostAndPortConnections() throws Exception { Wait.untilEquals(1, () -> clusterClient.getPartitions().size()).waitOrTimeout(); Wait.untilEquals(2L, () -> clusterConnectionProvider.getConnectionCount()).waitOrTimeout(); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test public void readFromReplicaTest() { ClusterSetup.setup2Masters(clusterHelper); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); - clusterConnection.getStatefulConnection().setReadFrom(ReadFrom.REPLICA); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); + connection.setReadFrom(ReadFrom.REPLICA); - TestFutures.awaitOrTimeout(clusterConnection.set(key, value)); + TestFutures.awaitOrTimeout(async.set(key, value)); try { - clusterConnection.get(key); + async.get(key); } catch (RedisException e) { assertThat(e).hasMessageContaining("Cannot determine a partition to read for slot"); } - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test public void readFromNearestTest() { ClusterSetup.setup2Masters(clusterHelper); - RedisAdvancedClusterCommands clusterConnection = clusterClient.connect().sync(); - clusterConnection.getStatefulConnection().setReadFrom(ReadFrom.NEAREST); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterCommands sync = connection.sync(); + connection.setReadFrom(ReadFrom.NEAREST); - clusterConnection.set(key, value); + sync.set(key, value); - assertThat(clusterConnection.get(key)).isEqualTo(value); + assertThat(sync.get(key)).isEqualTo(value); - clusterConnection.getStatefulConnection().close(); + connection.close(); } private PooledClusterConnectionProvider getPooledClusterConnectionProvider( - RedisAdvancedClusterAsyncCommands clusterAsyncConnection) { + StatefulConnection clusterAsyncConnection) { RedisChannelHandler channelHandler = getChannelHandler(clusterAsyncConnection); ClusterDistributionChannelWriter writer = (ClusterDistributionChannelWriter) channelHandler.getChannelWriter(); @@ -601,8 +615,8 @@ private PooledClusterConnectionProvider getPooledClusterConnecti } private RedisChannelHandler getChannelHandler( - RedisAdvancedClusterAsyncCommands clusterAsyncConnection) { - return (RedisChannelHandler) clusterAsyncConnection.getStatefulConnection(); + StatefulConnection connection) { + return (RedisChannelHandler) connection; } private void assertExecuted(RedisFuture set) { @@ -611,13 +625,13 @@ private void assertExecuted(RedisFuture set) { assertThat(TestFutures.getOrTimeout(set)).isEqualTo("OK"); } - private void suspendConnection(RedisClusterAsyncCommands asyncCommands) { + private void suspendConnection(StatefulRedisConnection connection) { - ConnectionTestUtil.getConnectionWatchdog(((RedisAsyncCommands) asyncCommands).getStatefulConnection()) + ConnectionTestUtil.getConnectionWatchdog(connection) .setReconnectSuspended(true); - asyncCommands.quit(); + connection.async().quit(); - Wait.untilTrue(() -> !asyncCommands.isOpen()).waitOrTimeout(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); } private void shiftAllSlotsToNode1() { diff --git a/src/test/java/io/lettuce/core/cluster/RedisClusterStressScenariosTest.java b/src/test/java/io/lettuce/core/cluster/RedisClusterStressScenariosTest.java index 782f99db6f..4fcdc20633 100644 --- a/src/test/java/io/lettuce/core/cluster/RedisClusterStressScenariosTest.java +++ b/src/test/java/io/lettuce/core/cluster/RedisClusterStressScenariosTest.java @@ -15,20 +15,32 @@ */ package io.lettuce.core.cluster; -import static io.lettuce.core.cluster.ClusterTestUtil.getOwnPartition; -import static org.assertj.core.api.Assertions.assertThat; +import static io.lettuce.core.cluster.ClusterTestUtil.*; +import static org.assertj.core.api.Assertions.*; import java.util.Collections; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import io.lettuce.category.SlowTests; -import io.lettuce.core.*; +import io.lettuce.core.RedisChannelHandler; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisException; +import io.lettuce.core.RedisURI; +import io.lettuce.core.StatefulRedisConnectionImpl; +import io.lettuce.core.TestSupport; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.api.sync.RedisCommands; +import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.models.partitions.RedisClusterNode; import io.lettuce.test.Wait; import io.lettuce.test.resource.FastShutdown; @@ -89,9 +101,7 @@ public void before() { @AfterEach public void after() { redis5.close(); - - redissync5.getStatefulConnection().close(); - redissync6.getStatefulConnection().close(); + redis6.close(); } @Test @@ -124,12 +134,13 @@ public void testClusterFailover() { @Test public void testClusterConnectionStability() { - RedisAdvancedClusterAsyncCommandsImpl connection = (RedisAdvancedClusterAsyncCommandsImpl) clusterClient - .connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommandsImpl async = (RedisAdvancedClusterAsyncCommandsImpl) connection + .async(); - RedisChannelHandler statefulConnection = (RedisChannelHandler) connection.getStatefulConnection(); + RedisChannelHandler statefulConnection = (RedisChannelHandler) async.getStatefulConnection(); - connection.set("a", "b"); + async.set("a", "b"); ClusterDistributionChannelWriter writer = (ClusterDistributionChannelWriter) statefulConnection.getChannelWriter(); StatefulRedisConnectionImpl statefulSlotConnection = (StatefulRedisConnectionImpl) writer @@ -138,9 +149,9 @@ public void testClusterConnectionStability() { final RedisAsyncCommands slotConnection = statefulSlotConnection.async(); slotConnection.set("a", "b"); - slotConnection.getStatefulConnection().close(); + statefulSlotConnection.close(); - Wait.untilTrue(() -> !slotConnection.isOpen()).waitOrTimeout(); + Wait.untilTrue(() -> !statefulSlotConnection.isOpen()).waitOrTimeout(); assertThat(statefulSlotConnection.isClosed()).isTrue(); assertThat(statefulSlotConnection.isOpen()).isFalse(); @@ -150,12 +161,12 @@ public void testClusterConnectionStability() { assertThat(statefulConnection.isClosed()).isFalse(); try { - connection.set("a", "b"); + async.set("a", "b"); } catch (RedisException e) { assertThat(e).hasMessageContaining("Connection is closed"); } - connection.getStatefulConnection().close(); + async.getStatefulConnection().close(); } diff --git a/src/test/java/io/lettuce/core/cluster/commands/ListClusterCommandIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/commands/ListClusterCommandIntegrationTests.java index 90b8f421a4..557a6c49a7 100644 --- a/src/test/java/io/lettuce/core/cluster/commands/ListClusterCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/commands/ListClusterCommandIntegrationTests.java @@ -36,11 +36,10 @@ class ListClusterCommandIntegrationTests extends ListCommandIntegrationTests { @Inject ListClusterCommandIntegrationTests(StatefulRedisClusterConnection connection) { - super(ClusterTestUtil.redisCommandsOverCluster(connection)); + super(connection, ClusterTestUtil.redisCommandsOverCluster(connection)); this.redis = connection.sync(); } - // re-implementation because keys have to be on the same slot @Test void brpoplpush() { @@ -52,7 +51,6 @@ void brpoplpush() { assertThat(redis.lrange("br7EPz9bbj", 0, -1)).isEqualTo(list("2", "3", "4")); } - @Test void brpoplpushTimeout() { assertThat(redis.brpoplpush(1, "UKPDHs8Zlp", "br7EPz9bbj")).isNull(); @@ -103,4 +101,5 @@ void rpoplpush() { assertThat(redis.lrange("UKPDHs8Zlp", 0, -1)).isEqualTo(list("1")); assertThat(redis.lrange("br7EPz9bbj", 0, -1)).isEqualTo(list("2", "3", "4")); } + } diff --git a/src/test/java/io/lettuce/core/cluster/commands/reactive/ListClusterReactiveCommandIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/commands/reactive/ListClusterReactiveCommandIntegrationTests.java index 328074d26a..2af8813a56 100644 --- a/src/test/java/io/lettuce/core/cluster/commands/reactive/ListClusterReactiveCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/commands/reactive/ListClusterReactiveCommandIntegrationTests.java @@ -36,7 +36,7 @@ class ListClusterReactiveCommandIntegrationTests extends ListCommandIntegrationT @Inject ListClusterReactiveCommandIntegrationTests(StatefulRedisClusterConnection connection) { - super(ReactiveSyncInvocationHandler.sync(connection)); + super(connection, ReactiveSyncInvocationHandler.sync(connection)); this.redis = ReactiveSyncInvocationHandler.sync(connection); } diff --git a/src/test/java/io/lettuce/core/cluster/pubsub/RedisClusterPubSubConnectionIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/pubsub/RedisClusterPubSubConnectionIntegrationTests.java index 563c90ea24..5e59a8fcce 100644 --- a/src/test/java/io/lettuce/core/cluster/pubsub/RedisClusterPubSubConnectionIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/pubsub/RedisClusterPubSubConnectionIntegrationTests.java @@ -15,14 +15,10 @@ */ package io.lettuce.core.cluster.pubsub; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; -import java.time.Duration; import java.util.List; -import java.util.Map; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.LinkedBlockingQueue; import javax.inject.Inject; @@ -34,7 +30,6 @@ import io.lettuce.core.RedisURI; import io.lettuce.core.TestSupport; -import io.lettuce.core.api.push.PushMessage; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.cluster.RedisClusterClient; import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; @@ -49,8 +44,6 @@ import io.lettuce.core.support.PubSubTestListener; import io.lettuce.test.LettuceExtension; import io.lettuce.test.TestFutures; -import io.lettuce.test.Wait; -import io.lettuce.test.condition.EnabledOnCommand; /** * @author Mark Paluch @@ -224,6 +217,7 @@ void testNodeHostAndPortMessagePropagationSubscription() throws Exception { RedisURI uri = partition.getUri(); StatefulRedisPubSubConnection node = pubSubConnection.getConnection(uri.getHost(), uri.getPort()); node.sync().subscribe("channel"); + Thread.sleep(100); pubSubConnection2.sync().publish("channel", "message"); diff --git a/src/test/java/io/lettuce/core/cluster/topology/TopologyRefreshIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/topology/TopologyRefreshIntegrationTests.java index 4059de6ad6..933d3073b5 100644 --- a/src/test/java/io/lettuce/core/cluster/topology/TopologyRefreshIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/topology/TopologyRefreshIntegrationTests.java @@ -34,6 +34,7 @@ import io.lettuce.core.RedisClient; import io.lettuce.core.RedisURI; import io.lettuce.core.TestSupport; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.BaseRedisAsyncCommands; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.cluster.ClusterClientOptions; @@ -43,7 +44,6 @@ import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.api.async.RedisAdvancedClusterAsyncCommands; import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands; -import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands; import io.lettuce.core.cluster.models.partitions.Partitions; import io.lettuce.core.cluster.models.partitions.RedisClusterNode; import io.lettuce.test.Delay; @@ -68,8 +68,12 @@ class TopologyRefreshIntegrationTests extends TestSupport { private RedisClusterClient clusterClient; + private StatefulRedisConnection connection1; + private RedisCommands redis1; + private StatefulRedisConnection connection2; + private RedisCommands redis2; @Inject @@ -81,14 +85,16 @@ class TopologyRefreshIntegrationTests extends TestSupport { void openConnection() { clusterClient = RedisClusterClient.create(client.getResources(), RedisURI.Builder.redis(host, ClusterTestSettings.port1).build()); - redis1 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, ClusterTestSettings.port1).build()).sync(); - redis2 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, ClusterTestSettings.port2).build()).sync(); + connection1 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, ClusterTestSettings.port1).build()); + redis1 = connection1.sync(); + connection2 = client.connect(RedisURI.Builder.redis(ClusterTestSettings.host, ClusterTestSettings.port2).build()); + redis2 = connection2.sync(); } @AfterEach void closeConnection() { - redis1.getStatefulConnection().close(); - redis2.getStatefulConnection().close(); + connection1.close(); + connection2.close(); FastShutdown.shutdown(clusterClient); } @@ -100,7 +106,8 @@ void changeTopologyWhileOperations() { .refreshPeriod(1, TimeUnit.SECONDS)// .build(); clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); clusterClient.getPartitions().clear(); @@ -108,7 +115,7 @@ void changeTopologyWhileOperations() { return !clusterClient.getPartitions().isEmpty(); }).waitOrTimeout(); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -116,7 +123,8 @@ void dynamicSourcesProvidesClientCountForAllNodes() { ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.create(); clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); for (RedisClusterNode redisClusterNode : clusterClient.getPartitions()) { assertThat(redisClusterNode).isInstanceOf(RedisClusterNodeSnapshot.class); @@ -125,7 +133,7 @@ void dynamicSourcesProvidesClientCountForAllNodes() { assertThat(snapshot.getConnectedClients()).isNotNull().isGreaterThanOrEqualTo(0); } - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -134,7 +142,8 @@ void staticSourcesProvidesClientCountForSeedNodes() { ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder() .dynamicRefreshSources(false).build(); clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); Partitions partitions = clusterClient.getPartitions(); RedisClusterNodeSnapshot node1 = (RedisClusterNodeSnapshot) partitions.getPartitionBySlot(0); @@ -143,7 +152,7 @@ void staticSourcesProvidesClientCountForSeedNodes() { RedisClusterNodeSnapshot node2 = (RedisClusterNodeSnapshot) partitions.getPartitionBySlot(15000); assertThat(node2.getConnectedClients()).isNull(); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -185,23 +194,24 @@ void adaptiveTopologyUpdateIsRateLimited() { .enableAllAdaptiveRefreshTriggers()// .build(); clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); clusterClient.getPartitions().clear(); - clusterConnection.quit(); + async.quit(); Wait.untilTrue(() -> { return !clusterClient.getPartitions().isEmpty(); }).waitOrTimeout(); clusterClient.getPartitions().clear(); - clusterConnection.quit(); + async.quit(); Delay.delay(Duration.ofMillis(200)); assertThat(clusterClient.getPartitions()).isEmpty(); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -213,9 +223,10 @@ void adaptiveTopologyUpdatetUsesTimeout() { .enableAllAdaptiveRefreshTriggers()// .build(); clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); - clusterConnection.quit(); + async.quit(); Delay.delay(Duration.ofMillis(700)); Wait.untilTrue(() -> { @@ -223,13 +234,13 @@ void adaptiveTopologyUpdatetUsesTimeout() { }).waitOrTimeout(); clusterClient.getPartitions().clear(); - clusterConnection.quit(); + async.quit(); Wait.untilTrue(() -> { return !clusterClient.getPartitions().isEmpty(); }).waitOrTimeout(); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -239,15 +250,16 @@ void adaptiveTriggerDoesNotFireOnSingleReconnect() { .enableAllAdaptiveRefreshTriggers()// .build(); clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); clusterClient.getPartitions().clear(); - clusterConnection.quit(); + async.quit(); Delay.delay(Duration.ofMillis(500)); assertThat(clusterClient.getPartitions()).isEmpty(); - clusterConnection.getStatefulConnection().close(); + connection.close(); } @Test @@ -281,7 +293,7 @@ void adaptiveTriggerOnMoveRedirection() { assertThat(clusterClient.getPartitions().getPartitionByNodeId(node1.getNodeId()).getSlots()).hasSize(12000); assertThat(clusterClient.getPartitions().getPartitionByNodeId(node2.getNodeId()).getSlots()).hasSize(4384); - clusterConnection.getStatefulConnection().close(); + connection.close(); } private void runReconnectTest( @@ -292,10 +304,11 @@ private void runReconnectTest( .enableAllAdaptiveRefreshTriggers()// .build(); clusterClient.setOptions(ClusterClientOptions.builder().topologyRefreshOptions(topologyRefreshOptions).build()); - RedisAdvancedClusterAsyncCommands clusterConnection = clusterClient.connect().async(); + StatefulRedisClusterConnection connection = clusterClient.connect(); + RedisAdvancedClusterAsyncCommands async = connection.async(); RedisClusterNode node = clusterClient.getPartitions().getPartition(0); - BaseRedisAsyncCommands closeable = function.apply(clusterConnection, node); + BaseRedisAsyncCommands closeable = function.apply(async, node); clusterClient.getPartitions().clear(); closeable.quit(); @@ -304,10 +317,7 @@ private void runReconnectTest( return !clusterClient.getPartitions().isEmpty(); }).waitOrTimeout(); - if (closeable instanceof RedisAdvancedClusterCommands) { - ((RedisAdvancedClusterCommands) closeable).getStatefulConnection().close(); - } - clusterConnection.getStatefulConnection().close(); + connection.close(); } } diff --git a/src/test/java/io/lettuce/core/commands/BitCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/BitCommandIntegrationTests.java index 09e47fc898..199c6265b2 100644 --- a/src/test/java/io/lettuce/core/commands/BitCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/BitCommandIntegrationTests.java @@ -15,13 +15,10 @@ */ package io.lettuce.core.commands; +import static io.lettuce.core.BitFieldArgs.*; import static io.lettuce.core.BitFieldArgs.offset; -import static io.lettuce.core.BitFieldArgs.signed; -import static io.lettuce.core.BitFieldArgs.typeWidthBasedOffset; -import static io.lettuce.core.BitFieldArgs.unsigned; -import static io.lettuce.core.BitFieldArgs.OverflowType.WRAP; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static io.lettuce.core.BitFieldArgs.OverflowType.*; +import static org.assertj.core.api.Assertions.*; import java.util.List; @@ -36,6 +33,7 @@ import io.lettuce.core.BitFieldArgs; import io.lettuce.core.RedisClient; import io.lettuce.core.TestSupport; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.test.LettuceExtension; import io.lettuce.test.condition.EnabledOnCommand; @@ -51,6 +49,7 @@ public class BitCommandIntegrationTests extends TestSupport { private final RedisClient client; private final RedisCommands redis; + private StatefulRedisConnection bitConnection; protected RedisCommands bitstring; @Inject @@ -62,12 +61,13 @@ protected BitCommandIntegrationTests(RedisClient client, RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject CustomCommandIntegrationTests(StatefulRedisConnection connection) { this.redis = connection.sync(); + this.connection = connection; } @BeforeEach @@ -191,9 +193,7 @@ void standaloneFireAndForget() { } private StatefulRedisConnection getStandaloneConnection() { - - assumeTrue(redis.getStatefulConnection() instanceof StatefulRedisConnection); - return redis.getStatefulConnection(); + return connection; } public enum MyCommands implements ProtocolKeyword { diff --git a/src/test/java/io/lettuce/core/commands/ListCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/ListCommandIntegrationTests.java index c392ad573b..c98ed1625b 100644 --- a/src/test/java/io/lettuce/core/commands/ListCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/ListCommandIntegrationTests.java @@ -31,6 +31,7 @@ import io.lettuce.core.LMoveArgs; import io.lettuce.core.LPosArgs; import io.lettuce.core.TestSupport; +import io.lettuce.core.api.StatefulConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.test.LettuceExtension; import io.lettuce.test.ListStreamingAdapter; @@ -51,8 +52,11 @@ public class ListCommandIntegrationTests extends TestSupport { private final RedisCommands redis; + private final StatefulConnection connection; + @Inject - protected ListCommandIntegrationTests(RedisCommands redis) { + protected ListCommandIntegrationTests(StatefulConnection connection, RedisCommands redis) { + this.connection = connection; this.redis = redis; } @@ -76,7 +80,7 @@ void blpopDoubleTimeout() { @Test void blpopTimeout() { - redis.setTimeout(Duration.ofSeconds(10)); + connection.setTimeout(Duration.ofSeconds(10)); assertThat(redis.blpop(1, key)).isNull(); } diff --git a/src/test/java/io/lettuce/core/commands/RunOnlyOnceServerCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/RunOnlyOnceServerCommandIntegrationTests.java index 71ff1ec37e..c961b573bf 100644 --- a/src/test/java/io/lettuce/core/commands/RunOnlyOnceServerCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/RunOnlyOnceServerCommandIntegrationTests.java @@ -15,10 +15,9 @@ */ package io.lettuce.core.commands; -import static io.lettuce.test.settings.TestSettings.host; -import static io.lettuce.test.settings.TestSettings.port; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static io.lettuce.test.settings.TestSettings.*; +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; import java.util.Arrays; @@ -67,15 +66,16 @@ void debugSegfault() { assumeTrue(CanConnect.to(host(), port(1))); - final RedisAsyncCommands commands = client.connect(RedisURI.Builder.redis(host(), port(1)).build()) + StatefulRedisConnection connection = client.connect(RedisURI.Builder.redis(host(), port(1)).build()); + RedisAsyncCommands async = connection .async(); try { - commands.debugSegfault(); + async.debugSegfault(); - Wait.untilTrue(() -> !commands.getStatefulConnection().isOpen()).waitOrTimeout(); - assertThat(commands.getStatefulConnection().isOpen()).isFalse(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); + assertThat(connection.isOpen()).isFalse(); } finally { - commands.getStatefulConnection().close(); + connection.close(); } } @@ -122,18 +122,19 @@ void shutdown() { assumeTrue(CanConnect.to(host(), port(2))); - final RedisAsyncCommands commands = client.connect(RedisURI.Builder.redis(host(), port(2)).build()) + StatefulRedisConnection connection = client.connect(RedisURI.Builder.redis(host(), port(2)).build()); + RedisAsyncCommands async = connection .async(); try { - commands.shutdown(true); - commands.shutdown(false); - Wait.untilTrue(() -> !commands.getStatefulConnection().isOpen()).waitOrTimeout(); + async.shutdown(true); + async.shutdown(false); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); - assertThat(commands.getStatefulConnection().isOpen()).isFalse(); + assertThat(connection.isOpen()).isFalse(); } finally { - commands.getStatefulConnection().close(); + connection.close(); } } } diff --git a/src/test/java/io/lettuce/core/commands/ServerCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/ServerCommandIntegrationTests.java index 1c4dc1d7c9..b9cbbb1d63 100644 --- a/src/test/java/io/lettuce/core/commands/ServerCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/ServerCommandIntegrationTests.java @@ -75,10 +75,17 @@ public class ServerCommandIntegrationTests extends TestSupport { private final RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject - protected ServerCommandIntegrationTests(RedisClient client, RedisCommands redis) { + protected ServerCommandIntegrationTests(RedisClient client, StatefulRedisConnection connection) { this.client = client; - this.redis = redis; + this.connection = connection; + this.redis = getCommands(connection); + } + + protected RedisCommands getCommands(StatefulRedisConnection connection) { + return connection.sync(); } @BeforeEach @@ -162,8 +169,9 @@ void clientKill() { @Test void clientKillExtended() { - RedisCommands connection2 = client.connect().sync(); - connection2.clientSetname("killme"); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); + sync.clientSetname("killme"); Pattern p = Pattern.compile("^.*[^l]addr=([^ ]+).*name=killme.*$", Pattern.MULTILINE | Pattern.DOTALL); String clients = redis.clientList(); @@ -178,7 +186,7 @@ void clientKillExtended() { assertThat(redis.clientKill(KillArgs.Builder.typeNormal().id(4234))).isEqualTo(0); assertThat(redis.clientKill(KillArgs.Builder.typePubsub().id(4234))).isEqualTo(0); - connection2.getStatefulConnection().close(); + connection.close(); } @Test @@ -206,11 +214,11 @@ void clientList() { void clientTracking() { redis.clientTracking(TrackingArgs.Builder.enabled(false)); - redis.clientTracking(TrackingArgs.Builder.enabled()); + List pushMessages = new CopyOnWriteArrayList<>(); - redis.getStatefulConnection().addListener(pushMessages::add); + connection.addListener(pushMessages::add); redis.set(key, value); assertThat(pushMessages.isEmpty()); @@ -232,11 +240,11 @@ void clientTracking() { void clientTrackingPrefixes() { redis.clientTracking(TrackingArgs.Builder.enabled(false)); - redis.clientTracking(TrackingArgs.Builder.enabled().bcast().prefixes("foo", "bar")); + List pushMessages = new CopyOnWriteArrayList<>(); - redis.getStatefulConnection().addListener(pushMessages::add); + connection.addListener(pushMessages::add); redis.get(key); redis.set(key, value); diff --git a/src/test/java/io/lettuce/core/commands/TransactionCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/TransactionCommandIntegrationTests.java index afd4b69aa7..d951886562 100644 --- a/src/test/java/io/lettuce/core/commands/TransactionCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/TransactionCommandIntegrationTests.java @@ -15,8 +15,7 @@ */ package io.lettuce.core.commands; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.*; import javax.inject.Inject; @@ -25,7 +24,12 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; -import io.lettuce.core.*; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisCommandExecutionException; +import io.lettuce.core.RedisException; +import io.lettuce.core.TestSupport; +import io.lettuce.core.TransactionResult; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.test.LettuceExtension; @@ -71,9 +75,10 @@ void exec() { void watch() { assertThat(redis.watch(key)).isEqualTo("OK"); - RedisCommands redis2 = client.connect().sync(); - redis2.set(key, value + "X"); - redis2.getStatefulConnection().close(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); + sync.set(key, value + "X"); + connection.close(); redis.multi(); redis.append(key, "foo"); diff --git a/src/test/java/io/lettuce/core/commands/reactive/CustomReactiveCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/reactive/CustomReactiveCommandIntegrationTests.java index c16d28a1d1..e0f20879b8 100644 --- a/src/test/java/io/lettuce/core/commands/reactive/CustomReactiveCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/reactive/CustomReactiveCommandIntegrationTests.java @@ -41,9 +41,12 @@ class CustomReactiveCommandIntegrationTests extends TestSupport { private final RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject CustomReactiveCommandIntegrationTests(StatefulRedisConnection connection) { this.redis = connection.sync(); + this.connection = connection; this.redis.flushdb(); } @@ -51,7 +54,7 @@ class CustomReactiveCommandIntegrationTests extends TestSupport { void dispatchGetAndSet() { redis.set(key, value); - RedisReactiveCommands reactive = redis.getStatefulConnection().reactive(); + RedisReactiveCommands reactive = connection.reactive(); Flux flux = reactive.dispatch(CommandType.GET, new ValueOutput<>(StringCodec.UTF8), new CommandArgs<>( StringCodec.UTF8).addKey(key)); @@ -63,7 +66,7 @@ void dispatchGetAndSet() { void dispatchList() { redis.rpush(key, "a", "b", "c"); - RedisReactiveCommands reactive = redis.getStatefulConnection().reactive(); + RedisReactiveCommands reactive = connection.reactive(); Flux flux = reactive.dispatch(CommandType.LRANGE, new ValueListOutput<>(StringCodec.UTF8), new CommandArgs<>( StringCodec.UTF8).addKey(key).add(0).add(-1)); diff --git a/src/test/java/io/lettuce/core/commands/reactive/ListReactiveCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/reactive/ListReactiveCommandIntegrationTests.java index 83f1103dc8..cd50076ef6 100644 --- a/src/test/java/io/lettuce/core/commands/reactive/ListReactiveCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/reactive/ListReactiveCommandIntegrationTests.java @@ -28,6 +28,6 @@ class ListReactiveCommandIntegrationTests extends ListCommandIntegrationTests { @Inject ListReactiveCommandIntegrationTests(StatefulRedisConnection connection) { - super(ReactiveSyncInvocationHandler.sync(connection)); + super(connection, ReactiveSyncInvocationHandler.sync(connection)); } } diff --git a/src/test/java/io/lettuce/core/commands/reactive/ServerReactiveCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/reactive/ServerReactiveCommandIntegrationTests.java index e6316cd53f..9cd03ba97a 100644 --- a/src/test/java/io/lettuce/core/commands/reactive/ServerReactiveCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/reactive/ServerReactiveCommandIntegrationTests.java @@ -15,7 +15,7 @@ */ package io.lettuce.core.commands.reactive; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import java.util.List; @@ -26,6 +26,7 @@ import io.lettuce.core.RedisClient; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.reactive.RedisReactiveCommands; +import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.commands.ServerCommandIntegrationTests; import io.lettuce.core.models.command.CommandDetail; import io.lettuce.core.models.command.CommandDetailParser; @@ -41,10 +42,17 @@ class ServerReactiveCommandIntegrationTests extends ServerCommandIntegrationTest private RedisReactiveCommands reactive; + private final StatefulRedisConnection connection; + @Inject ServerReactiveCommandIntegrationTests(RedisClient client, StatefulRedisConnection connection) { - super(client, ReactiveSyncInvocationHandler.sync(connection)); + super(client, connection); this.reactive = connection.reactive(); + this.connection = connection; + } + + protected RedisCommands getCommands(StatefulRedisConnection connection) { + return ReactiveSyncInvocationHandler.sync(connection); } /** @@ -53,31 +61,31 @@ class ServerReactiveCommandIntegrationTests extends ServerCommandIntegrationTest @Test void shutdown() { reactive.shutdown(true); - assertThat(reactive.getStatefulConnection().isOpen()).isTrue(); + assertThat(connection.isOpen()).isTrue(); } @Test void debugOom() { reactive.debugOom(); - assertThat(reactive.getStatefulConnection().isOpen()).isTrue(); + assertThat(connection.isOpen()).isTrue(); } @Test void debugSegfault() { reactive.debugSegfault(); - assertThat(reactive.getStatefulConnection().isOpen()).isTrue(); + assertThat(connection.isOpen()).isTrue(); } @Test void debugRestart() { reactive.debugRestart(1L); - assertThat(reactive.getStatefulConnection().isOpen()).isTrue(); + assertThat(connection.isOpen()).isTrue(); } @Test void migrate() { reactive.migrate("host", 1234, "key", 1, 10); - assertThat(reactive.getStatefulConnection().isOpen()).isTrue(); + assertThat(connection.isOpen()).isTrue(); } @Test diff --git a/src/test/java/io/lettuce/core/commands/transactional/ListTxCommandIntegrationTests.java b/src/test/java/io/lettuce/core/commands/transactional/ListTxCommandIntegrationTests.java index f47692f069..6f01ac28e7 100644 --- a/src/test/java/io/lettuce/core/commands/transactional/ListTxCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/commands/transactional/ListTxCommandIntegrationTests.java @@ -27,6 +27,6 @@ class ListTxCommandIntegrationTests extends ListCommandIntegrationTests { @Inject ListTxCommandIntegrationTests(StatefulRedisConnection connection) { - super(TxSyncInvocationHandler.sync(connection)); + super(connection, TxSyncInvocationHandler.sync(connection)); } } diff --git a/src/test/java/io/lettuce/core/dynamic/ReactiveTypeAdaptionIntegrationTests.java b/src/test/java/io/lettuce/core/dynamic/ReactiveTypeAdaptionIntegrationTests.java index 8c6ed92882..c9534cf6f2 100644 --- a/src/test/java/io/lettuce/core/dynamic/ReactiveTypeAdaptionIntegrationTests.java +++ b/src/test/java/io/lettuce/core/dynamic/ReactiveTypeAdaptionIntegrationTests.java @@ -15,7 +15,7 @@ */ package io.lettuce.core.dynamic; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import javax.inject.Inject; @@ -48,7 +48,7 @@ class ReactiveTypeAdaptionIntegrationTests extends TestSupport { this.redis = connection.sync(); - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); this.rxjava1 = factory.getCommands(RxJava1Types.class); this.rxjava2 = factory.getCommands(RxJava2Types.class); this.rxjava3 = factory.getCommands(RxJava3Types.class); diff --git a/src/test/java/io/lettuce/core/dynamic/RedisCommandsAsyncIntegrationTests.java b/src/test/java/io/lettuce/core/dynamic/RedisCommandsAsyncIntegrationTests.java index ea6f35a72c..ed0271061e 100644 --- a/src/test/java/io/lettuce/core/dynamic/RedisCommandsAsyncIntegrationTests.java +++ b/src/test/java/io/lettuce/core/dynamic/RedisCommandsAsyncIntegrationTests.java @@ -15,7 +15,7 @@ */ package io.lettuce.core.dynamic; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; @@ -38,15 +38,18 @@ class RedisCommandsAsyncIntegrationTests extends TestSupport { private final RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject RedisCommandsAsyncIntegrationTests(StatefulRedisConnection connection) { this.redis = connection.sync(); + this.connection = connection; } @Test void async() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); diff --git a/src/test/java/io/lettuce/core/dynamic/RedisCommandsBatchingIntegrationTests.java b/src/test/java/io/lettuce/core/dynamic/RedisCommandsBatchingIntegrationTests.java index ea9e60c299..92efba9bed 100644 --- a/src/test/java/io/lettuce/core/dynamic/RedisCommandsBatchingIntegrationTests.java +++ b/src/test/java/io/lettuce/core/dynamic/RedisCommandsBatchingIntegrationTests.java @@ -15,7 +15,7 @@ */ package io.lettuce.core.dynamic; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Fail.fail; import java.util.concurrent.TimeUnit; @@ -48,9 +48,12 @@ class RedisCommandsBatchingIntegrationTests extends TestSupport { private final RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject RedisCommandsBatchingIntegrationTests(StatefulRedisConnection connection) { this.redis = connection.sync(); + this.connection = connection; } @BeforeEach @@ -61,7 +64,7 @@ void setUp() { @Test void selectiveBatching() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); SelectiveBatching api = factory.getCommands(SelectiveBatching.class); @@ -83,7 +86,7 @@ void selectiveBatching() { @Test void selectiveBatchingShouldHandleErrors() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); SelectiveBatching api = factory.getCommands(SelectiveBatching.class); @@ -102,7 +105,7 @@ void selectiveBatchingShouldHandleErrors() { @Test void shouldExecuteBatchingSynchronously() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); Batching api = factory.getCommands(Batching.class); @@ -120,7 +123,7 @@ void shouldExecuteBatchingSynchronously() { @Test void shouldHandleSynchronousBatchErrors() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); Batching api = factory.getCommands(Batching.class); @@ -148,7 +151,7 @@ void shouldHandleSynchronousBatchErrors() { @Test void shouldExecuteBatchingAynchronously() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); Batching api = factory.getCommands(Batching.class); @@ -166,7 +169,7 @@ void shouldExecuteBatchingAynchronously() { @Test void shouldHandleAsynchronousBatchErrors() throws Exception { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); Batching api = factory.getCommands(Batching.class); diff --git a/src/test/java/io/lettuce/core/dynamic/RedisCommandsIntegrationTests.java b/src/test/java/io/lettuce/core/dynamic/RedisCommandsIntegrationTests.java index a06cdcf30a..0bc0380c05 100644 --- a/src/test/java/io/lettuce/core/dynamic/RedisCommandsIntegrationTests.java +++ b/src/test/java/io/lettuce/core/dynamic/RedisCommandsIntegrationTests.java @@ -15,10 +15,8 @@ */ package io.lettuce.core.dynamic; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.when; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; import javax.inject.Inject; @@ -51,16 +49,19 @@ class RedisCommandsIntegrationTests extends TestSupport { private final RedisClient client; private final RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject RedisCommandsIntegrationTests(RedisClient client, StatefulRedisConnection connection) { this.client = client; this.redis = connection.sync(); + this.connection = connection; } @Test void verifierShouldCatchMisspelledDeclarations() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); assertThat(factory).hasFieldOrPropertyWithValue("verifyCommandMethods", true); try { @@ -74,7 +75,7 @@ void verifierShouldCatchMisspelledDeclarations() { @Test void disabledVerifierDoesNotReportTypo() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); factory.setVerifyCommandMethods(false); assertThat(factory.getCommands(WithTypo.class)).isNotNull(); @@ -97,7 +98,7 @@ void doesNotFailIfCommandRetrievalFails() { @Test void verifierShouldCatchTooFewParametersDeclarations() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); try { factory.getCommands(TooFewParameters.class); diff --git a/src/test/java/io/lettuce/core/dynamic/RedisCommandsReactiveIntegrationTests.java b/src/test/java/io/lettuce/core/dynamic/RedisCommandsReactiveIntegrationTests.java index e5b96228df..6c9e2dbbaf 100644 --- a/src/test/java/io/lettuce/core/dynamic/RedisCommandsReactiveIntegrationTests.java +++ b/src/test/java/io/lettuce/core/dynamic/RedisCommandsReactiveIntegrationTests.java @@ -38,9 +38,12 @@ class RedisCommandsReactiveIntegrationTests extends TestSupport { private final RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject RedisCommandsReactiveIntegrationTests(StatefulRedisConnection connection) { this.redis = connection.sync(); + this.connection = connection; } @BeforeEach @@ -51,7 +54,7 @@ void setUp() { @Test void reactive() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); @@ -61,7 +64,7 @@ void reactive() { @Test void shouldHandlePresentValue() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); @@ -72,7 +75,7 @@ void shouldHandlePresentValue() { @Test void shouldHandleAbsentValue() { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); @@ -82,7 +85,7 @@ void shouldHandleAbsentValue() { @Test void shouldHandlePresentValueRxJava() throws InterruptedException { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); @@ -93,7 +96,7 @@ void shouldHandlePresentValueRxJava() throws InterruptedException { @Test void shouldHandleAbsentValueRxJava() throws InterruptedException { - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); diff --git a/src/test/java/io/lettuce/core/dynamic/RedisCommandsSyncIntegrationTests.java b/src/test/java/io/lettuce/core/dynamic/RedisCommandsSyncIntegrationTests.java index 912afaa6e0..623d14b3d0 100644 --- a/src/test/java/io/lettuce/core/dynamic/RedisCommandsSyncIntegrationTests.java +++ b/src/test/java/io/lettuce/core/dynamic/RedisCommandsSyncIntegrationTests.java @@ -47,10 +47,13 @@ class RedisCommandsSyncIntegrationTests extends TestSupport { private final RedisClient client; private final RedisCommands redis; + private final StatefulRedisConnection connection; + @Inject RedisCommandsSyncIntegrationTests(RedisClient client, StatefulRedisConnection connection) { this.client = client; this.redis = connection.sync(); + this.connection = connection; } @Test @@ -88,7 +91,7 @@ void mgetAsValues() { redis.set(key, value); - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); @@ -103,7 +106,7 @@ void mgetByteArray() { redis.set(key, value); - RedisCommandFactory factory = new RedisCommandFactory(redis.getStatefulConnection()); + RedisCommandFactory factory = new RedisCommandFactory(connection); MultipleExecutionModels api = factory.getCommands(MultipleExecutionModels.class); diff --git a/src/test/java/io/lettuce/core/masterreplica/CustomCommandIntegrationTests.java b/src/test/java/io/lettuce/core/masterreplica/CustomCommandIntegrationTests.java index 2ea1054088..c904b6ab3e 100644 --- a/src/test/java/io/lettuce/core/masterreplica/CustomCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/masterreplica/CustomCommandIntegrationTests.java @@ -15,9 +15,7 @@ */ package io.lettuce.core.masterreplica; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.assertj.core.api.Assertions.*; import java.util.Arrays; @@ -28,12 +26,21 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import io.lettuce.core.*; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisCommandExecutionException; +import io.lettuce.core.RedisURI; +import io.lettuce.core.TestSupport; +import io.lettuce.core.TransactionResult; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.output.StatusOutput; -import io.lettuce.core.protocol.*; +import io.lettuce.core.protocol.AsyncCommand; +import io.lettuce.core.protocol.Command; +import io.lettuce.core.protocol.CommandArgs; +import io.lettuce.core.protocol.CommandType; +import io.lettuce.core.protocol.ProtocolKeyword; +import io.lettuce.core.protocol.RedisCommand; import io.lettuce.test.LettuceExtension; import io.lettuce.test.TestFutures; @@ -150,9 +157,7 @@ void masterReplicaFireAndForget() { } private StatefulRedisConnection getStandaloneConnection() { - - assumeTrue(redis.getStatefulConnection() instanceof StatefulRedisConnection); - return redis.getStatefulConnection(); + return connection; } public enum MyCommands implements ProtocolKeyword { diff --git a/src/test/java/io/lettuce/core/masterreplica/MasterReplicaTest.java b/src/test/java/io/lettuce/core/masterreplica/MasterReplicaTest.java index 209a9b8470..c3ca6a11fc 100644 --- a/src/test/java/io/lettuce/core/masterreplica/MasterReplicaTest.java +++ b/src/test/java/io/lettuce/core/masterreplica/MasterReplicaTest.java @@ -31,6 +31,7 @@ import io.lettuce.core.ReadFrom; import io.lettuce.core.RedisException; import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.models.role.RedisInstance; @@ -55,8 +56,13 @@ class MasterReplicaTest extends AbstractRedisClientTest { private RedisURI upstream; private RedisURI replica; - private RedisCommands connection1; - private RedisCommands connection2; + private StatefulRedisConnection connection1; + + private RedisCommands redis1; + + private StatefulRedisConnection connection2; + + private RedisCommands redis2; @BeforeEach void before() { @@ -64,11 +70,13 @@ void before() { RedisURI node1 = RedisURI.Builder.redis(host, TestSettings.port(3)).withDatabase(2).build(); RedisURI node2 = RedisURI.Builder.redis(host, TestSettings.port(4)).withDatabase(2).build(); - connection1 = client.connect(node1).sync(); - connection2 = client.connect(node2).sync(); + this.connection1 = client.connect(node1); + this.redis1 = connection1.sync(); + this.connection2 = client.connect(node2); + this.redis2 = connection2.sync(); - RedisInstance node1Instance = RoleParser.parse(this.connection1.role()); - RedisInstance node2Instance = RoleParser.parse(this.connection2.role()); + RedisInstance node1Instance = RoleParser.parse(this.redis1.role()); + RedisInstance node2Instance = RoleParser.parse(this.redis2.role()); if (node1Instance.getRole().isUpstream() && node2Instance.getRole().isReplica()) { upstream = node1; @@ -82,13 +90,13 @@ void before() { node1Instance, node2Instance)); } - WithPassword.enableAuthentication(this.connection1); - this.connection1.auth(passwd); - this.connection1.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis1); + this.redis1.auth(passwd); + this.redis1.configSet("masterauth", passwd.toString()); - WithPassword.enableAuthentication(this.connection2); - this.connection2.auth(passwd); - this.connection2.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis2); + this.redis2.auth(passwd); + this.redis2.configSet("masterauth", passwd.toString()); connection = MasterReplica.connect(client, StringCodec.UTF8, masterURI); connection.setReadFrom(ReadFrom.REPLICA); @@ -97,16 +105,16 @@ void before() { @AfterEach void after() { - if (connection1 != null) { - WithPassword.disableAuthentication(connection1); - connection1.configRewrite(); - connection1.getStatefulConnection().close(); + if (redis1 != null) { + WithPassword.disableAuthentication(redis1); + redis1.configRewrite(); + connection1.close(); } - if (connection2 != null) { - WithPassword.disableAuthentication(connection2); - connection2.configRewrite(); - connection2.getStatefulConnection().close(); + if (redis2 != null) { + WithPassword.disableAuthentication(redis2); + redis2.configRewrite(); + connection2.close(); } if (connection != null) { diff --git a/src/test/java/io/lettuce/core/masterreplica/StaticMasterReplicaTest.java b/src/test/java/io/lettuce/core/masterreplica/StaticMasterReplicaTest.java index 011d198ab1..06dc12fddd 100644 --- a/src/test/java/io/lettuce/core/masterreplica/StaticMasterReplicaTest.java +++ b/src/test/java/io/lettuce/core/masterreplica/StaticMasterReplicaTest.java @@ -31,6 +31,7 @@ import io.lettuce.core.ReadFrom; import io.lettuce.core.RedisException; import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.models.role.RedisInstance; @@ -50,8 +51,13 @@ class StaticMasterReplicaTest extends AbstractRedisClientTest { private RedisURI upstream; private RedisURI replica; - private RedisCommands connection1; - private RedisCommands connection2; + private StatefulRedisConnection connection1; + + private RedisCommands redis1; + + private StatefulRedisConnection connection2; + + private RedisCommands redis2; @BeforeEach void before() throws Exception { @@ -59,11 +65,13 @@ void before() throws Exception { RedisURI node1 = RedisURI.Builder.redis(host, TestSettings.port(3)).withClientName("my-client").withDatabase(2).build(); RedisURI node2 = RedisURI.Builder.redis(host, TestSettings.port(4)).withClientName("my-client").withDatabase(2).build(); - connection1 = client.connect(node1).sync(); - connection2 = client.connect(node2).sync(); + this.connection1 = client.connect(node1); + this.redis1 = connection1.sync(); + this.connection2 = client.connect(node2); + this.redis2 = connection2.sync(); - RedisInstance node1Instance = RoleParser.parse(this.connection1.role()); - RedisInstance node2Instance = RoleParser.parse(this.connection2.role()); + RedisInstance node1Instance = RoleParser.parse(this.redis1.role()); + RedisInstance node2Instance = RoleParser.parse(this.redis2.role()); if (node1Instance.getRole().isUpstream() && node2Instance.getRole().isReplica()) { upstream = node1; @@ -77,13 +85,13 @@ void before() throws Exception { node1Instance, node2Instance)); } - WithPassword.enableAuthentication(this.connection1); - this.connection1.auth(passwd); - this.connection1.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis1); + this.redis1.auth(passwd); + this.redis1.configSet("masterauth", passwd.toString()); - WithPassword.enableAuthentication(this.connection2); - this.connection2.auth(passwd); - this.connection2.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis2); + this.redis2.auth(passwd); + this.redis2.configSet("masterauth", passwd.toString()); node1.setPassword(passwd); node2.setPassword(passwd); @@ -95,18 +103,18 @@ void before() throws Exception { @AfterEach void after() throws Exception { - if (connection1 != null) { - WithPassword.disableAuthentication(connection1); - connection1.configSet("masterauth", ""); - connection1.configRewrite(); - connection1.getStatefulConnection().close(); + if (redis1 != null) { + WithPassword.disableAuthentication(redis1); + redis1.configSet("masterauth", ""); + redis1.configRewrite(); + connection1.close(); } - if (connection2 != null) { - WithPassword.disableAuthentication(connection2); - connection2.configSet("masterauth", ""); - connection2.configRewrite(); - connection2.getStatefulConnection().close(); + if (redis2 != null) { + WithPassword.disableAuthentication(redis2); + redis2.configSet("masterauth", ""); + redis2.configRewrite(); + connection2.close(); } if (connection != null) { diff --git a/src/test/java/io/lettuce/core/masterslave/MasterSlaveTest.java b/src/test/java/io/lettuce/core/masterslave/MasterSlaveTest.java index 00c19724a6..75b864bb57 100644 --- a/src/test/java/io/lettuce/core/masterslave/MasterSlaveTest.java +++ b/src/test/java/io/lettuce/core/masterslave/MasterSlaveTest.java @@ -31,6 +31,7 @@ import io.lettuce.core.ReadFrom; import io.lettuce.core.RedisException; import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.masterreplica.StatefulRedisMasterReplicaConnection; @@ -53,8 +54,13 @@ class MasterSlaveTest extends AbstractRedisClientTest { private RedisURI upstream; private RedisURI replica; - private RedisCommands connection1; - private RedisCommands connection2; + private StatefulRedisConnection connection1; + + private RedisCommands redis1; + + private StatefulRedisConnection connection2; + + private RedisCommands redis2; @BeforeEach void before() throws Exception { @@ -62,11 +68,13 @@ void before() throws Exception { RedisURI node1 = RedisURI.Builder.redis(host, TestSettings.port(3)).withDatabase(2).build(); RedisURI node2 = RedisURI.Builder.redis(host, TestSettings.port(4)).withDatabase(2).build(); - this.connection1 = client.connect(node1).sync(); - this.connection2 = client.connect(node2).sync(); + this.connection1 = client.connect(node1); + this.redis1 = connection1.sync(); + this.connection2 = client.connect(node2); + this.redis2 = connection2.sync(); - RedisInstance node1Instance = RoleParser.parse(this.connection1.role()); - RedisInstance node2Instance = RoleParser.parse(this.connection2.role()); + RedisInstance node1Instance = RoleParser.parse(this.redis1.role()); + RedisInstance node2Instance = RoleParser.parse(this.redis2.role()); if (node1Instance.getRole().isUpstream() && node2Instance.getRole().isReplica()) { upstream = node1; @@ -80,13 +88,13 @@ void before() throws Exception { node1Instance, node2Instance)); } - WithPassword.enableAuthentication(this.connection1); - this.connection1.auth(passwd); - this.connection1.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis1); + this.redis1.auth(passwd); + this.redis1.configSet("masterauth", passwd.toString()); - WithPassword.enableAuthentication(this.connection2); - this.connection2.auth(passwd); - this.connection2.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis2); + this.redis2.auth(passwd); + this.redis2.configSet("masterauth", passwd.toString()); connection = MasterSlave.connect(client, StringCodec.UTF8, upstreamURI); connection.setReadFrom(ReadFrom.REPLICA); @@ -95,16 +103,16 @@ void before() throws Exception { @AfterEach void after() { - if (connection1 != null) { - WithPassword.disableAuthentication(connection1); - connection1.configRewrite(); - connection1.getStatefulConnection().close(); + if (redis1 != null) { + WithPassword.disableAuthentication(redis1); + redis1.configRewrite(); + connection1.close(); } - if (connection2 != null) { - WithPassword.disableAuthentication(connection2); - connection2.configRewrite(); - connection2.getStatefulConnection().close(); + if (redis2 != null) { + WithPassword.disableAuthentication(redis2); + redis2.configRewrite(); + connection2.close(); } if (connection != null) { diff --git a/src/test/java/io/lettuce/core/masterslave/StaticMasterSlaveTest.java b/src/test/java/io/lettuce/core/masterslave/StaticMasterSlaveTest.java index 5b0dafe02f..9cbebee89c 100644 --- a/src/test/java/io/lettuce/core/masterslave/StaticMasterSlaveTest.java +++ b/src/test/java/io/lettuce/core/masterslave/StaticMasterSlaveTest.java @@ -30,6 +30,7 @@ import io.lettuce.core.ReadFrom; import io.lettuce.core.RedisException; import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.models.role.RedisInstance; @@ -47,8 +48,13 @@ class StaticMasterSlaveTest extends AbstractRedisClientTest { private RedisURI upstream; private RedisURI replica; - private RedisCommands connection1; - private RedisCommands connection2; + private StatefulRedisConnection connection1; + + private RedisCommands redis1; + + private StatefulRedisConnection connection2; + + private RedisCommands redis2; @BeforeEach void before() { @@ -56,11 +62,13 @@ void before() { RedisURI node1 = RedisURI.Builder.redis(host, TestSettings.port(3)).withClientName("my-client").withDatabase(2).build(); RedisURI node2 = RedisURI.Builder.redis(host, TestSettings.port(4)).withClientName("my-client").withDatabase(2).build(); - this.connection1 = client.connect(node1).sync(); - this.connection2 = client.connect(node2).sync(); + this.connection1 = client.connect(node1); + this.redis1 = connection1.sync(); + this.connection2 = client.connect(node2); + this.redis2 = connection2.sync(); - RedisInstance node1Instance = RoleParser.parse(this.connection1.role()); - RedisInstance node2Instance = RoleParser.parse(this.connection2.role()); + RedisInstance node1Instance = RoleParser.parse(this.redis1.role()); + RedisInstance node2Instance = RoleParser.parse(this.redis2.role()); if (node1Instance.getRole().isUpstream() && node2Instance.getRole().isReplica()) { upstream = node1; @@ -74,13 +82,13 @@ void before() { node1Instance, node2Instance)); } - WithPassword.enableAuthentication(this.connection1); - this.connection1.auth(passwd); - this.connection1.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis1); + this.redis1.auth(passwd); + this.redis1.configSet("masterauth", passwd.toString()); - WithPassword.enableAuthentication(this.connection2); - this.connection2.auth(passwd); - this.connection2.configSet("masterauth", passwd.toString()); + WithPassword.enableAuthentication(this.redis2); + this.redis2.auth(passwd); + this.redis2.configSet("masterauth", passwd.toString()); upstream.setPassword(passwd); replica.setPassword(passwd); @@ -92,18 +100,18 @@ void before() { @AfterEach void after() throws Exception { - if (connection1 != null) { - WithPassword.disableAuthentication(connection1); - connection1.configSet("masterauth", ""); - connection1.configRewrite(); - connection1.getStatefulConnection().close(); + if (redis1 != null) { + WithPassword.disableAuthentication(redis1); + redis1.configSet("masterauth", ""); + redis1.configRewrite(); + connection1.close(); } - if (connection2 != null) { - WithPassword.disableAuthentication(connection2); - connection2.configSet("masterauth", ""); - connection2.configRewrite(); - connection2.getStatefulConnection().close(); + if (redis2 != null) { + WithPassword.disableAuthentication(redis2); + redis2.configSet("masterauth", ""); + redis2.configRewrite(); + connection2.close(); } if (connection != null) { diff --git a/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java b/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java index 05837e14ff..dbd0328356 100644 --- a/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java +++ b/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java @@ -15,9 +15,7 @@ */ package io.lettuce.core.protocol; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.*; import java.lang.reflect.Field; import java.net.InetSocketAddress; @@ -25,7 +23,11 @@ import java.util.Comparator; import java.util.List; import java.util.Queue; -import java.util.concurrent.*; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @@ -34,18 +36,27 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.platform.commons.util.ReflectionUtils; -import io.lettuce.test.ReflectionTestUtils; - -import io.lettuce.core.*; +import io.lettuce.core.ClientOptions; +import io.lettuce.core.ConnectionEvents; +import io.lettuce.core.RedisAsyncCommandsImpl; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisConnectionException; +import io.lettuce.core.RedisException; +import io.lettuce.core.RedisFuture; +import io.lettuce.core.RedisURI; +import io.lettuce.core.TestSupport; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.event.Event; import io.lettuce.core.event.connection.ReconnectFailedEvent; import io.lettuce.core.resource.ClientResources; import io.lettuce.core.resource.NettyCustomizer; -import io.lettuce.test.*; +import io.lettuce.test.ConnectionTestUtil; +import io.lettuce.test.Delay; +import io.lettuce.test.LettuceExtension; +import io.lettuce.test.TestFutures; +import io.lettuce.test.Wait; import io.lettuce.test.resource.FastShutdown; import io.lettuce.test.server.RandomResponseServer; import io.lettuce.test.settings.TestSettings; @@ -112,9 +123,11 @@ void failOnReconnect() throws Exception { redisUri.setTimeout(Duration.ofSeconds(5)); try { - RedisAsyncCommands connection = client.connect(redisUri).async(); + + StatefulRedisConnection connection = client.connect(redisUri); + RedisAsyncCommands async = connection.async(); ConnectionWatchdog connectionWatchdog = ConnectionTestUtil - .getConnectionWatchdog(connection.getStatefulConnection()); + .getConnectionWatchdog(connection); assertThat(connectionWatchdog.isListenOnChannelInactive()).isTrue(); assertThat(connectionWatchdog.isReconnectSuspended()).isFalse(); @@ -123,15 +136,15 @@ void failOnReconnect() throws Exception { redisUri.setPort(TestSettings.nonexistentPort()); - connection.quit(); + async.quit(); Wait.untilTrue(() -> connectionWatchdog.isReconnectSuspended()).waitOrTimeout(); assertThat(connectionWatchdog.isListenOnChannelInactive()).isTrue(); - assertThatThrownBy(() -> TestFutures.awaitOrTimeout(connection.info())).hasRootCauseInstanceOf(RedisException.class) + assertThatThrownBy(() -> TestFutures.awaitOrTimeout(async.info())).hasRootCauseInstanceOf(RedisException.class) .hasMessageContaining("Invalid first byte"); - connection.getStatefulConnection().close(); + connection.close(); } finally { ts.shutdown(); } @@ -158,9 +171,10 @@ void failOnReconnectShouldSendEvents() throws Exception { try { final BlockingQueue events = new LinkedBlockingDeque<>(); - RedisAsyncCommands connection = client.connect(redisUri).async(); + StatefulRedisConnection connection = client.connect(redisUri); + RedisAsyncCommands async = connection.async(); ConnectionWatchdog connectionWatchdog = ConnectionTestUtil - .getConnectionWatchdog(connection.getStatefulConnection()); + .getConnectionWatchdog(connection); ReconnectionListener reconnectionListener = events::offer; @@ -170,16 +184,15 @@ void failOnReconnectShouldSendEvents() throws Exception { redisUri.setPort(TestSettings.nonexistentPort()); - connection.quit(); + async.quit(); Wait.untilTrue(() -> events.size() > 1).waitOrTimeout(); - connection.getStatefulConnection().close(); + connection.close(); ConnectionEvents.Reconnect event1 = events.take(); assertThat(event1.getAttempt()).isEqualTo(1); ConnectionEvents.Reconnect event2 = events.take(); assertThat(event2.getAttempt()).isEqualTo(2); - } finally { ts.shutdown(); } @@ -254,22 +267,22 @@ void emitEventOnReconnectFailure() throws Exception { client.setOptions(ClientOptions.builder().build()); try { - RedisAsyncCommandsImpl connection = (RedisAsyncCommandsImpl) client - .connect(redisUri).async(); + StatefulRedisConnection connection = client.connect(redisUri); + RedisAsyncCommandsImpl async = (RedisAsyncCommandsImpl) connection.async(); ConnectionWatchdog connectionWatchdog = ConnectionTestUtil - .getConnectionWatchdog(connection.getStatefulConnection()); + .getConnectionWatchdog(connection); redisUri.setPort(TestSettings.nonexistentPort()); client.getResources().eventBus().get().subscribe(queue::add); - connection.quit(); - Wait.untilTrue(() -> !connection.getStatefulConnection().isOpen()).waitOrTimeout(); + async.quit(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); connectionWatchdog.run(0); Delay.delay(Duration.ofMillis(500)); - connection.getStatefulConnection().close(); + connection.close(); assertThat(queue).isNotEmpty(); diff --git a/src/test/java/io/lettuce/core/pubsub/PubSubCommandTest.java b/src/test/java/io/lettuce/core/pubsub/PubSubCommandTest.java index e492af55aa..e8f12ad025 100644 --- a/src/test/java/io/lettuce/core/pubsub/PubSubCommandTest.java +++ b/src/test/java/io/lettuce/core/pubsub/PubSubCommandTest.java @@ -15,8 +15,7 @@ */ package io.lettuce.core.pubsub; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.*; import java.nio.ByteBuffer; import java.time.Duration; @@ -33,7 +32,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import io.lettuce.core.*; +import io.lettuce.core.AbstractRedisClientTest; +import io.lettuce.core.ClientOptions; +import io.lettuce.core.KillArgs; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisException; +import io.lettuce.core.RedisFuture; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.api.push.PushMessage; import io.lettuce.core.internal.LettuceFactories; @@ -57,6 +63,7 @@ */ class PubSubCommandTest extends AbstractRedisClientTest implements RedisPubSubListener { + private StatefulRedisPubSubConnection connection; private RedisPubSubAsyncCommands pubsub; private BlockingQueue channels; @@ -73,8 +80,9 @@ void openPubSubConnection() { try { client.setOptions(getOptions()); - pubsub = client.connectPubSub().async(); - pubsub.getStatefulConnection().addListener(this); + connection = client.connectPubSub(); + pubsub = connection.async(); + connection.addListener(this); } finally { channels = LettuceFactories.newBlockingQueue(); patterns = LettuceFactories.newBlockingQueue(); @@ -89,8 +97,8 @@ protected ClientOptions getOptions() { @AfterEach void closePubSubConnection() { - if (pubsub != null) { - pubsub.getStatefulConnection().close(); + if (connection != null) { + connection.close(); } } @@ -100,11 +108,12 @@ void auth() { client.setOptions( ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false).build()); - RedisPubSubAsyncCommands connection = client.connectPubSub().async(); - connection.getStatefulConnection().addListener(PubSubCommandTest.this); - connection.auth(passwd); + StatefulRedisPubSubConnection connection = client.connectPubSub(); + RedisPubSubAsyncCommands async = connection.async(); + connection.addListener(PubSubCommandTest.this); + async.auth(passwd); - connection.subscribe(channel); + async.subscribe(channel); assertThat(channels.take()).isEqualTo(channel); }); } @@ -116,11 +125,12 @@ void authWithUsername() { client.setOptions( ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false).build()); - RedisPubSubAsyncCommands connection = client.connectPubSub().async(); - connection.getStatefulConnection().addListener(PubSubCommandTest.this); - connection.auth(username, passwd); + StatefulRedisPubSubConnection connection = client.connectPubSub(); + RedisPubSubAsyncCommands async = connection.async(); + connection.addListener(PubSubCommandTest.this); + async.auth(username, passwd); - connection.subscribe(channel); + async.subscribe(channel); assertThat(channels.take()).isEqualTo(channel); }); } @@ -133,12 +143,13 @@ void authWithReconnect() { client.setOptions( ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false).build()); - RedisPubSubAsyncCommands connection = client.connectPubSub().async(); - connection.getStatefulConnection().addListener(PubSubCommandTest.this); - connection.auth(passwd); + StatefulRedisPubSubConnection connection = client.connectPubSub(); + RedisPubSubAsyncCommands async = connection.async(); + connection.addListener(PubSubCommandTest.this); + async.auth(passwd); - connection.clientSetname("authWithReconnect"); - connection.subscribe(channel).get(); + async.clientSetname("authWithReconnect"); + async.subscribe(channel).get(); assertThat(channels.take()).isEqualTo(channel); @@ -162,11 +173,12 @@ void authWithUsernameAndReconnect() { client.setOptions( ClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).pingBeforeActivateConnection(false).build()); - RedisPubSubAsyncCommands connection = client.connectPubSub().async(); - connection.getStatefulConnection().addListener(PubSubCommandTest.this); - connection.auth(username, passwd); - connection.clientSetname("authWithReconnect"); - connection.subscribe(channel).get(); + StatefulRedisPubSubConnection connection = client.connectPubSub(); + RedisPubSubAsyncCommands async = connection.async(); + connection.addListener(PubSubCommandTest.this); + async.auth(username, passwd); + async.clientSetname("authWithReconnect"); + async.subscribe(channel).get(); assertThat(channels.take()).isEqualTo(channel); @@ -212,7 +224,7 @@ void messageAsPushMessage() throws Exception { assertThat(counts.take()).isNotNull(); AtomicReference messageRef = new AtomicReference<>(); - pubsub.getStatefulConnection().addListener(messageRef::set); + connection.addListener(messageRef::set); redis.publish(channel, message); assertThat(messages.take()).isEqualTo(message); @@ -229,10 +241,11 @@ void messageAsPushMessage() throws Exception { void pipelinedMessage() throws Exception { pubsub.subscribe(channel); assertThat(channels.take()).isEqualTo(channel); - RedisAsyncCommands connection = client.connect().async(); + StatefulRedisConnection connection = client.connect(); + RedisAsyncCommands async = connection.async(); connection.setAutoFlushCommands(false); - connection.publish(channel, message); + async.publish(channel, message); Delay.delay(Duration.ofMillis(100)); assertThat(channels).isEmpty(); @@ -241,7 +254,7 @@ void pipelinedMessage() throws Exception { assertThat(channels.take()).isEqualTo(channel); assertThat(messages.take()).isEqualTo(message); - connection.getStatefulConnection().close(); + connection.close(); } @Test @@ -263,11 +276,11 @@ void pmessage() throws Exception { @Test void pipelinedSubscribe() throws Exception { - pubsub.setAutoFlushCommands(false); + connection.setAutoFlushCommands(false); pubsub.subscribe(channel); Delay.delay(Duration.ofMillis(100)); assertThat(channels).isEmpty(); - pubsub.flushCommands(); + connection.flushCommands(); assertThat(channels.take()).isEqualTo(channel); @@ -385,7 +398,8 @@ void pubsubCloseOnClientShutdown() { RedisClient redisClient = RedisClient.create(TestClientResources.get(), RedisURI.Builder.redis(host, port).build()); - RedisPubSubAsyncCommands connection = redisClient.connectPubSub().async(); + StatefulRedisPubSubConnection connection = redisClient.connectPubSub(); + RedisPubSubAsyncCommands async = connection.async(); FastShutdown.shutdown(redisClient); @@ -416,7 +430,7 @@ void resubscribeChannelsOnReconnect() throws Exception { assertThat(channels.take()).isEqualTo(channel); assertThat((long) counts.take()).isEqualTo(1); - Wait.untilTrue(pubsub::isOpen).waitOrTimeout(); + Wait.untilTrue(connection::isOpen).waitOrTimeout(); redis.publish(channel, message); assertThat(channels.take()).isEqualTo(channel); @@ -434,7 +448,7 @@ void resubscribePatternsOnReconnect() throws Exception { assertThat(patterns.take()).isEqualTo(pattern); assertThat((long) counts.take()).isEqualTo(1); - Wait.untilTrue(pubsub::isOpen).waitOrTimeout(); + Wait.untilTrue(connection::isOpen).waitOrTimeout(); redis.publish(channel, message); assertThat(channels.take()).isEqualTo(channel); @@ -459,7 +473,7 @@ public void unsubscribed(String channel, long count) { } }; - pubsub.getStatefulConnection().addListener(adapter); + connection.addListener(adapter); pubsub.subscribe(channel); pubsub.psubscribe(pattern); @@ -481,7 +495,7 @@ void removeListener() throws Exception { assertThat(channels.take()).isEqualTo(channel); assertThat(messages.take()).isEqualTo(message); - pubsub.getStatefulConnection().removeListener(this); + connection.removeListener(this); redis.publish(channel, message); assertThat(channels.poll(10, TimeUnit.MILLISECONDS)).isNull(); diff --git a/src/test/java/io/lettuce/core/pubsub/PubSubReactiveTest.java b/src/test/java/io/lettuce/core/pubsub/PubSubReactiveTest.java index ca77f2e50b..77442fee42 100644 --- a/src/test/java/io/lettuce/core/pubsub/PubSubReactiveTest.java +++ b/src/test/java/io/lettuce/core/pubsub/PubSubReactiveTest.java @@ -15,8 +15,7 @@ */ package io.lettuce.core.pubsub; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.*; import java.time.Duration; import java.util.List; @@ -50,7 +49,12 @@ */ class PubSubReactiveTest extends AbstractRedisClientTest implements RedisPubSubListener { - private RedisPubSubReactiveCommands pubsub; + private StatefulRedisPubSubConnection connection1; + + private RedisPubSubReactiveCommands pubsub1; + + private StatefulRedisPubSubConnection connection2; + private RedisPubSubReactiveCommands pubsub2; private BlockingQueue channels; @@ -65,9 +69,11 @@ class PubSubReactiveTest extends AbstractRedisClientTest implements RedisPubSubL @BeforeEach void openPubSubConnection() { - pubsub = client.connectPubSub().reactive(); - pubsub2 = client.connectPubSub().reactive(); - pubsub.getStatefulConnection().addListener(this); + connection1 = client.connectPubSub(); + pubsub1 = connection1.reactive(); + connection2 = client.connectPubSub(); + pubsub2 = connection2.reactive(); + connection1.addListener(this); channels = LettuceFactories.newBlockingQueue(); patterns = LettuceFactories.newBlockingQueue(); messages = LettuceFactories.newBlockingQueue(); @@ -76,18 +82,18 @@ void openPubSubConnection() { @AfterEach void closePubSubConnection() { - pubsub.getStatefulConnection().close(); - pubsub2.getStatefulConnection().close(); + connection1.close(); + connection2.close(); } @Test void observeChannels() throws Exception { - block(pubsub.subscribe(channel)); + block(pubsub1.subscribe(channel)); BlockingQueue> channelMessages = LettuceFactories.newBlockingQueue(); - Disposable disposable = pubsub.observeChannels().doOnNext(channelMessages::add).subscribe(); + Disposable disposable = pubsub1.observeChannels().doOnNext(channelMessages::add).subscribe(); redis.publish(channel, message); redis.publish(channel, message); @@ -109,14 +115,14 @@ void observeChannels() throws Exception { @Test void observeChannelsUnsubscribe() { - block(pubsub.subscribe(channel)); + block(pubsub1.subscribe(channel)); BlockingQueue> channelMessages = LettuceFactories.newBlockingQueue(); - pubsub.observeChannels().doOnNext(channelMessages::add).subscribe().dispose(); + pubsub1.observeChannels().doOnNext(channelMessages::add).subscribe().dispose(); - block(redis.getStatefulConnection().reactive().publish(channel, message)); - block(redis.getStatefulConnection().reactive().publish(channel, message)); + redis.publish(channel, message); + redis.publish(channel, message); Delay.delay(Duration.ofMillis(500)); assertThat(channelMessages).isEmpty(); @@ -125,11 +131,11 @@ void observeChannelsUnsubscribe() { @Test void observePatterns() throws Exception { - block(pubsub.psubscribe(pattern)); + block(pubsub1.psubscribe(pattern)); BlockingQueue> patternMessages = LettuceFactories.newBlockingQueue(); - pubsub.observePatterns().doOnNext(patternMessages::add).subscribe(); + pubsub1.observePatterns().doOnNext(patternMessages::add).subscribe(); redis.publish(channel, message); redis.publish(channel, message); @@ -147,11 +153,11 @@ void observePatterns() throws Exception { @Test void observePatternsWithUnsubscribe() { - block(pubsub.psubscribe(pattern)); + block(pubsub1.psubscribe(pattern)); BlockingQueue> patternMessages = LettuceFactories.newBlockingQueue(); - Disposable subscription = pubsub.observePatterns().doOnNext(patternMessages::add).subscribe(); + Disposable subscription = pubsub1.observePatterns().doOnNext(patternMessages::add).subscribe(); redis.publish(channel, message); redis.publish(channel, message); @@ -173,7 +179,7 @@ void observePatternsWithUnsubscribe() { @Test void message() throws Exception { - block(pubsub.subscribe(channel)); + block(pubsub1.subscribe(channel)); assertThat(channels.take()).isEqualTo(channel); redis.publish(channel, message); @@ -184,7 +190,7 @@ void message() throws Exception { @Test void pmessage() throws Exception { - block(pubsub.psubscribe(pattern)); + block(pubsub1.psubscribe(pattern)); assertThat(patterns.take()).isEqualTo(pattern); redis.publish(channel, message); @@ -201,7 +207,7 @@ void pmessage() throws Exception { @Test void psubscribe() throws Exception { - block(pubsub.psubscribe(pattern)); + block(pubsub1.psubscribe(pattern)); assertThat(patterns.take()).isEqualTo(pattern); assertThat((long) counts.take()).isEqualTo(1); @@ -209,13 +215,13 @@ void psubscribe() throws Exception { @Test void pubsubEmptyChannels() { - assertThatThrownBy(() -> pubsub.subscribe()).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> pubsub1.subscribe()).isInstanceOf(IllegalArgumentException.class); } @Test void pubsubChannels() { - block(pubsub.subscribe(channel)); + block(pubsub1.subscribe(channel)); List result = block(pubsub2.pubsubChannels().collectList()); assertThat(result).contains(channel); } @@ -223,7 +229,7 @@ void pubsubChannels() { @Test void pubsubMultipleChannels() { - StepVerifier.create(pubsub.subscribe(channel, "channel1", "channel3")).verifyComplete(); + StepVerifier.create(pubsub1.subscribe(channel, "channel1", "channel3")).verifyComplete(); StepVerifier.create(pubsub2.pubsubChannels().collectList()) .consumeNextWith(actual -> assertThat(actual).contains(channel, "channel1", "channel3")).verifyComplete(); @@ -232,7 +238,7 @@ void pubsubMultipleChannels() { @Test void pubsubChannelsWithArg() { - StepVerifier.create(pubsub.subscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.subscribe(channel)).verifyComplete(); Wait.untilTrue(() -> mono(pubsub2.pubsubChannels(pattern).filter(s -> channel.equals(s))) != null).waitOrTimeout(); String result = mono(pubsub2.pubsubChannels(pattern).filter(s -> channel.equals(s))); @@ -242,7 +248,7 @@ void pubsubChannelsWithArg() { @Test void pubsubNumsub() { - StepVerifier.create(pubsub.subscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.subscribe(channel)).verifyComplete(); Wait.untilEquals(1, () -> block(pubsub2.pubsubNumsub(channel)).size()).waitOrTimeout(); @@ -256,7 +262,7 @@ void pubsubNumpat() { Wait.untilEquals(0L, () -> block(pubsub2.pubsubNumpat())).waitOrTimeout(); - StepVerifier.create(pubsub.psubscribe(pattern)).verifyComplete(); + StepVerifier.create(pubsub1.psubscribe(pattern)).verifyComplete(); Wait.untilEquals(1L, () -> redis.pubsubNumpat()).waitOrTimeout(); Long result = block(pubsub2.pubsubNumpat()); @@ -266,7 +272,7 @@ void pubsubNumpat() { @Test void punsubscribe() throws Exception { - StepVerifier.create(pubsub.punsubscribe(pattern)).verifyComplete(); + StepVerifier.create(pubsub1.punsubscribe(pattern)).verifyComplete(); assertThat(patterns.take()).isEqualTo(pattern); assertThat((long) counts.take()).isEqualTo(0); @@ -275,7 +281,7 @@ void punsubscribe() throws Exception { @Test void subscribe() throws Exception { - StepVerifier.create(pubsub.subscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.subscribe(channel)).verifyComplete(); assertThat(channels.take()).isEqualTo(channel); assertThat((long) counts.take()).isGreaterThan(0); } @@ -283,11 +289,11 @@ void subscribe() throws Exception { @Test void unsubscribe() throws Exception { - StepVerifier.create(pubsub.unsubscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.unsubscribe(channel)).verifyComplete(); assertThat(channels.take()).isEqualTo(channel); assertThat((long) counts.take()).isEqualTo(0); - block(pubsub.unsubscribe()); + block(pubsub1.unsubscribe()); assertThat(channels).isEmpty(); assertThat(patterns).isEmpty(); @@ -299,7 +305,8 @@ void pubsubCloseOnClientShutdown() { RedisClient redisClient = RedisClient.create(TestClientResources.get(), RedisURI.Builder.redis(host, port).build()); - RedisPubSubCommands connection = redisClient.connectPubSub().sync(); + StatefulRedisPubSubConnection connection = redisClient.connectPubSub(); + RedisPubSubCommands sync = connection.sync(); FastShutdown.shutdown(redisClient); assertThat(connection.isOpen()).isFalse(); @@ -311,7 +318,7 @@ void utf8Channel() throws Exception { String channel = "channelλ"; String message = "αβγ"; - block(pubsub.subscribe(channel)); + block(pubsub1.subscribe(channel)); assertThat(channels.take()).isEqualTo(channel); StepVerifier.create(pubsub2.publish(channel, message)).expectNextCount(1).verifyComplete(); @@ -322,15 +329,15 @@ void utf8Channel() throws Exception { @Test void resubscribeChannelsOnReconnect() throws Exception { - StepVerifier.create(pubsub.subscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.subscribe(channel)).verifyComplete(); assertThat(channels.take()).isEqualTo(channel); assertThat((long) counts.take()).isEqualTo(1); - block(pubsub.quit()); + block(pubsub1.quit()); assertThat(channels.take()).isEqualTo(channel); assertThat((long) counts.take()).isEqualTo(1); - Wait.untilTrue(pubsub::isOpen).waitOrTimeout(); + Wait.untilTrue(connection1::isOpen).waitOrTimeout(); redis.publish(channel, message); assertThat(channels.take()).isEqualTo(channel); @@ -340,16 +347,16 @@ void resubscribeChannelsOnReconnect() throws Exception { @Test void resubscribePatternsOnReconnect() throws Exception { - StepVerifier.create(pubsub.psubscribe(pattern)).verifyComplete(); + StepVerifier.create(pubsub1.psubscribe(pattern)).verifyComplete(); assertThat(patterns.take()).isEqualTo(pattern); assertThat((long) counts.take()).isEqualTo(1); - block(pubsub.quit()); + block(pubsub1.quit()); assertThat(patterns.take()).isEqualTo(pattern); assertThat((long) counts.take()).isEqualTo(1); - Wait.untilTrue(pubsub::isOpen).waitOrTimeout(); + Wait.untilTrue(connection1::isOpen).waitOrTimeout(); StepVerifier.create(pubsub2.publish(channel, message)).expectNextCount(1).verifyComplete(); assertThat(channels.take()).isEqualTo(channel); @@ -375,15 +382,15 @@ public void unsubscribed(String channel, long count) { } }; - pubsub.getStatefulConnection().addListener(adapter); - StepVerifier.create(pubsub.subscribe(channel)).verifyComplete(); - StepVerifier.create(pubsub.psubscribe(pattern)).verifyComplete(); + connection1.addListener(adapter); + StepVerifier.create(pubsub1.subscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.psubscribe(pattern)).verifyComplete(); assertThat((long) localCounts.take()).isEqualTo(1L); StepVerifier.create(pubsub2.publish(channel, message)).expectNextCount(1).verifyComplete(); - StepVerifier.create(pubsub.punsubscribe(pattern)).verifyComplete(); - StepVerifier.create(pubsub.unsubscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.punsubscribe(pattern)).verifyComplete(); + StepVerifier.create(pubsub1.unsubscribe(channel)).verifyComplete(); assertThat((long) localCounts.take()).isEqualTo(0L); } @@ -391,14 +398,14 @@ public void unsubscribed(String channel, long count) { @Test void removeListener() throws Exception { - StepVerifier.create(pubsub.subscribe(channel)).verifyComplete(); + StepVerifier.create(pubsub1.subscribe(channel)).verifyComplete(); assertThat(channels.take()).isEqualTo(channel); StepVerifier.create(pubsub2.publish(channel, message)).expectNextCount(1).verifyComplete(); assertThat(channels.take()).isEqualTo(channel); assertThat(messages.take()).isEqualTo(message); - pubsub.getStatefulConnection().removeListener(this); + connection1.removeListener(this); StepVerifier.create(pubsub2.publish(channel, message)).expectNextCount(1).verifyComplete(); assertThat(channels.poll(10, TimeUnit.MILLISECONDS)).isNull(); diff --git a/src/test/java/io/lettuce/core/reliability/AtLeastOnceTest.java b/src/test/java/io/lettuce/core/reliability/AtLeastOnceTest.java index 5db9b59b7d..369ed168d7 100644 --- a/src/test/java/io/lettuce/core/reliability/AtLeastOnceTest.java +++ b/src/test/java/io/lettuce/core/reliability/AtLeastOnceTest.java @@ -64,10 +64,11 @@ void before() { // needs to be increased on slow systems...perhaps... client.setDefaultTimeout(3, TimeUnit.SECONDS); - RedisCommands connection = client.connect().sync(); - connection.flushall(); - connection.flushdb(); - connection.getStatefulConnection().close(); + try (StatefulRedisConnection connection = client.connect()) { + RedisCommands sync = connection.sync(); + sync.flushall(); + sync.flushdb(); + } } @Test @@ -83,71 +84,77 @@ void connectionIsConnectedAfterConnect() { @Test void reconnectIsActiveHandler() { - RedisCommands connection = client.connect().sync(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); - ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(connection.getStatefulConnection()); + ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(connection); assertThat(connectionWatchdog).isNotNull(); assertThat(connectionWatchdog.isListenOnChannelInactive()).isTrue(); assertThat(connectionWatchdog.isReconnectSuspended()).isFalse(); - connection.getStatefulConnection().close(); + connection.close(); } @Test void basicOperations() { - RedisCommands connection = client.connect().sync(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); - connection.set(key, "1"); - assertThat(connection.get("key")).isEqualTo("1"); + sync.set(key, "1"); + assertThat(sync.get("key")).isEqualTo("1"); - connection.getStatefulConnection().close(); + connection.close(); } @Test void noBufferedCommandsAfterExecute() { - RedisCommands connection = client.connect().sync(); - connection.set(key, "1"); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); - assertThat(ConnectionTestUtil.getStack(connection.getStatefulConnection())).isEmpty(); - assertThat(ConnectionTestUtil.getCommandBuffer(connection.getStatefulConnection())).isEmpty(); + sync.set(key, "1"); - connection.getStatefulConnection().close(); + assertThat(ConnectionTestUtil.getStack(connection)).isEmpty(); + assertThat(ConnectionTestUtil.getCommandBuffer(connection)).isEmpty(); + + connection.close(); } @Test void commandIsExecutedOnce() { - RedisCommands connection = client.connect().sync(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); - connection.set(key, "1"); - connection.incr(key); - assertThat(connection.get(key)).isEqualTo("2"); + sync.set(key, "1"); + sync.incr(key); + assertThat(sync.get(key)).isEqualTo("2"); - connection.incr(key); - assertThat(connection.get(key)).isEqualTo("3"); + sync.incr(key); + assertThat(sync.get(key)).isEqualTo("3"); - connection.incr(key); - assertThat(connection.get(key)).isEqualTo("4"); + sync.incr(key); + assertThat(sync.get(key)).isEqualTo("4"); - connection.getStatefulConnection().close(); + connection.close(); } @Test void commandFailsWhenFailOnEncode() { - RedisCommands connection = client.connect().sync(); - RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection.getStatefulConnection()); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); + RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection); RedisCommands verificationConnection = client.connect().sync(); - connection.set(key, "1"); + sync.set(key, "1"); AsyncCommand working = new AsyncCommand<>(new Command<>(CommandType.INCR, new IntegerOutput( StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8).addKey(key))); channelWriter.write(working); assertThat(working.await(2, TimeUnit.SECONDS)).isTrue(); - assertThat(connection.get(key)).isEqualTo("2"); + assertThat(sync.get(key)).isEqualTo("2"); AsyncCommand command = new AsyncCommand(new Command<>(CommandType.INCR, new IntegerOutput(StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8).addKey(key))) { @@ -166,9 +173,9 @@ public void encode(ByteBuf buf) { assertThat(verificationConnection.get(key)).isEqualTo("2"); - assertThat(ConnectionTestUtil.getStack(connection.getStatefulConnection())).isNotEmpty(); + assertThat(ConnectionTestUtil.getStack(connection)).isNotEmpty(); - connection.getStatefulConnection().close(); + connection.close(); } @Test @@ -220,15 +227,16 @@ void commandRetriedChannelClosesWhileFlush() { StatefulRedisConnection connection = client.connect(); RedisCommands sync = connection.sync(); - RedisCommands verificationConnection = client.connect().sync(); + StatefulRedisConnection verificationConnection = client.connect(); + RedisCommands verificationSync = verificationConnection.sync(); RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection); sync.set(key, "1"); - assertThat(verificationConnection.get(key)).isEqualTo("1"); + assertThat(verificationSync.get(key)).isEqualTo("1"); final CountDownLatch block = new CountDownLatch(1); - ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(sync.getStatefulConnection()); + ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(connection); AsyncCommand command = getBlockOnEncodeCommand(block); @@ -236,7 +244,7 @@ void commandRetriedChannelClosesWhileFlush() { connectionWatchdog.setReconnectSuspended(true); - Channel channel = ConnectionTestUtil.getChannel(sync.getStatefulConnection()); + Channel channel = ConnectionTestUtil.getChannel(connection); channel.unsafe().disconnect(channel.newPromise()); assertThat(channel.isOpen()).isFalse(); @@ -252,13 +260,13 @@ void commandRetriedChannelClosesWhileFlush() { assertThat(command.isCancelled()).isFalse(); assertThat(command.isDone()).isTrue(); - assertThat(verificationConnection.get(key)).isEqualTo("2"); + assertThat(verificationSync.get(key)).isEqualTo("2"); - assertThat(ConnectionTestUtil.getStack(sync.getStatefulConnection())).isEmpty(); - assertThat(ConnectionTestUtil.getCommandBuffer(sync.getStatefulConnection())).isEmpty(); + assertThat(ConnectionTestUtil.getStack(connection)).isEmpty(); + assertThat(ConnectionTestUtil.getCommandBuffer(connection)).isEmpty(); - sync.getStatefulConnection().close(); - verificationConnection.getStatefulConnection().close(); + connection.close(); + verificationConnection.close(); } AsyncCommand getBlockOnEncodeCommand(final CountDownLatch block) { @@ -279,11 +287,13 @@ public void encode(ByteBuf buf) { @Test void commandFailsDuringDecode() { - RedisCommands connection = client.connect().sync(); - RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection.getStatefulConnection()); - RedisCommands verificationConnection = client.connect().sync(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); + RedisChannelWriter channelWriter = ConnectionTestUtil.getChannelWriter(connection); + StatefulRedisConnection verificationConnection = client.connect(); + RedisCommands verificationConnectionSync = verificationConnection.sync(); - connection.set(key, "1"); + sync.set(key, "1"); AsyncCommand command = new AsyncCommand(new Command<>(CommandType.INCR, new StatusOutput<>( StringCodec.UTF8), new CommandArgs<>(StringCodec.UTF8).addKey(key))); @@ -295,11 +305,11 @@ void commandFailsDuringDecode() { assertThat(command.isDone()).isTrue(); assertThat(getException(command)).isInstanceOf(UnsupportedOperationException.class); - assertThat(verificationConnection.get(key)).isEqualTo("2"); - assertThat(connection.get(key)).isEqualTo("2"); + assertThat(verificationConnectionSync.get(key)).isEqualTo("2"); + assertThat(sync.get(key)).isEqualTo("2"); - connection.getStatefulConnection().close(); - verificationConnection.getStatefulConnection().close(); + connection.close(); + verificationConnection.close(); } @Test @@ -307,15 +317,16 @@ void commandCancelledOverSyncAPIAfterConnectionIsDisconnected() { StatefulRedisConnection connection = client.connect(); RedisCommands sync = connection.sync(); - RedisCommands verificationConnection = client.connect().sync(); + StatefulRedisConnection verificationConnection = client.connect(); + RedisCommands verificationConnectionSync = verificationConnection.sync(); sync.set(key, "1"); - ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(sync.getStatefulConnection()); + ConnectionWatchdog connectionWatchdog = ConnectionTestUtil.getConnectionWatchdog(connection); connectionWatchdog.setListenOnChannelInactive(false); sync.quit(); - Wait.untilTrue(() -> !sync.getStatefulConnection().isOpen()).waitOrTimeout(); + Wait.untilTrue(() -> !connection.isOpen()).waitOrTimeout(); try { sync.incr(key); @@ -323,7 +334,7 @@ void commandCancelledOverSyncAPIAfterConnectionIsDisconnected() { assertThat(e).isExactlyInstanceOf(RedisCommandTimeoutException.class); } - assertThat(verificationConnection.get("key")).isEqualTo("1"); + assertThat(verificationConnectionSync.get("key")).isEqualTo("1"); assertThat(ConnectionTestUtil.getDisconnectedBuffer(connection).size()).isGreaterThan(0); assertThat(ConnectionTestUtil.getCommandBuffer(connection)).isEmpty(); @@ -338,15 +349,16 @@ void commandCancelledOverSyncAPIAfterConnectionIsDisconnected() { assertThat(sync.get(key)).isEqualTo("1"); - sync.getStatefulConnection().close(); - verificationConnection.getStatefulConnection().close(); + connection.close(); + verificationConnection.close(); } @Test void retryAfterConnectionIsDisconnected() throws Exception { StatefulRedisConnection connection = client.connect(); - RedisCommands verificationConnection = client.connect().sync(); + StatefulRedisConnection verificationConnection = client.connect(); + RedisCommands verificationConnectionSync = verificationConnection.sync(); connection.sync().set(key, "1"); @@ -360,7 +372,7 @@ void retryAfterConnectionIsDisconnected() throws Exception { assertThat(connection.async().incr(key).await(1, TimeUnit.SECONDS)).isFalse(); - assertThat(verificationConnection.get("key")).isEqualTo("1"); + assertThat(verificationConnectionSync.get("key")).isEqualTo("1"); assertThat(ConnectionTestUtil.getDisconnectedBuffer(connection).size()).isGreaterThan(0); assertThat(ConnectionTestUtil.getCommandBuffer(connection)).isEmpty(); @@ -374,10 +386,10 @@ void retryAfterConnectionIsDisconnected() throws Exception { } assertThat(connection.sync().get(key)).isEqualTo("2"); - assertThat(verificationConnection.get(key)).isEqualTo("2"); + assertThat(verificationConnectionSync.get(key)).isEqualTo("2"); connection.close(); - verificationConnection.getStatefulConnection().close(); + verificationConnection.close(); } private Throwable getException(RedisFuture command) { diff --git a/src/test/java/io/lettuce/core/reliability/AtMostOnceTest.java b/src/test/java/io/lettuce/core/reliability/AtMostOnceTest.java index 3b46bc420f..82024a507c 100644 --- a/src/test/java/io/lettuce/core/reliability/AtMostOnceTest.java +++ b/src/test/java/io/lettuce/core/reliability/AtMostOnceTest.java @@ -66,10 +66,11 @@ void before() { // needs to be increased on slow systems...perhaps... client.setDefaultTimeout(3, TimeUnit.SECONDS); - RedisCommands connection = client.connect().sync(); - connection.flushall(); - connection.flushdb(); - connection.getStatefulConnection().close(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); + sync.flushall(); + sync.flushdb(); + connection.close(); } @Test @@ -95,12 +96,13 @@ void noReconnectHandler() { @Test void basicOperations() { - RedisCommands connection = client.connect().sync(); + StatefulRedisConnection connection = client.connect(); + RedisCommands sync = connection.sync(); - connection.set(key, "1"); - assertThat(connection.get("key")).isEqualTo("1"); + sync.set(key, "1"); + assertThat(sync.get("key")).isEqualTo("1"); - connection.getStatefulConnection().close(); + connection.close(); } @Test @@ -293,7 +295,7 @@ void commandsCancelledOnDisconnect() { try { RedisAsyncCommands async = connection.async(); - async.setAutoFlushCommands(false); + connection.setAutoFlushCommands(false); async.quit(); RedisFuture incr = async.incr(key); diff --git a/src/test/java/io/lettuce/core/sentinel/SentinelCommandIntegrationTests.java b/src/test/java/io/lettuce/core/sentinel/SentinelCommandIntegrationTests.java index 0062d14ebc..4d9a40a424 100644 --- a/src/test/java/io/lettuce/core/sentinel/SentinelCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/sentinel/SentinelCommandIntegrationTests.java @@ -34,6 +34,7 @@ import io.lettuce.core.RedisConnectionException; import io.lettuce.core.RedisURI; import io.lettuce.core.TestSupport; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection; import io.lettuce.core.sentinel.api.sync.RedisSentinelCommands; @@ -110,19 +111,21 @@ void sentinelConnectWith() { RedisURI uri = RedisURI.Builder.sentinel(TestSettings.host(), 1234, SentinelTestSettings.MASTER_ID) .withSentinel(TestSettings.host()).build(); - RedisSentinelCommands sentinelConnection = this.redisClient.connectSentinel(uri).sync(); - assertThat(sentinelConnection.ping()).isEqualTo("PONG"); + StatefulRedisSentinelConnection sentinelConnection = this.redisClient.connectSentinel(uri); + RedisSentinelCommands sync = sentinelConnection.sync(); + assertThat(sync.ping()).isEqualTo("PONG"); - sentinelConnection.getStatefulConnection().close(); + sentinelConnection.close(); - RedisCommands connection2 = this.redisClient.connect(uri).sync(); - assertThat(connection2.ping()).isEqualTo("PONG"); - connection2.quit(); + StatefulRedisConnection connection = this.redisClient.connect(uri); + RedisCommands commands = connection.sync(); + assertThat(commands.ping()).isEqualTo("PONG"); + commands.quit(); - Wait.untilTrue(() -> connection2.getStatefulConnection().isOpen()).waitOrTimeout(); + Wait.untilTrue(() -> connection.isOpen()).waitOrTimeout(); - assertThat(connection2.ping()).isEqualTo("PONG"); - connection2.getStatefulConnection().close(); + assertThat(commands.ping()).isEqualTo("PONG"); + connection.close(); } @Test @@ -145,17 +148,16 @@ void getMaster() { @Test void role() { - RedisCommands connection = redisClient.connect(RedisURI.Builder.redis(host, 26380).build()).sync(); - try { + try (StatefulRedisConnection connection = redisClient + .connect(RedisURI.Builder.redis(host, 26380).build())) { + RedisCommands sync = connection.sync(); - List objects = connection.role(); + List objects = sync.role(); assertThat(objects).hasSize(2); - assertThat(objects.get(0)).isEqualTo("sentinel"); - assertThat(objects.get(1).toString()).isEqualTo("[" + SentinelTestSettings.MASTER_ID + "]"); - } finally { - connection.getStatefulConnection().close(); + assertThat(objects.get(0)).isEqualTo("sentinel"); + assertThat(objects.get(1).toString()).isEqualTo("[" + SentinelTestSettings.MASTER_ID + "]"); } } diff --git a/src/test/java/io/lettuce/core/sentinel/SentinelConnectionIntegrationTests.java b/src/test/java/io/lettuce/core/sentinel/SentinelConnectionIntegrationTests.java index b1d38b6793..046d381232 100644 --- a/src/test/java/io/lettuce/core/sentinel/SentinelConnectionIntegrationTests.java +++ b/src/test/java/io/lettuce/core/sentinel/SentinelConnectionIntegrationTests.java @@ -15,7 +15,7 @@ */ package io.lettuce.core.sentinel; -import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.*; import java.util.List; import java.util.Map; @@ -29,7 +29,11 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import io.lettuce.core.*; +import io.lettuce.core.ClientOptions; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisFuture; +import io.lettuce.core.RedisURI; +import io.lettuce.core.TestSupport; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.codec.ByteArrayCodec; import io.lettuce.core.sentinel.api.StatefulRedisSentinelConnection; @@ -37,7 +41,6 @@ import io.lettuce.core.sentinel.api.sync.RedisSentinelCommands; import io.lettuce.test.LettuceExtension; import io.lettuce.test.TestFutures; -import io.lettuce.test.Wait; import io.lettuce.test.settings.TestSettings; /** @@ -99,66 +102,25 @@ void testFuture() throws Exception { assertThat(state.get()).isTrue(); } - @Test - void testStatefulConnection() { - - StatefulRedisSentinelConnection statefulConnection = sentinel.getStatefulConnection(); - assertThat(statefulConnection).isSameAs(statefulConnection.async().getStatefulConnection()); - } - @Test - void testSyncConnection() { - - StatefulRedisSentinelConnection statefulConnection = sentinel.getStatefulConnection(); - RedisSentinelCommands sync = statefulConnection.sync(); - assertThat(sync.ping()).isEqualTo("PONG"); - } - - @Test - void testSyncAsyncConversion() { - - StatefulRedisSentinelConnection statefulConnection = sentinel.getStatefulConnection(); - assertThat(statefulConnection.sync().getStatefulConnection()).isSameAs(statefulConnection); - assertThat(statefulConnection.sync().getStatefulConnection().sync()).isSameAs(statefulConnection.sync()); - } - - @Test - void testSyncClose() { - - StatefulRedisSentinelConnection statefulConnection = sentinel.getStatefulConnection(); - statefulConnection.sync().getStatefulConnection().close(); - - Wait.untilTrue(() -> !sentinel.isOpen()).waitOrTimeout(); - - assertThat(sentinel.isOpen()).isFalse(); - assertThat(statefulConnection.isOpen()).isFalse(); - } - - @Test - void testAsyncClose() { - StatefulRedisSentinelConnection statefulConnection = sentinel.getStatefulConnection(); - statefulConnection.async().getStatefulConnection().close(); - - Wait.untilTrue(() -> !sentinel.isOpen()).waitOrTimeout(); - - assertThat(sentinel.isOpen()).isFalse(); - assertThat(statefulConnection.isOpen()).isFalse(); - } @Test void connectToOneNode() { - RedisSentinelCommands connection = redisClient.connectSentinel(SentinelTestSettings.SENTINEL_URI) + StatefulRedisSentinelConnection connection = redisClient + .connectSentinel(SentinelTestSettings.SENTINEL_URI); + RedisSentinelCommands sync = connection .sync(); - assertThat(connection.ping()).isEqualTo("PONG"); - connection.getStatefulConnection().close(); + assertThat(sync.ping()).isEqualTo("PONG"); + connection.close(); } @Test void connectWithByteCodec() { - RedisSentinelCommands connection = redisClient.connectSentinel(new ByteArrayCodec(), - SentinelTestSettings.SENTINEL_URI).sync(); - assertThat(connection.master(SentinelTestSettings.MASTER_ID.getBytes())).isNotNull(); - connection.getStatefulConnection().close(); + StatefulRedisSentinelConnection connection = redisClient.connectSentinel(new ByteArrayCodec(), + SentinelTestSettings.SENTINEL_URI); + RedisSentinelCommands sync = connection.sync(); + assertThat(sync.master(SentinelTestSettings.MASTER_ID.getBytes())).isNotNull(); + connection.close(); } @Test diff --git a/src/test/java/io/lettuce/core/sentinel/SentinelServerCommandIntegrationTests.java b/src/test/java/io/lettuce/core/sentinel/SentinelServerCommandIntegrationTests.java index 3bb0bc42a1..5313ad338a 100644 --- a/src/test/java/io/lettuce/core/sentinel/SentinelServerCommandIntegrationTests.java +++ b/src/test/java/io/lettuce/core/sentinel/SentinelServerCommandIntegrationTests.java @@ -98,8 +98,9 @@ public void clientKill() { public void clientKillExtended() { RedisURI redisURI = RedisURI.Builder.sentinel(TestSettings.host(), SentinelTestSettings.MASTER_ID).build(); - RedisSentinelCommands connection2 = redisClient.connectSentinel(redisURI).sync(); - connection2.clientSetname("killme"); + StatefulRedisSentinelConnection connection = redisClient.connectSentinel(redisURI); + RedisSentinelCommands sync = connection.sync(); + sync.clientSetname("killme"); Pattern p = Pattern.compile("^.*[^l]addr=([^ ]+).*name=killme.*$", Pattern.MULTILINE | Pattern.DOTALL); String clients = sentinel.clientList(); @@ -114,7 +115,7 @@ public void clientKillExtended() { assertThat(sentinel.clientKill(KillArgs.Builder.typeNormal().id(4234))).isEqualTo(0); assertThat(sentinel.clientKill(KillArgs.Builder.typePubsub().id(4234))).isEqualTo(0); - connection2.getStatefulConnection().close(); + connection.close(); } @Test diff --git a/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java b/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java index d4b2a9c0f6..d6e693b7bd 100644 --- a/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java +++ b/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java @@ -15,8 +15,7 @@ */ package io.lettuce.core.support; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.*; import java.lang.reflect.Proxy; import java.util.Set; @@ -27,7 +26,14 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import io.lettuce.core.*; +import io.lettuce.core.ClientOptions; +import io.lettuce.core.RedisAsyncCommandsImpl; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisCommandExecutionException; +import io.lettuce.core.RedisException; +import io.lettuce.core.RedisReactiveCommandsImpl; +import io.lettuce.core.RedisURI; +import io.lettuce.core.TestSupport; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.api.reactive.RedisReactiveCommands; @@ -75,8 +81,8 @@ void asyncPoolShouldWorkWithWrappedConnections() { borrowAndClose(pool); borrowAndCloseAsync(pool); - TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()).sync().getStatefulConnection())); - TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()).async().getStatefulConnection())); + TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()))); + TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()))); assertThat(channels).hasSize(1); @@ -97,8 +103,8 @@ void asyncPoolWithAsyncCreationWorkWithWrappedConnections() { borrowAndClose(pool); borrowAndCloseAsync(pool); - TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()).sync().getStatefulConnection())); - TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()).async().getStatefulConnection())); + TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()))); + TestFutures.awaitOrTimeout(pool.release(TestFutures.getOrTimeout(pool.acquire()))); assertThat(channels).hasSize(1); @@ -187,8 +193,6 @@ void wrappedConnectionShouldUseWrappers() { assertThat(connection.async()).isInstanceOf(RedisAsyncCommands.class).isNotInstanceOf(RedisAsyncCommandsImpl.class); assertThat(connection.reactive()).isInstanceOf(RedisReactiveCommands.class).isNotInstanceOf( RedisReactiveCommandsImpl.class); - assertThat(sync.getStatefulConnection()).isInstanceOf(StatefulRedisConnection.class) - .isNotInstanceOf(StatefulRedisConnectionImpl.class).isSameAs(connection); connection.close(); pool.close(); diff --git a/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java b/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java index ba703e02d3..0c4301342c 100644 --- a/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java +++ b/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java @@ -15,8 +15,7 @@ */ package io.lettuce.core.support; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +import static org.assertj.core.api.Assertions.*; import java.lang.reflect.Proxy; import java.util.Set; @@ -28,9 +27,15 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import io.lettuce.test.ReflectionTestUtils; -import io.lettuce.core.*; +import io.lettuce.core.ClientOptions; +import io.lettuce.core.RedisAsyncCommandsImpl; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisCommandExecutionException; +import io.lettuce.core.RedisException; +import io.lettuce.core.RedisReactiveCommandsImpl; +import io.lettuce.core.RedisURI; +import io.lettuce.core.TestSupport; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.async.RedisAsyncCommands; import io.lettuce.core.api.reactive.RedisReactiveCommands; @@ -46,6 +51,7 @@ import io.lettuce.core.codec.StringCodec; import io.lettuce.core.masterreplica.MasterReplica; import io.lettuce.core.masterreplica.StatefulRedisMasterReplicaConnection; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.test.Wait; import io.lettuce.test.resource.FastShutdown; import io.lettuce.test.resource.TestClientResources; @@ -83,8 +89,8 @@ void genericPoolShouldWorkWithWrappedConnections() throws Exception { borrowAndClose(pool); borrowAndCloseTryWithResources(pool); - pool.returnObject(pool.borrowObject().sync().getStatefulConnection()); - pool.returnObject(pool.borrowObject().async().getStatefulConnection()); + pool.returnObject(pool.borrowObject()); + pool.returnObject(pool.borrowObject()); assertThat(channels).hasSize(1); @@ -196,8 +202,6 @@ void wrappedConnectionShouldUseWrappers() throws Exception { assertThat(connection.async()).isInstanceOf(RedisAsyncCommands.class).isNotInstanceOf(RedisAsyncCommandsImpl.class); assertThat(connection.reactive()).isInstanceOf(RedisReactiveCommands.class).isNotInstanceOf( RedisReactiveCommandsImpl.class); - assertThat(sync.getStatefulConnection()).isInstanceOf(StatefulRedisConnection.class) - .isNotInstanceOf(StatefulRedisConnectionImpl.class).isSameAs(connection); connection.close(); pool.close(); @@ -220,8 +224,6 @@ void wrappedMasterSlaveConnectionShouldUseWrappers() throws Exception { assertThat(connection.async()).isInstanceOf(RedisAsyncCommands.class).isNotInstanceOf(RedisAsyncCommandsImpl.class); assertThat(connection.reactive()).isInstanceOf(RedisReactiveCommands.class).isNotInstanceOf( RedisReactiveCommandsImpl.class); - assertThat(sync.getStatefulConnection()).isInstanceOf(StatefulRedisConnection.class) - .isNotInstanceOf(StatefulRedisConnectionImpl.class).isSameAs(connection); connection.close(); pool.close(); @@ -248,8 +250,6 @@ void wrappedClusterConnectionShouldUseWrappers() throws Exception { RedisAdvancedClusterAsyncCommandsImpl.class); assertThat(connection.reactive()).isInstanceOf(RedisAdvancedClusterReactiveCommands.class).isNotInstanceOf( RedisAdvancedClusterReactiveCommandsImpl.class); - assertThat(sync.getStatefulConnection()).isInstanceOf(StatefulRedisClusterConnection.class) - .isNotInstanceOf(StatefulRedisClusterConnectionImpl.class).isSameAs(connection); connection.close(); pool.close(); @@ -274,8 +274,6 @@ void plainConnectionShouldNotUseWrappers() throws Exception { assertThat(connection.async()).isInstanceOf(RedisAsyncCommands.class).isInstanceOf(RedisAsyncCommandsImpl.class); assertThat(connection.reactive()).isInstanceOf(RedisReactiveCommands.class).isInstanceOf( RedisReactiveCommandsImpl.class); - assertThat(sync.getStatefulConnection()).isInstanceOf(StatefulRedisConnection.class).isInstanceOf( - StatefulRedisConnectionImpl.class); pool.returnObject(connection); pool.close(); diff --git a/src/test/java/io/lettuce/core/support/InjectedClient.java b/src/test/java/io/lettuce/core/support/InjectedClient.java index 939488f867..14a5f4d627 100644 --- a/src/test/java/io/lettuce/core/support/InjectedClient.java +++ b/src/test/java/io/lettuce/core/support/InjectedClient.java @@ -20,6 +20,7 @@ import javax.inject.Inject; import io.lettuce.core.RedisClient; +import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.cluster.RedisClusterClient; @@ -43,21 +44,24 @@ public class InjectedClient { @PersonDB public RedisClusterClient qualifiedRedisClusterClient; - private RedisCommands connection; + private StatefulRedisConnection connection; + + private RedisCommands commands; @PostConstruct public void postConstruct() { - connection = redisClient.connect().sync(); + connection = redisClient.connect(); + commands = connection.sync(); } public void pingRedis() { - connection.ping(); + commands.ping(); } @PreDestroy public void preDestroy() { if (connection != null) { - connection.getStatefulConnection().close(); + connection.close(); } } } diff --git a/src/test/java/io/lettuce/test/LettuceExtension.java b/src/test/java/io/lettuce/test/LettuceExtension.java index 28026fc80b..9b6e09edcf 100644 --- a/src/test/java/io/lettuce/test/LettuceExtension.java +++ b/src/test/java/io/lettuce/test/LettuceExtension.java @@ -23,14 +23,28 @@ import java.lang.reflect.Parameter; import java.lang.reflect.Type; import java.time.Duration; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; import javax.enterprise.inject.New; import javax.inject.Inject; -import org.junit.jupiter.api.extension.*; +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; import io.lettuce.core.ClientOptions; import io.lettuce.core.RedisClient; @@ -103,7 +117,8 @@ public class LettuceExtension implements ParameterResolver, AfterAllCallback, Af private final ExtensionContext.Namespace LETTUCE = ExtensionContext.Namespace.create("lettuce.parameters"); - private static final Set> SUPPORTED_INJECTABLE_TYPES = new HashSet<>(Arrays.asList(StatefulRedisConnection.class, + private static final Set> SUPPORTED_INJECTABLE_TYPES = new HashSet<>(Arrays.asList(StatefulConnection.class, + StatefulRedisConnection.class, StatefulRedisPubSubConnection.class, RedisCommands.class, RedisClient.class, ClientResources.class, StatefulRedisClusterConnection.class, RedisClusterClient.class)); From 7ebabf53f13e430408e5ed3de90054bb41c1f239 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 1 Mar 2022 15:15:14 +0100 Subject: [PATCH 3/6] Promote AsyncCloseable to public API #2030 --- src/main/java/io/lettuce/core/api/AsyncCloseable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/lettuce/core/api/AsyncCloseable.java b/src/main/java/io/lettuce/core/api/AsyncCloseable.java index 2372cd0d61..b3b334b1d3 100644 --- a/src/main/java/io/lettuce/core/api/AsyncCloseable.java +++ b/src/main/java/io/lettuce/core/api/AsyncCloseable.java @@ -21,7 +21,7 @@ * A {@link AsyncCloseable} is a resource that can be closed. The {@link #closeAsync()} method is invoked to request resources * release that the object is holding (such as open files). * - * @since 5.1 + * @since 6.2 * @author Mark Paluch */ public interface AsyncCloseable { From 3991e73b215918fb08f28621f6cce0eed4d01ec5 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 1 Mar 2022 15:40:03 +0100 Subject: [PATCH 4/6] Move connection-related commands from BaseRedisCommands to RedisConnectionCommands #2031 --- .../core/AbstractRedisAsyncCommands.java | 3 +- .../core/AbstractRedisReactiveCommands.java | 3 +- .../core/api/async/RedisAsyncCommands.java | 18 -- .../async/RedisConnectionAsyncCommands.java | 192 +++++++++++++++++ .../api/async/RedisServerAsyncCommands.java | 98 +-------- .../RedisConnectionReactiveCommands.java | 191 +++++++++++++++++ .../api/reactive/RedisReactiveCommands.java | 21 +- .../reactive/RedisServerReactiveCommands.java | 98 +-------- .../lettuce/core/api/sync/RedisCommands.java | 27 +-- .../api/sync/RedisConnectionCommands.java | 191 +++++++++++++++++ .../core/api/sync/RedisServerCommands.java | 98 +-------- .../api/async/NodeSelectionAsyncCommands.java | 3 +- .../NodeSelectionConnectionAsyncCommands.java | 160 +++++++++++++++ .../NodeSelectionServerAsyncCommands.java | 98 +-------- .../api/async/RedisClusterAsyncCommands.java | 5 +- .../RedisClusterReactiveCommands.java | 28 +-- .../api/sync/NodeSelectionCommands.java | 3 +- .../sync/NodeSelectionConnectionCommands.java | 160 +++++++++++++++ .../api/sync/NodeSelectionServerCommands.java | 98 +-------- .../api/sync/RedisClusterCommands.java | 28 +-- .../coroutines/BaseRedisCoroutinesCommands.kt | 46 ----- .../BaseRedisCoroutinesCommandsImpl.kt | 13 +- .../RedisConnectionCoroutinesCommands.kt | 194 ++++++++++++++++++ .../RedisConnectionCoroutinesCommandsImpl.kt | 80 ++++++++ .../coroutines/RedisCoroutinesCommandsImpl.kt | 19 +- .../RedisServerCoroutinesCommands.kt | 136 +++--------- .../RedisServerCoroutinesCommandsImpl.kt | 26 +-- .../lettuce/core/api/BaseRedisCommands.java | 46 ----- .../core/api/RedisConnectionCommands.java | 191 +++++++++++++++++ .../lettuce/core/api/RedisServerCommands.java | 93 --------- .../io/lettuce/apigenerator/Constants.java | 1 + .../CreateSyncNodeSelectionClusterApi.java | 4 +- 32 files changed, 1429 insertions(+), 943 deletions(-) create mode 100644 src/main/java/io/lettuce/core/api/async/RedisConnectionAsyncCommands.java create mode 100644 src/main/java/io/lettuce/core/api/reactive/RedisConnectionReactiveCommands.java create mode 100644 src/main/java/io/lettuce/core/api/sync/RedisConnectionCommands.java create mode 100644 src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionConnectionAsyncCommands.java create mode 100644 src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionConnectionCommands.java create mode 100644 src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommands.kt create mode 100644 src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommandsImpl.kt create mode 100644 src/main/templates/io/lettuce/core/api/RedisConnectionCommands.java diff --git a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java index 43238afcf6..b5ff7accb2 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisAsyncCommands.java @@ -58,7 +58,8 @@ * @author Andrey Shlykov */ @SuppressWarnings("unchecked") -public abstract class AbstractRedisAsyncCommands implements RedisAclAsyncCommands, +public abstract class AbstractRedisAsyncCommands + implements RedisAclAsyncCommands, RedisConnectionAsyncCommands, RedisHashAsyncCommands, RedisKeyAsyncCommands, RedisStringAsyncCommands, RedisListAsyncCommands, RedisSetAsyncCommands, RedisSortedSetAsyncCommands, RedisScriptingAsyncCommands, RedisServerAsyncCommands, RedisHLLAsyncCommands, diff --git a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java index 55e6cb8a3a..a730b2736d 100644 --- a/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/AbstractRedisReactiveCommands.java @@ -66,7 +66,8 @@ * @author Andrey Shlykov * @since 4.0 */ -public abstract class AbstractRedisReactiveCommands implements RedisAclReactiveCommands, +public abstract class AbstractRedisReactiveCommands + implements RedisAclReactiveCommands, RedisConnectionReactiveCommands, RedisHashReactiveCommands, RedisKeyReactiveCommands, RedisStringReactiveCommands, RedisListReactiveCommands, RedisSetReactiveCommands, RedisSortedSetReactiveCommands, RedisScriptingReactiveCommands, RedisServerReactiveCommands, RedisHLLReactiveCommands, diff --git a/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java index fce5f4c84e..53506619a9 100644 --- a/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/RedisAsyncCommands.java @@ -32,24 +32,6 @@ public interface RedisAsyncCommands extends BaseRedisAsyncCommands, RedisSetAsyncCommands, RedisSortedSetAsyncCommands, RedisStreamAsyncCommands, RedisStringAsyncCommands, RedisTransactionalAsyncCommands { - /** - * Authenticate to the server. - * - * @param password the password - * @return String simple-string-reply - */ - RedisFuture auth(CharSequence password); - - /** - * Authenticate to the server with username and password. Requires Redis 6 or newer. - * - * @param username the username - * @param password the password - * @return String simple-string-reply - * @since 6.0 - */ - RedisFuture auth(String username, CharSequence password); - /** * Change the selected database for the current connection. * diff --git a/src/main/java/io/lettuce/core/api/async/RedisConnectionAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisConnectionAsyncCommands.java new file mode 100644 index 0000000000..b0f7abaebd --- /dev/null +++ b/src/main/java/io/lettuce/core/api/async/RedisConnectionAsyncCommands.java @@ -0,0 +1,192 @@ +/* + * Copyright 2017-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core.api.async; + +import java.util.List; + +import io.lettuce.core.KillArgs; +import io.lettuce.core.RedisFuture; +import io.lettuce.core.TrackingArgs; +import io.lettuce.core.UnblockType; + +/** + * Asynchronous executed commands for connection commands. + * + * @param Key type. + * @param Value type. + * @author Mark Paluch + * @since 7.0 + * @generated by io.lettuce.apigenerator.CreateAsyncApi + */ +public interface RedisConnectionAsyncCommands { + + /** + * Authenticate to the server. + * + * @param password the password + * @return String simple-string-reply + */ + RedisFuture auth(CharSequence password); + + /** + * Authenticate to the server with username and password. Requires Redis 6 or newer. + * + * @param username the username + * @param password the password + * @return String simple-string-reply + * @since 6.0 + */ + RedisFuture auth(String username, CharSequence password); + + /** + * Control tracking of keys in the context of server-assisted client cache invalidation. + * + * @param enabled {@code true} to enable key tracking. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + RedisFuture clientCaching(boolean enabled); + + /** + * Get the current connection name. + * + * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. + */ + RedisFuture clientGetname(); + + /** + * Returns the client ID we are redirecting our tracking notifications to. + * + * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not + * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. + * @since 6.0 + */ + RedisFuture clientGetredir(); + + /** + * Get the id of the current connection. + * + * @return Long The command just returns the ID of the current connection. + * @since 5.3 + */ + RedisFuture clientId(); + + /** + * Kill the connection of a client identified by ip:port. + * + * @param addr ip:port. + * @return String simple-string-reply {@code OK} if the connection exists and has been closed. + */ + RedisFuture clientKill(String addr); + + /** + * Kill connections of clients which are filtered by {@code killArgs}. + * + * @param killArgs args for the kill operation. + * @return Long integer-reply number of killed connections. + */ + RedisFuture clientKill(KillArgs killArgs); + + /** + * Get the list of client connections. + * + * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), + * each line is composed of a succession of property=value fields separated by a space character. + */ + RedisFuture clientList(); + + /** + * Stop processing commands from clients for some time. + * + * @param timeout the timeout value in milliseconds. + * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. + */ + RedisFuture clientPause(long timeout); + + /** + * Set the current connection name. + * + * @param name the client name. + * @return simple-string-reply {@code OK} if the connection name was successfully set. + */ + RedisFuture clientSetname(K name); + + /** + * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages + * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. + * + * @param args for the CLIENT TRACKING operation. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + RedisFuture clientTracking(TrackingArgs args); + + /** + * Unblock the specified blocked client. + * + * @param id the client id. + * @param type unblock type. + * @return Long integer-reply number of unblocked connections. + * @since 5.1 + */ + RedisFuture clientUnblock(long id, UnblockType type); + + /** + * Echo the given string. + * + * @param msg the message type: value. + * @return V bulk-string-reply. + */ + RedisFuture echo(V msg); + + /** + * Return the role of the instance in the context of replication. + * + * @return List<Object> array-reply where the first element is one of master, slave, sentinel and the additional + * elements are role-specific. + */ + RedisFuture> role(); + + /** + * Ping the server. + * + * @return String simple-string-reply. + */ + RedisFuture ping(); + + /** + * Switch connection to Read-Only mode when connecting to a cluster. + * + * @return String simple-string-reply. + */ + RedisFuture readOnly(); + + /** + * Switch connection to Read-Write mode (default) when connecting to a cluster. + * + * @return String simple-string-reply. + */ + RedisFuture readWrite(); + + /** + * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if + * the connection was disconnected. Use {@link io.lettuce.core.api.StatefulConnection#close} to close connections and + * release resources. + * + * @return String simple-string-reply always OK. + */ + RedisFuture quit(); +} diff --git a/src/main/java/io/lettuce/core/api/async/RedisServerAsyncCommands.java b/src/main/java/io/lettuce/core/api/async/RedisServerAsyncCommands.java index 4698c1950b..edddafb6ad 100644 --- a/src/main/java/io/lettuce/core/api/async/RedisServerAsyncCommands.java +++ b/src/main/java/io/lettuce/core/api/async/RedisServerAsyncCommands.java @@ -20,11 +20,8 @@ import java.util.Map; import io.lettuce.core.FlushMode; -import io.lettuce.core.KillArgs; import io.lettuce.core.RedisFuture; import io.lettuce.core.ShutdownArgs; -import io.lettuce.core.TrackingArgs; -import io.lettuce.core.UnblockType; import io.lettuce.core.protocol.CommandType; /** @@ -52,99 +49,6 @@ public interface RedisServerAsyncCommands { */ RedisFuture bgsave(); - /** - * Control tracking of keys in the context of server-assisted client cache invalidation. - * - * @param enabled {@code true} to enable key tracking. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - RedisFuture clientCaching(boolean enabled); - - /** - * Get the current connection name. - * - * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. - */ - RedisFuture clientGetname(); - - /** - * Returns the client ID we are redirecting our tracking notifications to. - * - * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not - * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. - * @since 6.0 - */ - RedisFuture clientGetredir(); - - /** - * Get the id of the current connection. - * - * @return Long The command just returns the ID of the current connection. - * @since 5.3 - */ - RedisFuture clientId(); - - /** - * Kill the connection of a client identified by ip:port. - * - * @param addr ip:port. - * @return String simple-string-reply {@code OK} if the connection exists and has been closed. - */ - RedisFuture clientKill(String addr); - - /** - * Kill connections of clients which are filtered by {@code killArgs}. - * - * @param killArgs args for the kill operation. - * @return Long integer-reply number of killed connections. - */ - RedisFuture clientKill(KillArgs killArgs); - - /** - * Get the list of client connections. - * - * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), - * each line is composed of a succession of property=value fields separated by a space character. - */ - RedisFuture clientList(); - - /** - * Stop processing commands from clients for some time. - * - * @param timeout the timeout value in milliseconds. - * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. - */ - RedisFuture clientPause(long timeout); - - /** - * Set the current connection name. - * - * @param name the client name. - * @return simple-string-reply {@code OK} if the connection name was successfully set. - */ - RedisFuture clientSetname(K name); - - /** - * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages - * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. - * - * @param args for the CLIENT TRACKING operation. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - RedisFuture clientTracking(TrackingArgs args); - - /** - * Unblock the specified blocked client. - * - * @param id the client id. - * @param type unblock type. - * @return Long integer-reply number of unblocked connections. - * @since 5.1 - */ - RedisFuture clientUnblock(long id, UnblockType type); - /** * Returns an array reply of details about all Redis commands. * @@ -421,6 +325,7 @@ public interface RedisServerAsyncCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaof(String, int)} instead. */ + @Deprecated RedisFuture slaveof(String host, int port); /** @@ -429,6 +334,7 @@ public interface RedisServerAsyncCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaofNoOne()} instead. */ + @Deprecated RedisFuture slaveofNoOne(); /** diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisConnectionReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisConnectionReactiveCommands.java new file mode 100644 index 0000000000..c7c2f30e09 --- /dev/null +++ b/src/main/java/io/lettuce/core/api/reactive/RedisConnectionReactiveCommands.java @@ -0,0 +1,191 @@ +/* + * Copyright 2017-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core.api.reactive; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import io.lettuce.core.KillArgs; +import io.lettuce.core.TrackingArgs; +import io.lettuce.core.UnblockType; + +/** + * Reactive executed commands for connection commands. + * + * @param Key type. + * @param Value type. + * @author Mark Paluch + * @since 7.0 + * @generated by io.lettuce.apigenerator.CreateReactiveApi + */ +public interface RedisConnectionReactiveCommands { + + /** + * Authenticate to the server. + * + * @param password the password + * @return String simple-string-reply + */ + Mono auth(CharSequence password); + + /** + * Authenticate to the server with username and password. Requires Redis 6 or newer. + * + * @param username the username + * @param password the password + * @return String simple-string-reply + * @since 6.0 + */ + Mono auth(String username, CharSequence password); + + /** + * Control tracking of keys in the context of server-assisted client cache invalidation. + * + * @param enabled {@code true} to enable key tracking. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + Mono clientCaching(boolean enabled); + + /** + * Get the current connection name. + * + * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. + */ + Mono clientGetname(); + + /** + * Returns the client ID we are redirecting our tracking notifications to. + * + * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not + * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. + * @since 6.0 + */ + Mono clientGetredir(); + + /** + * Get the id of the current connection. + * + * @return Long The command just returns the ID of the current connection. + * @since 5.3 + */ + Mono clientId(); + + /** + * Kill the connection of a client identified by ip:port. + * + * @param addr ip:port. + * @return String simple-string-reply {@code OK} if the connection exists and has been closed. + */ + Mono clientKill(String addr); + + /** + * Kill connections of clients which are filtered by {@code killArgs}. + * + * @param killArgs args for the kill operation. + * @return Long integer-reply number of killed connections. + */ + Mono clientKill(KillArgs killArgs); + + /** + * Get the list of client connections. + * + * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), + * each line is composed of a succession of property=value fields separated by a space character. + */ + Mono clientList(); + + /** + * Stop processing commands from clients for some time. + * + * @param timeout the timeout value in milliseconds. + * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. + */ + Mono clientPause(long timeout); + + /** + * Set the current connection name. + * + * @param name the client name. + * @return simple-string-reply {@code OK} if the connection name was successfully set. + */ + Mono clientSetname(K name); + + /** + * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages + * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. + * + * @param args for the CLIENT TRACKING operation. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + Mono clientTracking(TrackingArgs args); + + /** + * Unblock the specified blocked client. + * + * @param id the client id. + * @param type unblock type. + * @return Long integer-reply number of unblocked connections. + * @since 5.1 + */ + Mono clientUnblock(long id, UnblockType type); + + /** + * Echo the given string. + * + * @param msg the message type: value. + * @return V bulk-string-reply. + */ + Mono echo(V msg); + + /** + * Return the role of the instance in the context of replication. + * + * @return Object array-reply where the first element is one of master, slave, sentinel and the additional elements are + * role-specific. + */ + Flux role(); + + /** + * Ping the server. + * + * @return String simple-string-reply. + */ + Mono ping(); + + /** + * Switch connection to Read-Only mode when connecting to a cluster. + * + * @return String simple-string-reply. + */ + Mono readOnly(); + + /** + * Switch connection to Read-Write mode (default) when connecting to a cluster. + * + * @return String simple-string-reply. + */ + Mono readWrite(); + + /** + * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if + * the connection was disconnected. Use {@link io.lettuce.core.api.StatefulConnection#close} to close connections and + * release resources. + * + * @return String simple-string-reply always OK. + */ + Mono quit(); +} diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java index 308071ef73..6ff8f54922 100644 --- a/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/RedisReactiveCommands.java @@ -26,30 +26,13 @@ * @author Mark Paluch * @since 5.0 */ -public interface RedisReactiveCommands extends BaseRedisReactiveCommands, RedisAclReactiveCommands, RedisClusterReactiveCommands, +public interface RedisReactiveCommands extends BaseRedisReactiveCommands, RedisAclReactiveCommands, + RedisClusterReactiveCommands, RedisConnectionReactiveCommands, RedisGeoReactiveCommands, RedisHashReactiveCommands, RedisHLLReactiveCommands, RedisKeyReactiveCommands, RedisListReactiveCommands, RedisScriptingReactiveCommands, RedisServerReactiveCommands, RedisSetReactiveCommands, RedisSortedSetReactiveCommands, RedisStreamReactiveCommands, RedisStringReactiveCommands, RedisTransactionalReactiveCommands { - /** - * Authenticate to the server. - * - * @param password the password - * @return String simple-string-reply - */ - Mono auth(CharSequence password); - - /** - * Authenticate to the server with username and password. Requires Redis 6 or newer. - * - * @param username the username - * @param password the password - * @return String simple-string-reply - * @since 6.0 - */ - Mono auth(String username, CharSequence password); - /** * Change the selected database for the current connection. * diff --git a/src/main/java/io/lettuce/core/api/reactive/RedisServerReactiveCommands.java b/src/main/java/io/lettuce/core/api/reactive/RedisServerReactiveCommands.java index 240db6b689..91855ae1f7 100644 --- a/src/main/java/io/lettuce/core/api/reactive/RedisServerReactiveCommands.java +++ b/src/main/java/io/lettuce/core/api/reactive/RedisServerReactiveCommands.java @@ -21,10 +21,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import io.lettuce.core.FlushMode; -import io.lettuce.core.KillArgs; import io.lettuce.core.ShutdownArgs; -import io.lettuce.core.TrackingArgs; -import io.lettuce.core.UnblockType; import io.lettuce.core.protocol.CommandType; /** @@ -52,99 +49,6 @@ public interface RedisServerReactiveCommands { */ Mono bgsave(); - /** - * Control tracking of keys in the context of server-assisted client cache invalidation. - * - * @param enabled {@code true} to enable key tracking. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - Mono clientCaching(boolean enabled); - - /** - * Get the current connection name. - * - * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. - */ - Mono clientGetname(); - - /** - * Returns the client ID we are redirecting our tracking notifications to. - * - * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not - * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. - * @since 6.0 - */ - Mono clientGetredir(); - - /** - * Get the id of the current connection. - * - * @return Long The command just returns the ID of the current connection. - * @since 5.3 - */ - Mono clientId(); - - /** - * Kill the connection of a client identified by ip:port. - * - * @param addr ip:port. - * @return String simple-string-reply {@code OK} if the connection exists and has been closed. - */ - Mono clientKill(String addr); - - /** - * Kill connections of clients which are filtered by {@code killArgs}. - * - * @param killArgs args for the kill operation. - * @return Long integer-reply number of killed connections. - */ - Mono clientKill(KillArgs killArgs); - - /** - * Get the list of client connections. - * - * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), - * each line is composed of a succession of property=value fields separated by a space character. - */ - Mono clientList(); - - /** - * Stop processing commands from clients for some time. - * - * @param timeout the timeout value in milliseconds. - * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. - */ - Mono clientPause(long timeout); - - /** - * Set the current connection name. - * - * @param name the client name. - * @return simple-string-reply {@code OK} if the connection name was successfully set. - */ - Mono clientSetname(K name); - - /** - * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages - * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. - * - * @param args for the CLIENT TRACKING operation. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - Mono clientTracking(TrackingArgs args); - - /** - * Unblock the specified blocked client. - * - * @param id the client id. - * @param type unblock type. - * @return Long integer-reply number of unblocked connections. - * @since 5.1 - */ - Mono clientUnblock(long id, UnblockType type); - /** * Returns an array reply of details about all Redis commands. * @@ -421,6 +325,7 @@ public interface RedisServerReactiveCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaof(String, int)} instead. */ + @Deprecated Mono slaveof(String host, int port); /** @@ -429,6 +334,7 @@ public interface RedisServerReactiveCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaofNoOne()} instead. */ + @Deprecated Mono slaveofNoOne(); /** diff --git a/src/main/java/io/lettuce/core/api/sync/RedisCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisCommands.java index 26f219c75f..662800b490 100644 --- a/src/main/java/io/lettuce/core/api/sync/RedisCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/RedisCommands.java @@ -26,28 +26,11 @@ * @author Mark Paluch * @since 3.0 */ -public interface RedisCommands extends BaseRedisCommands, RedisAclCommands, RedisClusterCommands, RedisGeoCommands, - RedisHashCommands, RedisHLLCommands, RedisKeyCommands, RedisListCommands, - RedisScriptingCommands, RedisServerCommands, RedisSetCommands, RedisSortedSetCommands, - RedisStreamCommands, RedisStringCommands, RedisTransactionalCommands { - - /** - * Authenticate to the server. - * - * @param password the password - * @return String simple-string-reply - */ - String auth(CharSequence password); - - /** - * Authenticate to the server with username and password. Requires Redis 6 or newer. - * - * @param username the username - * @param password the password - * @return String simple-string-reply - * @since 6.0 - */ - String auth(String username, CharSequence password); +public interface RedisCommands + extends BaseRedisCommands, RedisAclCommands, RedisClusterCommands, RedisConnectionCommands, + RedisGeoCommands, RedisHashCommands, RedisHLLCommands, RedisKeyCommands, + RedisListCommands, RedisScriptingCommands, RedisServerCommands, RedisSetCommands, + RedisSortedSetCommands, RedisStreamCommands, RedisStringCommands, RedisTransactionalCommands { /** * Change the selected database for the current Commands. diff --git a/src/main/java/io/lettuce/core/api/sync/RedisConnectionCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisConnectionCommands.java new file mode 100644 index 0000000000..4ceec05ded --- /dev/null +++ b/src/main/java/io/lettuce/core/api/sync/RedisConnectionCommands.java @@ -0,0 +1,191 @@ +/* + * Copyright 2017-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core.api.sync; + +import java.util.List; + +import io.lettuce.core.KillArgs; +import io.lettuce.core.TrackingArgs; +import io.lettuce.core.UnblockType; + +/** + * Synchronous executed commands for connection commands. + * + * @param Key type. + * @param Value type. + * @author Mark Paluch + * @since 7.0 + * @generated by io.lettuce.apigenerator.CreateSyncApi + */ +public interface RedisConnectionCommands { + + /** + * Authenticate to the server. + * + * @param password the password + * @return String simple-string-reply + */ + String auth(CharSequence password); + + /** + * Authenticate to the server with username and password. Requires Redis 6 or newer. + * + * @param username the username + * @param password the password + * @return String simple-string-reply + * @since 6.0 + */ + String auth(String username, CharSequence password); + + /** + * Control tracking of keys in the context of server-assisted client cache invalidation. + * + * @param enabled {@code true} to enable key tracking. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + String clientCaching(boolean enabled); + + /** + * Get the current connection name. + * + * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. + */ + K clientGetname(); + + /** + * Returns the client ID we are redirecting our tracking notifications to. + * + * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not + * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. + * @since 6.0 + */ + Long clientGetredir(); + + /** + * Get the id of the current connection. + * + * @return Long The command just returns the ID of the current connection. + * @since 5.3 + */ + Long clientId(); + + /** + * Kill the connection of a client identified by ip:port. + * + * @param addr ip:port. + * @return String simple-string-reply {@code OK} if the connection exists and has been closed. + */ + String clientKill(String addr); + + /** + * Kill connections of clients which are filtered by {@code killArgs}. + * + * @param killArgs args for the kill operation. + * @return Long integer-reply number of killed connections. + */ + Long clientKill(KillArgs killArgs); + + /** + * Get the list of client connections. + * + * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), + * each line is composed of a succession of property=value fields separated by a space character. + */ + String clientList(); + + /** + * Stop processing commands from clients for some time. + * + * @param timeout the timeout value in milliseconds. + * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. + */ + String clientPause(long timeout); + + /** + * Set the current connection name. + * + * @param name the client name. + * @return simple-string-reply {@code OK} if the connection name was successfully set. + */ + String clientSetname(K name); + + /** + * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages + * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. + * + * @param args for the CLIENT TRACKING operation. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + String clientTracking(TrackingArgs args); + + /** + * Unblock the specified blocked client. + * + * @param id the client id. + * @param type unblock type. + * @return Long integer-reply number of unblocked connections. + * @since 5.1 + */ + Long clientUnblock(long id, UnblockType type); + + /** + * Echo the given string. + * + * @param msg the message type: value. + * @return V bulk-string-reply. + */ + V echo(V msg); + + /** + * Return the role of the instance in the context of replication. + * + * @return List<Object> array-reply where the first element is one of master, slave, sentinel and the additional + * elements are role-specific. + */ + List role(); + + /** + * Ping the server. + * + * @return String simple-string-reply. + */ + String ping(); + + /** + * Switch connection to Read-Only mode when connecting to a cluster. + * + * @return String simple-string-reply. + */ + String readOnly(); + + /** + * Switch connection to Read-Write mode (default) when connecting to a cluster. + * + * @return String simple-string-reply. + */ + String readWrite(); + + /** + * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if + * the connection was disconnected. Use {@link io.lettuce.core.api.StatefulConnection#close} to close connections and + * release resources. + * + * @return String simple-string-reply always OK. + */ + String quit(); +} diff --git a/src/main/java/io/lettuce/core/api/sync/RedisServerCommands.java b/src/main/java/io/lettuce/core/api/sync/RedisServerCommands.java index 8a5f8e1006..41907c7970 100644 --- a/src/main/java/io/lettuce/core/api/sync/RedisServerCommands.java +++ b/src/main/java/io/lettuce/core/api/sync/RedisServerCommands.java @@ -20,10 +20,7 @@ import java.util.Map; import io.lettuce.core.FlushMode; -import io.lettuce.core.KillArgs; import io.lettuce.core.ShutdownArgs; -import io.lettuce.core.TrackingArgs; -import io.lettuce.core.UnblockType; import io.lettuce.core.protocol.CommandType; /** @@ -51,99 +48,6 @@ public interface RedisServerCommands { */ String bgsave(); - /** - * Control tracking of keys in the context of server-assisted client cache invalidation. - * - * @param enabled {@code true} to enable key tracking. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - String clientCaching(boolean enabled); - - /** - * Get the current connection name. - * - * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. - */ - K clientGetname(); - - /** - * Returns the client ID we are redirecting our tracking notifications to. - * - * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not - * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. - * @since 6.0 - */ - Long clientGetredir(); - - /** - * Get the id of the current connection. - * - * @return Long The command just returns the ID of the current connection. - * @since 5.3 - */ - Long clientId(); - - /** - * Kill the connection of a client identified by ip:port. - * - * @param addr ip:port. - * @return String simple-string-reply {@code OK} if the connection exists and has been closed. - */ - String clientKill(String addr); - - /** - * Kill connections of clients which are filtered by {@code killArgs}. - * - * @param killArgs args for the kill operation. - * @return Long integer-reply number of killed connections. - */ - Long clientKill(KillArgs killArgs); - - /** - * Get the list of client connections. - * - * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), - * each line is composed of a succession of property=value fields separated by a space character. - */ - String clientList(); - - /** - * Stop processing commands from clients for some time. - * - * @param timeout the timeout value in milliseconds. - * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. - */ - String clientPause(long timeout); - - /** - * Set the current connection name. - * - * @param name the client name. - * @return simple-string-reply {@code OK} if the connection name was successfully set. - */ - String clientSetname(K name); - - /** - * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages - * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. - * - * @param args for the CLIENT TRACKING operation. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - String clientTracking(TrackingArgs args); - - /** - * Unblock the specified blocked client. - * - * @param id the client id. - * @param type unblock type. - * @return Long integer-reply number of unblocked connections. - * @since 5.1 - */ - Long clientUnblock(long id, UnblockType type); - /** * Returns an array reply of details about all Redis commands. * @@ -420,6 +324,7 @@ public interface RedisServerCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaof(String, int)} instead. */ + @Deprecated String slaveof(String host, int port); /** @@ -428,6 +333,7 @@ public interface RedisServerCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaofNoOne()} instead. */ + @Deprecated String slaveofNoOne(); /** diff --git a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionAsyncCommands.java index 62f2edee10..a95c47a345 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionAsyncCommands.java @@ -24,7 +24,8 @@ * @author Mark Paluch */ public interface NodeSelectionAsyncCommands - extends BaseNodeSelectionAsyncCommands, NodeSelectionGeoAsyncCommands, NodeSelectionHashAsyncCommands, + extends BaseNodeSelectionAsyncCommands, NodeSelectionGeoAsyncCommands, + NodeSelectionConnectionAsyncCommands, NodeSelectionHashAsyncCommands, NodeSelectionHLLAsyncCommands, NodeSelectionKeyAsyncCommands, NodeSelectionListAsyncCommands, NodeSelectionScriptingAsyncCommands, NodeSelectionServerAsyncCommands, NodeSelectionSetAsyncCommands, NodeSelectionSortedSetAsyncCommands, NodeSelectionStreamCommands, NodeSelectionStringAsyncCommands { diff --git a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionConnectionAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionConnectionAsyncCommands.java new file mode 100644 index 0000000000..b400c7580c --- /dev/null +++ b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionConnectionAsyncCommands.java @@ -0,0 +1,160 @@ +/* + * Copyright 2017-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core.cluster.api.async; + +import java.util.List; + +import io.lettuce.core.KillArgs; +import io.lettuce.core.TrackingArgs; +import io.lettuce.core.UnblockType; + +/** + * Asynchronous executed commands on a node selection for connection commands. + * + * @param Key type. + * @param Value type. + * @author Mark Paluch + * @since 7.0 + * @generated by io.lettuce.apigenerator.CreateAsyncNodeSelectionClusterApi + */ +public interface NodeSelectionConnectionAsyncCommands { + + /** + * Control tracking of keys in the context of server-assisted client cache invalidation. + * + * @param enabled {@code true} to enable key tracking. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + AsyncExecutions clientCaching(boolean enabled); + + /** + * Get the current connection name. + * + * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. + */ + AsyncExecutions clientGetname(); + + /** + * Returns the client ID we are redirecting our tracking notifications to. + * + * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not + * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. + * @since 6.0 + */ + AsyncExecutions clientGetredir(); + + /** + * Get the id of the current connection. + * + * @return Long The command just returns the ID of the current connection. + * @since 5.3 + */ + AsyncExecutions clientId(); + + /** + * Kill the connection of a client identified by ip:port. + * + * @param addr ip:port. + * @return String simple-string-reply {@code OK} if the connection exists and has been closed. + */ + AsyncExecutions clientKill(String addr); + + /** + * Kill connections of clients which are filtered by {@code killArgs}. + * + * @param killArgs args for the kill operation. + * @return Long integer-reply number of killed connections. + */ + AsyncExecutions clientKill(KillArgs killArgs); + + /** + * Get the list of client connections. + * + * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), + * each line is composed of a succession of property=value fields separated by a space character. + */ + AsyncExecutions clientList(); + + /** + * Stop processing commands from clients for some time. + * + * @param timeout the timeout value in milliseconds. + * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. + */ + AsyncExecutions clientPause(long timeout); + + /** + * Set the current connection name. + * + * @param name the client name. + * @return simple-string-reply {@code OK} if the connection name was successfully set. + */ + AsyncExecutions clientSetname(K name); + + /** + * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages + * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. + * + * @param args for the CLIENT TRACKING operation. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + AsyncExecutions clientTracking(TrackingArgs args); + + /** + * Unblock the specified blocked client. + * + * @param id the client id. + * @param type unblock type. + * @return Long integer-reply number of unblocked connections. + * @since 5.1 + */ + AsyncExecutions clientUnblock(long id, UnblockType type); + + /** + * Echo the given string. + * + * @param msg the message type: value. + * @return V bulk-string-reply. + */ + AsyncExecutions echo(V msg); + + /** + * Return the role of the instance in the context of replication. + * + * @return List<Object> array-reply where the first element is one of master, slave, sentinel and the additional + * elements are role-specific. + */ + AsyncExecutions> role(); + + /** + * Ping the server. + * + * @return String simple-string-reply. + */ + AsyncExecutions ping(); + + /** + * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if + * the connection was disconnected. Use {@link io.lettuce.core.api.StatefulConnection#close} to close connections and + * release resources. + * + * @return String simple-string-reply always OK. + */ + AsyncExecutions quit(); + +} diff --git a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionServerAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionServerAsyncCommands.java index 0509772af8..d5ead9e131 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionServerAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/NodeSelectionServerAsyncCommands.java @@ -20,9 +20,6 @@ import java.util.Map; import io.lettuce.core.FlushMode; -import io.lettuce.core.KillArgs; -import io.lettuce.core.TrackingArgs; -import io.lettuce.core.UnblockType; import io.lettuce.core.protocol.CommandType; /** @@ -50,99 +47,6 @@ public interface NodeSelectionServerAsyncCommands { */ AsyncExecutions bgsave(); - /** - * Control tracking of keys in the context of server-assisted client cache invalidation. - * - * @param enabled {@code true} to enable key tracking. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - AsyncExecutions clientCaching(boolean enabled); - - /** - * Get the current connection name. - * - * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. - */ - AsyncExecutions clientGetname(); - - /** - * Returns the client ID we are redirecting our tracking notifications to. - * - * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not - * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. - * @since 6.0 - */ - AsyncExecutions clientGetredir(); - - /** - * Get the id of the current connection. - * - * @return Long The command just returns the ID of the current connection. - * @since 5.3 - */ - AsyncExecutions clientId(); - - /** - * Kill the connection of a client identified by ip:port. - * - * @param addr ip:port. - * @return String simple-string-reply {@code OK} if the connection exists and has been closed. - */ - AsyncExecutions clientKill(String addr); - - /** - * Kill connections of clients which are filtered by {@code killArgs}. - * - * @param killArgs args for the kill operation. - * @return Long integer-reply number of killed connections. - */ - AsyncExecutions clientKill(KillArgs killArgs); - - /** - * Get the list of client connections. - * - * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), - * each line is composed of a succession of property=value fields separated by a space character. - */ - AsyncExecutions clientList(); - - /** - * Stop processing commands from clients for some time. - * - * @param timeout the timeout value in milliseconds. - * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. - */ - AsyncExecutions clientPause(long timeout); - - /** - * Set the current connection name. - * - * @param name the client name. - * @return simple-string-reply {@code OK} if the connection name was successfully set. - */ - AsyncExecutions clientSetname(K name); - - /** - * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages - * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. - * - * @param args for the CLIENT TRACKING operation. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - AsyncExecutions clientTracking(TrackingArgs args); - - /** - * Unblock the specified blocked client. - * - * @param id the client id. - * @param type unblock type. - * @return Long integer-reply number of unblocked connections. - * @since 5.1 - */ - AsyncExecutions clientUnblock(long id, UnblockType type); - /** * Returns an array reply of details about all Redis commands. * @@ -390,6 +294,7 @@ public interface NodeSelectionServerAsyncCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaof(String, int)} instead. */ + @Deprecated AsyncExecutions slaveof(String host, int port); /** @@ -398,6 +303,7 @@ public interface NodeSelectionServerAsyncCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaofNoOne()} instead. */ + @Deprecated AsyncExecutions slaveofNoOne(); /** diff --git a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java index 418fae1572..175745f2c1 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java @@ -32,8 +32,9 @@ * @author dengliming * @since 4.0 */ -public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands, RedisAclAsyncCommands, RedisGeoAsyncCommands, - RedisHashAsyncCommands, RedisHLLAsyncCommands, RedisKeyAsyncCommands, RedisListAsyncCommands, +public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands, RedisAclAsyncCommands, + RedisConnectionAsyncCommands, RedisGeoAsyncCommands, RedisHashAsyncCommands, + RedisHLLAsyncCommands, RedisKeyAsyncCommands, RedisListAsyncCommands, RedisScriptingAsyncCommands, RedisServerAsyncCommands, RedisSetAsyncCommands, RedisSortedSetAsyncCommands, RedisStreamAsyncCommands, RedisStringAsyncCommands { diff --git a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java index 69f0a537c0..06e893dbb8 100644 --- a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java @@ -33,11 +33,11 @@ * @since 5.0 */ public interface RedisClusterReactiveCommands - extends BaseRedisReactiveCommands, RedisAclReactiveCommands, RedisGeoReactiveCommands, - RedisHashReactiveCommands, RedisHLLReactiveCommands, RedisKeyReactiveCommands, - RedisListReactiveCommands, RedisScriptingReactiveCommands, RedisServerReactiveCommands, - RedisSetReactiveCommands, RedisSortedSetReactiveCommands, RedisStreamReactiveCommands, - RedisStringReactiveCommands { + extends BaseRedisReactiveCommands, RedisAclReactiveCommands, RedisConnectionReactiveCommands, + RedisGeoReactiveCommands, RedisHashReactiveCommands, RedisHLLReactiveCommands, + RedisKeyReactiveCommands, RedisListReactiveCommands, RedisScriptingReactiveCommands, + RedisServerReactiveCommands, RedisSetReactiveCommands, RedisSortedSetReactiveCommands, + RedisStreamReactiveCommands, RedisStringReactiveCommands { /** * The asking command is required after a {@code -ASK} redirection. The client should issue {@code ASKING} before to @@ -47,24 +47,6 @@ public interface RedisClusterReactiveCommands */ Mono asking(); - /** - * Authenticate to the server. - * - * @param password the password - * @return String simple-string-reply - */ - Mono auth(CharSequence password); - - /** - * Authenticate to the server with username and password. Requires Redis 6 or newer. - * - * @param username the username - * @param password the password - * @return String simple-string-reply - * @since 6.0 - */ - Mono auth(String username, CharSequence password); - /** * Adds slots to the cluster node. The current node will become the master for the specified slots. * diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionCommands.java index 2783d7fd1b..274508efb6 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionCommands.java @@ -23,7 +23,8 @@ * @author Mark Paluch */ public interface NodeSelectionCommands - extends BaseNodeSelectionCommands, NodeSelectionGeoCommands, NodeSelectionHashCommands, + extends BaseNodeSelectionCommands, NodeSelectionConnectionCommands, NodeSelectionGeoCommands, + NodeSelectionHashCommands, NodeSelectionHLLCommands, NodeSelectionKeyCommands, NodeSelectionListCommands, NodeSelectionScriptingCommands, NodeSelectionServerCommands, NodeSelectionSetCommands, NodeSelectionSortedSetCommands, NodeSelectionStreamCommands, NodeSelectionStringCommands { diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionConnectionCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionConnectionCommands.java new file mode 100644 index 0000000000..f1e8bacfd8 --- /dev/null +++ b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionConnectionCommands.java @@ -0,0 +1,160 @@ +/* + * Copyright 2017-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core.cluster.api.sync; + +import java.util.List; + +import io.lettuce.core.KillArgs; +import io.lettuce.core.TrackingArgs; +import io.lettuce.core.UnblockType; + +/** + * Synchronous executed commands on a node selection for connection commands. + * + * @param Key type. + * @param Value type. + * @author Mark Paluch + * @since 7.0 + * @generated by io.lettuce.apigenerator.CreateSyncNodeSelectionClusterApi + */ +public interface NodeSelectionConnectionCommands { + + /** + * Control tracking of keys in the context of server-assisted client cache invalidation. + * + * @param enabled {@code true} to enable key tracking. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + Executions clientCaching(boolean enabled); + + /** + * Get the current connection name. + * + * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. + */ + Executions clientGetname(); + + /** + * Returns the client ID we are redirecting our tracking notifications to. + * + * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not + * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. + * @since 6.0 + */ + Executions clientGetredir(); + + /** + * Get the id of the current connection. + * + * @return Long The command just returns the ID of the current connection. + * @since 5.3 + */ + Executions clientId(); + + /** + * Kill the connection of a client identified by ip:port. + * + * @param addr ip:port. + * @return String simple-string-reply {@code OK} if the connection exists and has been closed. + */ + Executions clientKill(String addr); + + /** + * Kill connections of clients which are filtered by {@code killArgs}. + * + * @param killArgs args for the kill operation. + * @return Long integer-reply number of killed connections. + */ + Executions clientKill(KillArgs killArgs); + + /** + * Get the list of client connections. + * + * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), + * each line is composed of a succession of property=value fields separated by a space character. + */ + Executions clientList(); + + /** + * Stop processing commands from clients for some time. + * + * @param timeout the timeout value in milliseconds. + * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. + */ + Executions clientPause(long timeout); + + /** + * Set the current connection name. + * + * @param name the client name. + * @return simple-string-reply {@code OK} if the connection name was successfully set. + */ + Executions clientSetname(K name); + + /** + * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages + * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. + * + * @param args for the CLIENT TRACKING operation. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + Executions clientTracking(TrackingArgs args); + + /** + * Unblock the specified blocked client. + * + * @param id the client id. + * @param type unblock type. + * @return Long integer-reply number of unblocked connections. + * @since 5.1 + */ + Executions clientUnblock(long id, UnblockType type); + + /** + * Echo the given string. + * + * @param msg the message type: value. + * @return V bulk-string-reply. + */ + Executions echo(V msg); + + /** + * Return the role of the instance in the context of replication. + * + * @return List<Object> array-reply where the first element is one of master, slave, sentinel and the additional + * elements are role-specific. + */ + Executions> role(); + + /** + * Ping the server. + * + * @return String simple-string-reply. + */ + Executions ping(); + + /** + * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if + * the connection was disconnected. Use {@link io.lettuce.core.api.StatefulConnection#close} to close connections and + * release resources. + * + * @return String simple-string-reply always OK. + */ + Executions quit(); + +} diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionServerCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionServerCommands.java index e60088dc1c..cc74dbfa63 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionServerCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/NodeSelectionServerCommands.java @@ -20,9 +20,6 @@ import java.util.Map; import io.lettuce.core.FlushMode; -import io.lettuce.core.KillArgs; -import io.lettuce.core.TrackingArgs; -import io.lettuce.core.UnblockType; import io.lettuce.core.protocol.CommandType; /** @@ -50,99 +47,6 @@ public interface NodeSelectionServerCommands { */ Executions bgsave(); - /** - * Control tracking of keys in the context of server-assisted client cache invalidation. - * - * @param enabled {@code true} to enable key tracking. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - Executions clientCaching(boolean enabled); - - /** - * Get the current connection name. - * - * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. - */ - Executions clientGetname(); - - /** - * Returns the client ID we are redirecting our tracking notifications to. - * - * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not - * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. - * @since 6.0 - */ - Executions clientGetredir(); - - /** - * Get the id of the current connection. - * - * @return Long The command just returns the ID of the current connection. - * @since 5.3 - */ - Executions clientId(); - - /** - * Kill the connection of a client identified by ip:port. - * - * @param addr ip:port. - * @return String simple-string-reply {@code OK} if the connection exists and has been closed. - */ - Executions clientKill(String addr); - - /** - * Kill connections of clients which are filtered by {@code killArgs}. - * - * @param killArgs args for the kill operation. - * @return Long integer-reply number of killed connections. - */ - Executions clientKill(KillArgs killArgs); - - /** - * Get the list of client connections. - * - * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), - * each line is composed of a succession of property=value fields separated by a space character. - */ - Executions clientList(); - - /** - * Stop processing commands from clients for some time. - * - * @param timeout the timeout value in milliseconds. - * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. - */ - Executions clientPause(long timeout); - - /** - * Set the current connection name. - * - * @param name the client name. - * @return simple-string-reply {@code OK} if the connection name was successfully set. - */ - Executions clientSetname(K name); - - /** - * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages - * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. - * - * @param args for the CLIENT TRACKING operation. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - Executions clientTracking(TrackingArgs args); - - /** - * Unblock the specified blocked client. - * - * @param id the client id. - * @param type unblock type. - * @return Long integer-reply number of unblocked connections. - * @since 5.1 - */ - Executions clientUnblock(long id, UnblockType type); - /** * Returns an array reply of details about all Redis commands. * @@ -390,6 +294,7 @@ public interface NodeSelectionServerCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaof(String, int)} instead. */ + @Deprecated Executions slaveof(String host, int port); /** @@ -398,6 +303,7 @@ public interface NodeSelectionServerCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use {@link #replicaofNoOne()} instead. */ + @Deprecated Executions slaveofNoOne(); /** diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java index 471ea9f19c..69e5b2c72d 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java @@ -29,12 +29,10 @@ * @author dengliming * @since 4.0 */ -public interface RedisClusterCommands - extends BaseRedisCommands, RedisAclCommands, RedisGeoCommands, - RedisHashCommands, RedisHLLCommands, RedisKeyCommands, - RedisListCommands, RedisScriptingCommands, RedisServerCommands, - RedisSetCommands, RedisSortedSetCommands, RedisStreamCommands, - RedisStringCommands { +public interface RedisClusterCommands extends BaseRedisCommands, RedisAclCommands, + RedisConnectionCommands, RedisGeoCommands, RedisHashCommands, RedisHLLCommands, + RedisKeyCommands, RedisListCommands, RedisScriptingCommands, RedisServerCommands, + RedisSetCommands, RedisSortedSetCommands, RedisStreamCommands, RedisStringCommands { /** * The asking command is required after a {@code -ASK} redirection. The client should issue {@code ASKING} before to @@ -44,24 +42,6 @@ public interface RedisClusterCommands */ String asking(); - /** - * Authenticate to the server. - * - * @param password the password - * @return String simple-string-reply - */ - String auth(CharSequence password); - - /** - * Authenticate to the server with username and password. Requires Redis 6 or newer. - * - * @param username the username - * @param password the password - * @return String simple-string-reply - * @since 6.0 - */ - String auth(String username, CharSequence password); - /** * Adds slots to the cluster node. The current node will become the master for the specified slots. * diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt index 1edb422858..9de5267f70 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommands.kt @@ -73,52 +73,6 @@ interface BaseRedisCoroutinesCommands { */ suspend fun pubsubNumpat(): Long - /** - * Echo the given string. - * - * @param msg the message type: value. - * @return V bulk-string-reply. - */ - suspend fun echo(msg: V): V - - /** - * Return the role of the instance in the context of replication. - * - * @return List array-reply where the first element is one of master, slave, sentinel and the additional - * elements are role-specific. - */ - suspend fun role(): List - - /** - * Ping the server. - * - * @return String simple-string-reply. - */ - suspend fun ping(): String - - /** - * Switch connection to Read-Only mode when connecting to a cluster. - * - * @return String simple-string-reply. - */ - suspend fun readOnly(): String - - /** - * Switch connection to Read-Write mode (default) when connecting to a cluster. - * - * @return String simple-string-reply. - */ - suspend fun readWrite(): String - - /** - * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if - * the connection was disconnected. Use [io.lettuce.core.api.StatefulConnection#close] to close connections and - * release resources. - * - * @return String simple-string-reply always OK. - */ - suspend fun quit(): String? - /** * Wait for replication. * diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt index f446b1e3d0..37582843ad 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/BaseRedisCoroutinesCommandsImpl.kt @@ -34,6 +34,7 @@ import kotlinx.coroutines.reactive.awaitSingle * @param Key type. * @param Value type. * @author Mikhael Sokolov + * @author Mark Paluch * @since 6.0 */ @ExperimentalLettuceCoroutinesApi @@ -49,18 +50,6 @@ internal class BaseRedisCoroutinesCommandsImpl(internal val op override suspend fun pubsubNumpat(): Long = ops.pubsubNumpat().awaitSingle() - override suspend fun echo(msg: V): V = ops.echo(msg).awaitSingle() - - override suspend fun role(): List = ops.role().asFlow().toList() - - override suspend fun ping(): String = ops.ping().awaitSingle() - - override suspend fun readOnly(): String = ops.readOnly().awaitSingle() - - override suspend fun readWrite(): String = ops.readWrite().awaitSingle() - - override suspend fun quit(): String? = ops.quit().awaitFirstOrNull() - override suspend fun waitForReplication(replicas: Int, timeout: Long): Long? = ops.waitForReplication(replicas, timeout).awaitFirstOrNull() override fun dispatch(type: ProtocolKeyword, output: CommandOutput): Flow = ops.dispatch(type, output).asFlow() diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommands.kt new file mode 100644 index 0000000000..62aabfdb5c --- /dev/null +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommands.kt @@ -0,0 +1,194 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core.api.coroutines + +import io.lettuce.core.ExperimentalLettuceCoroutinesApi +import io.lettuce.core.KillArgs +import io.lettuce.core.TrackingArgs +import io.lettuce.core.UnblockType + +/** + * Coroutine executed commands for connection commands. + * + * @param Key type. + * @param Value type. + * @author Mark Paluch + * @since 7.0 + * @generated by io.lettuce.apigenerator.CreateKotlinCoroutinesApi + */ +@ExperimentalLettuceCoroutinesApi +interface RedisConnectionCoroutinesCommands { + + /** + * Authenticate to the server. + * + * @param password the password + * @return String simple-string-reply + */ + suspend fun auth(password: CharSequence): String? + + /** + * Authenticate to the server with username and password. Requires Redis 6 or newer. + * + * @param username the username + * @param password the password + * @return String simple-string-reply + * @since 6.0 + */ + suspend fun auth(username: String, password: CharSequence): String? + + /** + * Control tracking of keys in the context of server-assisted client cache invalidation. + * + * @param enabled @code true} to enable key tracking. + * @return String simple-string-reply `OK`. + * @since 6.0 + */ + suspend fun clientCaching(enabled: Boolean): String? + + /** + * Get the current connection name. + * + * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. + */ + suspend fun clientGetname(): K? + + /** + * Returns the client ID we are redirecting our tracking notifications to. + * + * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not + * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. + * @since 6.0 + */ + suspend fun clientGetredir(): Long? + + /** + * Get the id of the current connection. + * + * @return Long The command just returns the ID of the current connection. + * @since 5.3 + */ + suspend fun clientId(): Long? + + /** + * Kill the connection of a client identified by ip:port. + * + * @param addr ip:port. + * @return String simple-string-reply `OK` if the connection exists and has been closed. + */ + suspend fun clientKill(addr: String): String? + + /** + * Kill connections of clients which are filtered by `killArgs`. + * + * @param killArgs args for the kill operation. + * @return Long integer-reply number of killed connections. + */ + suspend fun clientKill(killArgs: KillArgs): Long? + + /** + * Get the list of client connections. + * + * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), + * each line is composed of a succession of property=value fields separated by a space character. + */ + suspend fun clientList(): String? + + /** + * Stop processing commands from clients for some time. + * + * @param timeout the timeout value in milliseconds. + * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. + */ + suspend fun clientPause(timeout: Long): String? + + /** + * Set the current connection name. + * + * @param name the client name. + * @return simple-string-reply `OK` if the connection name was successfully set. + */ + suspend fun clientSetname(name: K): String? + + /** + * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages + * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. + * + * @param args for the CLIENT TRACKING operation. + * @return String simple-string-reply `OK`. + * @since 6.0 + */ + suspend fun clientTracking(args: TrackingArgs): String? + + /** + * Unblock the specified blocked client. + * + * @param id the client id. + * @param type unblock type. + * @return Long integer-reply number of unblocked connections. + * @since 5.1 + */ + suspend fun clientUnblock(id: Long, type: UnblockType): Long? + + /** + * Echo the given string. + * + * @param msg the message type: value. + * @return V bulk-string-reply. + */ + suspend fun echo(msg: V): V + + /** + * Return the role of the instance in the context of replication. + * + * @return List array-reply where the first element is one of master, slave, sentinel and the additional + * elements are role-specific. + */ + suspend fun role(): List + + /** + * Ping the server. + * + * @return String simple-string-reply. + */ + suspend fun ping(): String + + /** + * Switch connection to Read-Only mode when connecting to a cluster. + * + * @return String simple-string-reply. + */ + suspend fun readOnly(): String + + /** + * Switch connection to Read-Write mode (default) when connecting to a cluster. + * + * @return String simple-string-reply. + */ + suspend fun readWrite(): String + + /** + * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if + * the connection was disconnected. Use [io.lettuce.core.api.StatefulConnection#close] to close connections and + * release resources. + * + * @return String simple-string-reply always OK. + */ + suspend fun quit(): String? + +} + diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommandsImpl.kt new file mode 100644 index 0000000000..89b3309a2d --- /dev/null +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisConnectionCoroutinesCommandsImpl.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2020-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core.api.coroutines + +import io.lettuce.core.ExperimentalLettuceCoroutinesApi +import io.lettuce.core.KillArgs +import io.lettuce.core.TrackingArgs +import io.lettuce.core.UnblockType +import io.lettuce.core.api.reactive.RedisConnectionReactiveCommands +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.reactive.asFlow +import kotlinx.coroutines.reactive.awaitFirstOrNull +import kotlinx.coroutines.reactive.awaitSingle + + +/** + * Coroutine executed commands (based on reactive commands) for basic commands. + * + * @param Key type. + * @param Value type. + * @author Mikhael Sokolov + * @author Mark Paluch + * @since 6.0 + */ +@ExperimentalLettuceCoroutinesApi +internal class RedisConnectionCoroutinesCommandsImpl(internal val ops: RedisConnectionReactiveCommands) : RedisConnectionCoroutinesCommands { + + override suspend fun auth(password: CharSequence): String? = ops.auth(password).awaitFirstOrNull() + + override suspend fun auth(username: String, password: CharSequence): String? = ops.auth(username, password).awaitFirstOrNull() + + override suspend fun clientCaching(enabled: Boolean): String? = ops.clientCaching(enabled).awaitFirstOrNull() + + override suspend fun clientGetname(): K? = ops.clientGetname().awaitFirstOrNull() + + override suspend fun clientGetredir(): Long? = ops.clientGetredir().awaitFirstOrNull() + + override suspend fun clientId(): Long? = ops.clientId().awaitFirstOrNull() + + override suspend fun clientKill(addr: String): String? = ops.clientKill(addr).awaitFirstOrNull() + + override suspend fun clientKill(killArgs: KillArgs): Long? = ops.clientKill(killArgs).awaitFirstOrNull() + + override suspend fun clientList(): String? = ops.clientList().awaitFirstOrNull() + + override suspend fun clientPause(timeout: Long): String? = ops.clientPause(timeout).awaitFirstOrNull() + + override suspend fun clientSetname(name: K): String? = ops.clientSetname(name).awaitFirstOrNull() + + override suspend fun clientTracking(args: TrackingArgs): String? = ops.clientTracking(args).awaitFirstOrNull() + + override suspend fun clientUnblock(id: Long, type: UnblockType): Long? = ops.clientUnblock(id, type).awaitFirstOrNull() + + override suspend fun echo(msg: V): V = ops.echo(msg).awaitSingle() + + override suspend fun role(): List = ops.role().asFlow().toList() + + override suspend fun ping(): String = ops.ping().awaitSingle() + + override suspend fun readOnly(): String = ops.readOnly().awaitSingle() + + override suspend fun readWrite(): String = ops.readWrite().awaitSingle() + + override suspend fun quit(): String? = ops.quit().awaitFirstOrNull() + +} diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisCoroutinesCommandsImpl.kt index 4b3e444fe7..c738190ef0 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisCoroutinesCommandsImpl.kt @@ -37,6 +37,7 @@ open class RedisCoroutinesCommandsImpl( ) : RedisCoroutinesCommands, RedisClusterCoroutinesCommands, BaseRedisCoroutinesCommands by BaseRedisCoroutinesCommandsImpl(ops), RedisAclCoroutinesCommands by RedisAclCoroutinesCommandsImpl(ops), + RedisConnectionCoroutinesCommands by RedisConnectionCoroutinesCommandsImpl(ops), RedisGeoCoroutinesCommands by RedisGeoCoroutinesCommandsImpl(ops), RedisHashCoroutinesCommands by RedisHashCoroutinesCommandsImpl(ops), RedisHLLCoroutinesCommands by RedisHLLCoroutinesCommandsImpl(ops), @@ -50,24 +51,6 @@ open class RedisCoroutinesCommandsImpl( RedisStringCoroutinesCommands by RedisStringCoroutinesCommandsImpl(ops), RedisTransactionalCoroutinesCommands by RedisTransactionalCoroutinesCommandsImpl(ops) { - /** - * Authenticate to the server. - * - * @param password the password - * @return String simple-string-reply - */ - override suspend fun auth(password: CharSequence): String? = ops.auth(password).awaitFirstOrNull() - - /** - * Authenticate to the server with username and password. Requires Redis 6 or newer. - * - * @param username the username - * @param password the password - * @return String simple-string-reply - * @since 6.0 - */ - override suspend fun auth(username: String, password: CharSequence): String? = ops.auth(username, password).awaitFirstOrNull() - /** * Change the selected database for the current connection. * diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommands.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommands.kt index 77d29e49a5..ee48353a9b 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommands.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommands.kt @@ -16,7 +16,9 @@ package io.lettuce.core.api.coroutines -import io.lettuce.core.* +import io.lettuce.core.ExperimentalLettuceCoroutinesApi +import io.lettuce.core.FlushMode +import io.lettuce.core.ShutdownArgs import io.lettuce.core.protocol.CommandType import java.util.* @@ -46,99 +48,6 @@ interface RedisServerCoroutinesCommands { */ suspend fun bgsave(): String? - /** - * Control tracking of keys in the context of server-assisted client cache invalidation. - * - * @param enabled @code true} to enable key tracking. - * @return String simple-string-reply `OK`. - * @since 6.0 - */ - suspend fun clientCaching(enabled: Boolean): String? - - /** - * Get the current connection name. - * - * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. - */ - suspend fun clientGetname(): K? - - /** - * Returns the client ID we are redirecting our tracking notifications to. - * - * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not - * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. - * @since 6.0 - */ - suspend fun clientGetredir(): Long? - - /** - * Get the id of the current connection. - * - * @return Long The command just returns the ID of the current connection. - * @since 5.3 - */ - suspend fun clientId(): Long? - - /** - * Kill the connection of a client identified by ip:port. - * - * @param addr ip:port. - * @return String simple-string-reply `OK` if the connection exists and has been closed. - */ - suspend fun clientKill(addr: String): String? - - /** - * Kill connections of clients which are filtered by `killArgs`. - * - * @param killArgs args for the kill operation. - * @return Long integer-reply number of killed connections. - */ - suspend fun clientKill(killArgs: KillArgs): Long? - - /** - * Get the list of client connections. - * - * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), - * each line is composed of a succession of property=value fields separated by a space character. - */ - suspend fun clientList(): String? - - /** - * Stop processing commands from clients for some time. - * - * @param timeout the timeout value in milliseconds. - * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. - */ - suspend fun clientPause(timeout: Long): String? - - /** - * Set the current connection name. - * - * @param name the client name. - * @return simple-string-reply `OK` if the connection name was successfully set. - */ - suspend fun clientSetname(name: K): String? - - /** - * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages - * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. - * - * @param args for the CLIENT TRACKING operation. - * @return String simple-string-reply `OK`. - * @since 6.0 - */ - suspend fun clientTracking(args: TrackingArgs): String? - - /** - * Unblock the specified blocked client. - * - * @param id the client id. - * @param type unblock type. - * @return Long integer-reply number of unblocked connections. - * @since 5.1 - */ - suspend fun clientUnblock(id: Long, type: UnblockType): Long? - /** * Returns an array reply of details about all Redis commands. * @@ -394,17 +303,18 @@ interface RedisServerCoroutinesCommands { /** * Synchronously save the dataset to disk and then shut down the server. - * - * @param save @code true} force save operation. - */ - suspend fun shutdown(save: Boolean) + * + * @param save @code true} force save operation. + */ + suspend fun shutdown(save: Boolean) - /** - * Synchronously save the dataset to disk and then shutdown the server. - * - * @param args - */ - suspend fun shutdown(args: ShutdownArgs) + /** + * Synchronously save the dataset to disk and then shutdown the server. + * + * @param args + * @since 6.2 + */ + suspend fun shutdown(args: ShutdownArgs) /** * Make the server a replica of another instance. @@ -414,6 +324,7 @@ interface RedisServerCoroutinesCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use [replicaof(String, Integer)] instead. */ + @Deprecated(message = "since 6.1.7", replaceWith = ReplaceWith("replicaof(host, port)")) suspend fun slaveof(host: String, port: Int): String? /** @@ -422,6 +333,7 @@ interface RedisServerCoroutinesCommands { * @return String simple-string-reply. * @deprecated since 6.1.7, use [replicaofNoOne] instead. */ + @Deprecated(message = "since 6.1.7", replaceWith = ReplaceWith("replicaofNoOne()")) suspend fun slaveofNoOne(): String? /** @@ -431,15 +343,15 @@ interface RedisServerCoroutinesCommands { */ suspend fun slowlogGet(): List - /** - * Read the slow log. - * - * @param count the count. - * @return List deeply nested multi bulk replies. - */ - suspend fun slowlogGet(count: Int): List + /** + * Read the slow log. + * + * @param count the count. + * @return List deeply nested multi bulk replies. + */ + suspend fun slowlogGet(count: Int): List - /** + /** * Obtaining the current length of the slow log. * * @return Long length of the slow log. diff --git a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommandsImpl.kt b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommandsImpl.kt index ab35a37bf2..61ca9b2b0f 100644 --- a/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommandsImpl.kt +++ b/src/main/kotlin/io/lettuce/core/api/coroutines/RedisServerCoroutinesCommandsImpl.kt @@ -16,7 +16,9 @@ package io.lettuce.core.api.coroutines -import io.lettuce.core.* +import io.lettuce.core.ExperimentalLettuceCoroutinesApi +import io.lettuce.core.FlushMode +import io.lettuce.core.ShutdownArgs import io.lettuce.core.api.reactive.RedisServerReactiveCommands import io.lettuce.core.protocol.CommandType import kotlinx.coroutines.flow.toList @@ -42,28 +44,6 @@ internal class RedisServerCoroutinesCommandsImpl(internal val override suspend fun bgsave(): String? = ops.bgsave().awaitFirstOrNull() - override suspend fun clientCaching(enabled: Boolean): String? = ops.clientCaching(enabled).awaitFirstOrNull() - - override suspend fun clientGetname(): K? = ops.clientGetname().awaitFirstOrNull() - - override suspend fun clientGetredir(): Long? = ops.clientGetredir().awaitFirstOrNull() - - override suspend fun clientId(): Long? = ops.clientId().awaitFirstOrNull() - - override suspend fun clientKill(addr: String): String? = ops.clientKill(addr).awaitFirstOrNull() - - override suspend fun clientKill(killArgs: KillArgs): Long? = ops.clientKill(killArgs).awaitFirstOrNull() - - override suspend fun clientList(): String? = ops.clientList().awaitFirstOrNull() - - override suspend fun clientPause(timeout: Long): String? = ops.clientPause(timeout).awaitFirstOrNull() - - override suspend fun clientSetname(name: K): String? = ops.clientSetname(name).awaitFirstOrNull() - - override suspend fun clientTracking(args: TrackingArgs): String? = ops.clientTracking(args).awaitFirstOrNull() - - override suspend fun clientUnblock(id: Long, type: UnblockType): Long? = ops.clientUnblock(id, type).awaitFirstOrNull() - override suspend fun command(): List = ops.command().asFlow().toList() override suspend fun commandCount(): Long? = ops.commandCount().awaitFirstOrNull() diff --git a/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java b/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java index aadc45bdd8..606aa39ac3 100644 --- a/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java +++ b/src/main/templates/io/lettuce/core/api/BaseRedisCommands.java @@ -71,52 +71,6 @@ public interface BaseRedisCommands { */ Long pubsubNumpat(); - /** - * Echo the given string. - * - * @param msg the message type: value. - * @return V bulk-string-reply. - */ - V echo(V msg); - - /** - * Return the role of the instance in the context of replication. - * - * @return List<Object> array-reply where the first element is one of master, slave, sentinel and the additional - * elements are role-specific. - */ - List role(); - - /** - * Ping the server. - * - * @return String simple-string-reply. - */ - String ping(); - - /** - * Switch connection to Read-Only mode when connecting to a cluster. - * - * @return String simple-string-reply. - */ - String readOnly(); - - /** - * Switch connection to Read-Write mode (default) when connecting to a cluster. - * - * @return String simple-string-reply. - */ - String readWrite(); - - /** - * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if - * the connection was disconnected. Use {@link io.lettuce.core.api.StatefulConnection#close} to close connections and - * release resources. - * - * @return String simple-string-reply always OK. - */ - String quit(); - /** * Wait for replication. * diff --git a/src/main/templates/io/lettuce/core/api/RedisConnectionCommands.java b/src/main/templates/io/lettuce/core/api/RedisConnectionCommands.java new file mode 100644 index 0000000000..41ce04c0d7 --- /dev/null +++ b/src/main/templates/io/lettuce/core/api/RedisConnectionCommands.java @@ -0,0 +1,191 @@ +/* + * Copyright 2017-2022 the original author or authors. + * + * Licensed 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 + * + * https://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 io.lettuce.core; + +import java.util.List; +import java.util.List; +import io.lettuce.core.KillArgs; +import io.lettuce.core.TrackingArgs; +import io.lettuce.core.UnblockType; + +/** + * ${intent} for connection commands. + * + * @param Key type. + * @param Value type. + * @author Mark Paluch + * @since 7.0 + */ +public interface RedisConnectionCommands { + + /** + * Authenticate to the server. + * + * @param password the password + * @return String simple-string-reply + */ + String auth(CharSequence password); + + /** + * Authenticate to the server with username and password. Requires Redis 6 or newer. + * + * @param username the username + * @param password the password + * @return String simple-string-reply + * @since 6.0 + */ + String auth(String username, CharSequence password); + + /** + * Control tracking of keys in the context of server-assisted client cache invalidation. + * + * @param enabled {@code true} to enable key tracking. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + String clientCaching(boolean enabled); + + /** + * Get the current connection name. + * + * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. + */ + K clientGetname(); + + /** + * Returns the client ID we are redirecting our tracking notifications to. + * + * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not + * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. + * @since 6.0 + */ + Long clientGetredir(); + + /** + * Get the id of the current connection. + * + * @return Long The command just returns the ID of the current connection. + * @since 5.3 + */ + Long clientId(); + + /** + * Kill the connection of a client identified by ip:port. + * + * @param addr ip:port. + * @return String simple-string-reply {@code OK} if the connection exists and has been closed. + */ + String clientKill(String addr); + + /** + * Kill connections of clients which are filtered by {@code killArgs}. + * + * @param killArgs args for the kill operation. + * @return Long integer-reply number of killed connections. + */ + Long clientKill(KillArgs killArgs); + + /** + * Get the list of client connections. + * + * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), + * each line is composed of a succession of property=value fields separated by a space character. + */ + String clientList(); + + /** + * Stop processing commands from clients for some time. + * + * @param timeout the timeout value in milliseconds. + * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. + */ + String clientPause(long timeout); + + /** + * Set the current connection name. + * + * @param name the client name. + * @return simple-string-reply {@code OK} if the connection name was successfully set. + */ + String clientSetname(K name); + + /** + * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages + * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. + * + * @param args for the CLIENT TRACKING operation. + * @return String simple-string-reply {@code OK}. + * @since 6.0 + */ + String clientTracking(TrackingArgs args); + + /** + * Unblock the specified blocked client. + * + * @param id the client id. + * @param type unblock type. + * @return Long integer-reply number of unblocked connections. + * @since 5.1 + */ + Long clientUnblock(long id, UnblockType type); + + /** + * Echo the given string. + * + * @param msg the message type: value. + * @return V bulk-string-reply. + */ + V echo(V msg); + + /** + * Return the role of the instance in the context of replication. + * + * @return List<Object> array-reply where the first element is one of master, slave, sentinel and the additional + * elements are role-specific. + */ + List role(); + + /** + * Ping the server. + * + * @return String simple-string-reply. + */ + String ping(); + + /** + * Switch connection to Read-Only mode when connecting to a cluster. + * + * @return String simple-string-reply. + */ + String readOnly(); + + /** + * Switch connection to Read-Write mode (default) when connecting to a cluster. + * + * @return String simple-string-reply. + */ + String readWrite(); + + /** + * Instructs Redis to disconnect the connection. Note that if auto-reconnect is enabled then Lettuce will auto-reconnect if + * the connection was disconnected. Use {@link io.lettuce.core.api.StatefulConnection#close} to close connections and + * release resources. + * + * @return String simple-string-reply always OK. + */ + String quit(); + +} diff --git a/src/main/templates/io/lettuce/core/api/RedisServerCommands.java b/src/main/templates/io/lettuce/core/api/RedisServerCommands.java index 8fb0e02843..7169b8ace0 100644 --- a/src/main/templates/io/lettuce/core/api/RedisServerCommands.java +++ b/src/main/templates/io/lettuce/core/api/RedisServerCommands.java @@ -49,99 +49,6 @@ public interface RedisServerCommands { */ String bgsave(); - /** - * Control tracking of keys in the context of server-assisted client cache invalidation. - * - * @param enabled {@code true} to enable key tracking. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - String clientCaching(boolean enabled); - - /** - * Get the current connection name. - * - * @return K bulk-string-reply The connection name, or a null bulk reply if no name is set. - */ - K clientGetname(); - - /** - * Returns the client ID we are redirecting our tracking notifications to. - * - * @return the ID of the client we are redirecting the notifications to. The command returns -1 if client tracking is not - * enabled, or 0 if client tracking is enabled but we are not redirecting the notifications to any client. - * @since 6.0 - */ - Long clientGetredir(); - - /** - * Get the id of the current connection. - * - * @return Long The command just returns the ID of the current connection. - * @since 5.3 - */ - Long clientId(); - - /** - * Kill the connection of a client identified by ip:port. - * - * @param addr ip:port. - * @return String simple-string-reply {@code OK} if the connection exists and has been closed. - */ - String clientKill(String addr); - - /** - * Kill connections of clients which are filtered by {@code killArgs}. - * - * @param killArgs args for the kill operation. - * @return Long integer-reply number of killed connections. - */ - Long clientKill(KillArgs killArgs); - - /** - * Get the list of client connections. - * - * @return String bulk-string-reply a unique string, formatted as follows: One client connection per line (separated by LF), - * each line is composed of a succession of property=value fields separated by a space character. - */ - String clientList(); - - /** - * Stop processing commands from clients for some time. - * - * @param timeout the timeout value in milliseconds. - * @return String simple-string-reply The command returns OK or an error if the timeout is invalid. - */ - String clientPause(long timeout); - - /** - * Set the current connection name. - * - * @param name the client name. - * @return simple-string-reply {@code OK} if the connection name was successfully set. - */ - String clientSetname(K name); - - /** - * Enables the tracking feature of the Redis server, that is used for server assisted client side caching. Tracking messages - * are either available when using the RESP3 protocol or through Pub/Sub notification when using RESP2. - * - * @param args for the CLIENT TRACKING operation. - * @return String simple-string-reply {@code OK}. - * @since 6.0 - */ - String clientTracking(TrackingArgs args); - - /** - * Unblock the specified blocked client. - * - * @param id the client id. - * @param type unblock type. - * @return Long integer-reply number of unblocked connections. - * @since 5.1 - */ - Long clientUnblock(long id, UnblockType type); - /** * Returns an array reply of details about all Redis commands. * diff --git a/src/test/java/io/lettuce/apigenerator/Constants.java b/src/test/java/io/lettuce/apigenerator/Constants.java index 38bb67cf9b..ceee758a23 100644 --- a/src/test/java/io/lettuce/apigenerator/Constants.java +++ b/src/test/java/io/lettuce/apigenerator/Constants.java @@ -25,6 +25,7 @@ class Constants { public static final String[] TEMPLATE_NAMES = { "BaseRedisCommands", "RedisAclCommands", + "RedisConnectionCommands", "RedisGeoCommands", "RedisHashCommands", "RedisHLLCommands", diff --git a/src/test/java/io/lettuce/apigenerator/CreateSyncNodeSelectionClusterApi.java b/src/test/java/io/lettuce/apigenerator/CreateSyncNodeSelectionClusterApi.java index 1332cc64df..5d9ca2f70f 100644 --- a/src/test/java/io/lettuce/apigenerator/CreateSyncNodeSelectionClusterApi.java +++ b/src/test/java/io/lettuce/apigenerator/CreateSyncNodeSelectionClusterApi.java @@ -44,7 +44,9 @@ public class CreateSyncNodeSelectionClusterApi { private static final Set FILTER_TEMPLATES = LettuceSets.unmodifiableSet("RedisSentinelCommands", "RedisTransactionalCommands"); - private static final Set FILTER_METHODS = LettuceSets.unmodifiableSet("shutdown", "debugOom", "debugSegfault", "digest", + + private static final Set FILTER_METHODS = LettuceSets.unmodifiableSet("auth", "shutdown", "debugOom", + "debugSegfault", "digest", "close", "isOpen", "BaseRedisCommands.reset", "readOnly", "readWrite", "dispatch", "setAutoFlushCommands", "flushCommands"); /** From 24558d1237189919516a173982ef8803268d6192 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 1 Mar 2022 15:43:38 +0100 Subject: [PATCH 5/6] Polishing #2031 Add missing Override annotations. --- .../RedisAdvancedClusterAsyncCommands.java | 26 ++++++++++++++++++- .../api/async/RedisClusterAsyncCommands.java | 6 +++++ .../RedisClusterReactiveCommands.java | 6 +++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java index 7f7e44cc78..7bee009f07 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/RedisAdvancedClusterAsyncCommands.java @@ -25,6 +25,7 @@ import io.lettuce.core.ScanArgs; import io.lettuce.core.ScanCursor; import io.lettuce.core.StreamScanCursor; +import io.lettuce.core.api.async.RedisConnectionAsyncCommands; import io.lettuce.core.api.async.RedisKeyAsyncCommands; import io.lettuce.core.api.async.RedisScriptingAsyncCommands; import io.lettuce.core.api.async.RedisServerAsyncCommands; @@ -226,6 +227,7 @@ default AsyncNodeSelection all() { * {@code 1} if the all the keys were set. {@code 0} if no key was set (at least one key already existed). * @see RedisStringAsyncCommands#msetnx(Map) */ + @Override RedisFuture msetnx(Map map); /** @@ -233,8 +235,9 @@ default AsyncNodeSelection all() { * * @param name the client name * @return simple-string-reply {@code OK} if the connection name was successfully set. - * @see RedisServerAsyncCommands#clientSetname(Object) + * @see RedisConnectionAsyncCommands#clientSetname(Object) */ + @Override RedisFuture clientSetname(K name); /** @@ -243,6 +246,7 @@ default AsyncNodeSelection all() { * @return String simple-string-reply * @see RedisServerAsyncCommands#flushall() */ + @Override RedisFuture flushall(); /** @@ -252,6 +256,7 @@ default AsyncNodeSelection all() { * @see RedisServerAsyncCommands#flushallAsync() * @since 6.0 */ + @Override RedisFuture flushallAsync(); /** @@ -260,6 +265,7 @@ default AsyncNodeSelection all() { * @return String simple-string-reply * @see RedisServerAsyncCommands#flushdb() */ + @Override RedisFuture flushdb(); /** @@ -268,6 +274,7 @@ default AsyncNodeSelection all() { * @return Long integer-reply * @see RedisServerAsyncCommands#dbsize() */ + @Override RedisFuture dbsize(); /** @@ -277,6 +284,7 @@ default AsyncNodeSelection all() { * @return List<K> array-reply list of keys matching {@code pattern}. * @see RedisKeyAsyncCommands#keys(Object) */ + @Override RedisFuture> keys(K pattern); /** @@ -287,6 +295,7 @@ default AsyncNodeSelection all() { * @return Long array-reply list of keys matching {@code pattern}. * @see RedisKeyAsyncCommands#keys(KeyStreamingChannel, Object) */ + @Override RedisFuture keys(KeyStreamingChannel channel, K pattern); /** @@ -295,6 +304,7 @@ default AsyncNodeSelection all() { * @return K bulk-string-reply the random key, or {@code null} when the database is empty. * @see RedisKeyAsyncCommands#randomkey() */ + @Override RedisFuture randomkey(); /** @@ -303,6 +313,7 @@ default AsyncNodeSelection all() { * @return String simple-string-reply * @see RedisScriptingAsyncCommands#scriptFlush() */ + @Override RedisFuture scriptFlush(); /** @@ -311,6 +322,7 @@ default AsyncNodeSelection all() { * @return String simple-string-reply, always {@literal OK}. * @see RedisScriptingAsyncCommands#scriptKill() */ + @Override RedisFuture scriptKill(); /** @@ -320,6 +332,7 @@ default AsyncNodeSelection all() { * @return String bulk-string-reply This command returns the SHA1 digest of the script added into the script cache. * @since 6.0 */ + @Override RedisFuture scriptLoad(String script); /** @@ -329,6 +342,7 @@ default AsyncNodeSelection all() { * @return String bulk-string-reply This command returns the SHA1 digest of the script added into the script cache. * @since 6.0 */ + @Override RedisFuture scriptLoad(byte[] script); /** @@ -337,6 +351,7 @@ default AsyncNodeSelection all() { * @param save {@code true} force save operation * @see RedisServerAsyncCommands#shutdown(boolean) */ + @Override void shutdown(boolean save); /** @@ -345,6 +360,7 @@ default AsyncNodeSelection all() { * @return KeyScanCursor<K> scan cursor. * @see RedisKeyAsyncCommands#scan() */ + @Override RedisFuture> scan(); /** @@ -354,6 +370,7 @@ default AsyncNodeSelection all() { * @return KeyScanCursor<K> scan cursor. * @see RedisKeyAsyncCommands#scan(ScanArgs) */ + @Override RedisFuture> scan(ScanArgs scanArgs); /** @@ -365,6 +382,7 @@ default AsyncNodeSelection all() { * @return KeyScanCursor<K> scan cursor. * @see RedisKeyAsyncCommands#scan(ScanCursor, ScanArgs) */ + @Override RedisFuture> scan(ScanCursor scanCursor, ScanArgs scanArgs); /** @@ -375,6 +393,7 @@ default AsyncNodeSelection all() { * @return KeyScanCursor<K> scan cursor. * @see RedisKeyAsyncCommands#scan(ScanCursor) */ + @Override RedisFuture> scan(ScanCursor scanCursor); /** @@ -384,6 +403,7 @@ default AsyncNodeSelection all() { * @return StreamScanCursor scan cursor. * @see RedisKeyAsyncCommands#scan(KeyStreamingChannel) */ + @Override RedisFuture scan(KeyStreamingChannel channel); /** @@ -394,6 +414,7 @@ default AsyncNodeSelection all() { * @return StreamScanCursor scan cursor. * @see RedisKeyAsyncCommands#scan(KeyStreamingChannel, ScanArgs) */ + @Override RedisFuture scan(KeyStreamingChannel channel, ScanArgs scanArgs); /** @@ -406,6 +427,7 @@ default AsyncNodeSelection all() { * @return StreamScanCursor scan cursor. * @see RedisKeyAsyncCommands#scan(KeyStreamingChannel, ScanCursor, ScanArgs) */ + @Override RedisFuture scan(KeyStreamingChannel channel, ScanCursor scanCursor, ScanArgs scanArgs); /** @@ -417,6 +439,7 @@ default AsyncNodeSelection all() { * @return StreamScanCursor scan cursor. * @see RedisKeyAsyncCommands#scan(ScanCursor, ScanArgs) */ + @Override RedisFuture scan(KeyStreamingChannel channel, ScanCursor scanCursor); /** @@ -426,6 +449,7 @@ default AsyncNodeSelection all() { * @param keys the keys * @return Long integer-reply the number of found keys. */ + @Override RedisFuture touch(K... keys); } diff --git a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java index 175745f2c1..a7230a632a 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java @@ -316,6 +316,7 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< * @param keys the key * @return RedisFuture<Long> integer-reply The number of keys that were removed. */ + @Override RedisFuture del(K... keys); /** @@ -325,6 +326,7 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< * @param keys the key * @return RedisFuture<List<V>> array-reply list of values at the specified keys. */ + @Override RedisFuture>> mget(K... keys); /** @@ -334,6 +336,7 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< * @param map the map * @return RedisFuture<String> simple-string-reply always {@code OK} since {@code MSET} can't fail. */ + @Override RedisFuture mset(Map map); /** @@ -345,6 +348,7 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< * * {@code 1} if the all the keys were set. {@code 0} if no key was set (at least one key already existed). */ + @Override RedisFuture msetnx(Map map); /** @@ -353,6 +357,7 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< * * @return String simple-string-reply */ + @Override RedisFuture readOnly(); /** @@ -360,6 +365,7 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< * * @return String simple-string-reply */ + @Override RedisFuture readWrite(); } diff --git a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java index 06e893dbb8..32e712df1f 100644 --- a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java @@ -299,6 +299,7 @@ public interface RedisClusterReactiveCommands * @param keys the key * @return Flux<Long> integer-reply The number of keys that were removed. */ + @Override Mono del(K... keys); /** @@ -308,6 +309,7 @@ public interface RedisClusterReactiveCommands * @param keys the key * @return Flux<List<V>> array-reply list of values at the specified keys. */ + @Override Flux> mget(K... keys); /** @@ -317,6 +319,7 @@ public interface RedisClusterReactiveCommands * @param map the map * @return Flux<String> simple-string-reply always {@code OK} since {@code MSET} can't fail. */ + @Override Mono mset(Map map); /** @@ -328,6 +331,7 @@ public interface RedisClusterReactiveCommands * * {@code 1} if the all the keys were set. {@code 0} if no key was set (at least one key already existed). */ + @Override Mono msetnx(Map map); /** @@ -336,6 +340,7 @@ public interface RedisClusterReactiveCommands * * @return String simple-string-reply */ + @Override Mono readOnly(); /** @@ -343,6 +348,7 @@ public interface RedisClusterReactiveCommands * * @return String simple-string-reply */ + @Override Mono readWrite(); } From b7c644d73361cbcc354db09c6e4ee4433e4c4eaa Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 1 Mar 2022 15:47:04 +0100 Subject: [PATCH 6/6] Polishing #2031 Remove duplicate method declarations from the Cluster API. Cross-slot operations are only available on the advanced cluster API provided by RedisClusterClient and not on the regular single-node connection interface. --- .../api/async/RedisClusterAsyncCommands.java | 60 ------------------ .../RedisClusterReactiveCommands.java | 61 ------------------- .../api/sync/RedisClusterCommands.java | 17 ------ 3 files changed, 138 deletions(-) diff --git a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java index a7230a632a..d88b34c720 100644 --- a/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/async/RedisClusterAsyncCommands.java @@ -16,9 +16,7 @@ package io.lettuce.core.cluster.api.async; import java.util.List; -import java.util.Map; -import io.lettuce.core.KeyValue; import io.lettuce.core.Range; import io.lettuce.core.RedisFuture; import io.lettuce.core.api.async.*; @@ -310,62 +308,4 @@ public interface RedisClusterAsyncCommands extends BaseRedisAsyncCommands< */ RedisFuture> clusterSlots(); - /** - * Delete a key with pipelining. Cross-slot keys will result in multiple calls to the particular cluster nodes. - * - * @param keys the key - * @return RedisFuture<Long> integer-reply The number of keys that were removed. - */ - @Override - RedisFuture del(K... keys); - - /** - * Get the values of all the given keys with pipelining. Cross-slot keys will result in multiple calls to the particular - * cluster nodes. - * - * @param keys the key - * @return RedisFuture<List<V>> array-reply list of values at the specified keys. - */ - @Override - RedisFuture>> mget(K... keys); - - /** - * Set multiple keys to multiple values with pipelining. Cross-slot keys will result in multiple calls to the particular - * cluster nodes. - * - * @param map the map - * @return RedisFuture<String> simple-string-reply always {@code OK} since {@code MSET} can't fail. - */ - @Override - RedisFuture mset(Map map); - - /** - * Set multiple keys to multiple values, only if none of the keys exist with pipelining. Cross-slot keys will result in - * multiple calls to the particular cluster nodes. - * - * @param map the map - * @return RedisFuture<Boolean> integer-reply specifically: - * - * {@code 1} if the all the keys were set. {@code 0} if no key was set (at least one key already existed). - */ - @Override - RedisFuture msetnx(Map map); - - /** - * Tells a Redis cluster replica node that the client is ok reading possibly stale data and is not interested in running - * write queries. - * - * @return String simple-string-reply - */ - @Override - RedisFuture readOnly(); - - /** - * Resets readOnly flag. - * - * @return String simple-string-reply - */ - @Override - RedisFuture readWrite(); - } diff --git a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java index 32e712df1f..7d00990537 100644 --- a/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/reactive/RedisClusterReactiveCommands.java @@ -15,11 +15,8 @@ */ package io.lettuce.core.cluster.api.reactive; -import java.util.Map; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import io.lettuce.core.KeyValue; import io.lettuce.core.Range; import io.lettuce.core.api.reactive.*; @@ -293,62 +290,4 @@ public interface RedisClusterReactiveCommands */ Flux clusterSlots(); - /** - * Delete a key with pipelining. Cross-slot keys will result in multiple calls to the particular cluster nodes. - * - * @param keys the key - * @return Flux<Long> integer-reply The number of keys that were removed. - */ - @Override - Mono del(K... keys); - - /** - * Get the values of all the given keys with pipelining. Cross-slot keys will result in multiple calls to the particular - * cluster nodes. - * - * @param keys the key - * @return Flux<List<V>> array-reply list of values at the specified keys. - */ - @Override - Flux> mget(K... keys); - - /** - * Set multiple keys to multiple values with pipelining. Cross-slot keys will result in multiple calls to the particular - * cluster nodes. - * - * @param map the map - * @return Flux<String> simple-string-reply always {@code OK} since {@code MSET} can't fail. - */ - @Override - Mono mset(Map map); - - /** - * Set multiple keys to multiple values, only if none of the keys exist with pipelining. Cross-slot keys will result in - * multiple calls to the particular cluster nodes. - * - * @param map the map - * @return Flux<Boolean> integer-reply specifically: - * - * {@code 1} if the all the keys were set. {@code 0} if no key was set (at least one key already existed). - */ - @Override - Mono msetnx(Map map); - - /** - * Tells a Redis cluster replica node that the client is ok reading possibly stale data and is not interested in running - * write queries. - * - * @return String simple-string-reply - */ - @Override - Mono readOnly(); - - /** - * Resets readOnly flag. - * - * @return String simple-string-reply - */ - @Override - Mono readWrite(); - } diff --git a/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java b/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java index 69e5b2c72d..9cd5ff675e 100644 --- a/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java +++ b/src/main/java/io/lettuce/core/cluster/api/sync/RedisClusterCommands.java @@ -288,21 +288,4 @@ public interface RedisClusterCommands extends BaseRedisCommands, Red */ List clusterSlots(); - /** - * Tells a Redis cluster replica node that the client is ok reading possibly stale data and is not interested in running - * write queries. - * - * @return String simple-string-reply - */ - @Override - String readOnly(); - - /** - * Resets readOnly flag. - * - * @return String simple-string-reply - */ - @Override - String readWrite(); - }