From fc8ba1aa844098507186380820bf7ef8fcbc55ea Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 25 Mar 2022 09:40:48 +0100 Subject: [PATCH] Polishing. Consistently use InvalidDataAccessApiUsageException to signal that an operation is not allowed/supported in the current mode of operation. Replace converter objects with conversion within the actual method to remove indirections. Original Pull Request: #2287 --- .../jedis/JedisClusterConnection.java | 6 +- .../jedis/JedisClusterKeyCommands.java | 2 +- .../connection/jedis/JedisConnection.java | 6 +- .../redis/connection/jedis/JedisInvoker.java | 7 ++- .../jedis/JedisScriptingCommands.java | 3 +- .../connection/jedis/JedisStringCommands.java | 2 +- .../lettuce/ClusterConnectionProvider.java | 3 +- .../lettuce/LettuceClusterKeyCommands.java | 3 +- .../connection/lettuce/LettuceConnection.java | 10 ++-- .../lettuce/LettuceHashCommands.java | 3 +- .../lettuce/LettuceKeyCommands.java | 3 +- .../LettuceReactiveClusterKeyCommands.java | 4 +- .../lettuce/LettuceScriptingCommands.java | 3 +- .../lettuce/LettuceServerCommands.java | 6 +- .../lettuce/LettuceSetCommands.java | 3 +- .../lettuce/LettuceStringCommands.java | 5 +- .../lettuce/LettuceZSetCommands.java | 3 +- ...StaticMasterReplicaConnectionProvider.java | 1 + .../connection/lettuce/StreamConverters.java | 56 +++++++------------ .../AbstractConnectionIntegrationTests.java | 2 +- ...ConnectionTransactionIntegrationTests.java | 7 ++- .../jedis/JedisClusterConnectionTests.java | 2 +- ...disConnectionPipelineIntegrationTests.java | 35 ++++++------ ...ConnectionTransactionIntegrationTests.java | 7 ++- .../LettuceClusterConnectionTests.java | 3 +- .../LettuceConnectionIntegrationTests.java | 3 +- ...uceConnectionPipelineIntegrationTests.java | 10 +--- ...nPipelineTxFlushOnEndIntegrationTests.java | 2 +- ...eConnectionPipelineTxIntegrationTests.java | 10 +--- ...ConnectionTransactionIntegrationTests.java | 3 +- 30 files changed, 100 insertions(+), 113 deletions(-) diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java index cb527eb8e..6f02406d1 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterConnection.java @@ -653,17 +653,17 @@ public class JedisClusterConnection implements RedisClusterConnection { @Override public void openPipeline() { - throw new UnsupportedOperationException("Pipeline is currently not supported for JedisClusterConnection."); + throw new InvalidDataAccessApiUsageException("Pipeline is not supported for JedisClusterConnection."); } @Override public List closePipeline() throws RedisPipelineException { - throw new UnsupportedOperationException("Pipeline is currently not supported for JedisClusterConnection."); + throw new InvalidDataAccessApiUsageException("Pipeline is not supported for JedisClusterConnection."); } @Override public RedisSentinelConnection getSentinelConnection() { - throw new UnsupportedOperationException("Sentinel is currently not supported for JedisClusterConnection."); + throw new InvalidDataAccessApiUsageException("Sentinel is not supported for JedisClusterConnection."); } @Override diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java index 68556ff4c..578f0d540 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java @@ -335,7 +335,7 @@ class JedisClusterKeyCommands implements RedisKeyCommands { @Override public Boolean move(byte[] key, int dbIndex) { - throw new UnsupportedOperationException("Cluster mode does not allow moving keys."); + throw new InvalidDataAccessApiUsageException("Cluster mode does not allow moving keys."); } @Override diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java index 3ea8fe448..ffcf5200c 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisConnection.java @@ -553,7 +553,7 @@ public class JedisConnection extends AbstractRedisConnection { @Override public void watch(byte[]... keys) { if (isQueueing()) { - throw new UnsupportedOperationException(); + throw new InvalidDataAccessApiUsageException("WATCH is not supported when a transaction is active"); } doWithJedis(it -> { @@ -591,7 +591,7 @@ public class JedisConnection extends AbstractRedisConnection { } if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); + throw new InvalidDataAccessApiUsageException("Cannot subscribe in pipeline / transaction mode"); } doWithJedis(it -> { @@ -612,7 +612,7 @@ public class JedisConnection extends AbstractRedisConnection { } if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException(); + throw new InvalidDataAccessApiUsageException("Cannot subscribe in pipeline / transaction mode"); } doWithJedis(it -> { diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java index bc2305ada..a93876625 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisInvoker.java @@ -34,6 +34,7 @@ import java.util.function.Supplier; import org.springframework.aop.framework.ProxyFactory; import org.springframework.core.convert.converter.Converter; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -82,7 +83,7 @@ class JedisInvoker { Assert.notNull(function, "ConnectionFunction must not be null!"); return synchronizer.invoke(function::apply, it -> { - throw new UnsupportedOperationException("Operation not supported by Jedis in pipelining/transaction mode"); + throw new InvalidDataAccessApiUsageException("Operation not supported by Jedis in pipelining/transaction mode"); }, Converters.identityConverter(), () -> null); } @@ -231,7 +232,7 @@ class JedisInvoker { Assert.notNull(function, "ConnectionFunction must not be null!"); return from(function, connection -> { - throw new UnsupportedOperationException("Operation not supported in pipelining/transaction mode"); + throw new InvalidDataAccessApiUsageException("Operation not supported in pipelining/transaction mode"); }); } @@ -379,7 +380,7 @@ class JedisInvoker { Assert.notNull(function, "ConnectionFunction must not be null!"); return fromMany(function, connection -> { - throw new UnsupportedOperationException("Operation not supported in pipelining/transaction mode"); + throw new InvalidDataAccessApiUsageException("Operation not supported in pipelining/transaction mode"); }); } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java index cc29f36cb..4d1f8a6b6 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisScriptingCommands.java @@ -19,6 +19,7 @@ import redis.clients.jedis.Jedis; import java.util.List; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisScriptingCommands; import org.springframework.data.redis.connection.ReturnType; import org.springframework.util.Assert; @@ -101,7 +102,7 @@ class JedisScriptingCommands implements RedisScriptingCommands { private void assertDirectMode() { if (connection.isQueueing() || connection.isPipelined()) { - throw new UnsupportedOperationException("Scripting commands not supported in pipelining/transaction mode"); + throw new InvalidDataAccessApiUsageException("Scripting commands not supported in pipelining/transaction mode"); } } diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java index 55e3660de..622645ff9 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisStringCommands.java @@ -283,7 +283,7 @@ class JedisStringCommands implements RedisStringCommands { Assert.notNull(destination, "Destination key must not be null!"); if (op == BitOperation.NOT && keys.length > 1) { - throw new UnsupportedOperationException("Bitop NOT should only be performed against one key"); + throw new IllegalArgumentException("Bitop NOT should only be performed against one key"); } return connection.invoke().just(Jedis::bitop, PipelineBinaryCommands::bitop, JedisConverters.toBitOp(op), diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java index 4579182d3..1d4ee45b7 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/ClusterConnectionProvider.java @@ -26,6 +26,7 @@ import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; import java.util.Optional; import java.util.concurrent.CompletableFuture; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -110,7 +111,7 @@ class ClusterConnectionProvider implements LettuceConnectionProvider, RedisClien } return LettuceFutureUtils - .failed(new UnsupportedOperationException("Connection type " + connectionType + " not supported!")); + .failed(new InvalidDataAccessApiUsageException("Connection type " + connectionType + " not supported!")); } @Override diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java index 80ed1893a..f34c266b9 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.ThreadLocalRandom; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.RedisClusterNode; import org.springframework.data.redis.connection.SortParameters; @@ -134,7 +135,7 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands { @Override public Boolean move(byte[] key, int dbIndex) { - throw new UnsupportedOperationException("MOVE not supported in CLUSTER mode!"); + throw new InvalidDataAccessApiUsageException("MOVE not supported in CLUSTER mode!"); } @Nullable diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java index a40de2718..62e612e98 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceConnection.java @@ -547,7 +547,7 @@ public class LettuceConnection extends AbstractRedisConnection { public void select(int dbIndex) { if (asyncSharedConn != null) { - throw new UnsupportedOperationException("Selecting a new database not supported due to shared connection. " + throw new InvalidDataAccessApiUsageException("Selecting a new database not supported due to shared connection. " + "Use separate ConnectionFactorys to work with multiple databases"); } @@ -578,7 +578,7 @@ public class LettuceConnection extends AbstractRedisConnection { @Override public void watch(byte[]... keys) { if (isQueueing()) { - throw new UnsupportedOperationException(); + throw new InvalidDataAccessApiUsageException("WATCH is not supported when a transaction is active"); } try { if (isPipelined()) { @@ -620,7 +620,8 @@ public class LettuceConnection extends AbstractRedisConnection { checkSubscription(); if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException("Transaction/Pipelining is not supported for Pub/Sub subscriptions!"); + throw new InvalidDataAccessApiUsageException( + "Transaction/Pipelining is not supported for Pub/Sub subscriptions!"); } try { @@ -637,7 +638,8 @@ public class LettuceConnection extends AbstractRedisConnection { checkSubscription(); if (isQueueing() || isPipelined()) { - throw new UnsupportedOperationException("Transaction/Pipelining is not supported for Pub/Sub subscriptions!"); + throw new InvalidDataAccessApiUsageException( + "Transaction/Pipelining is not supported for Pub/Sub subscriptions!"); } try { diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java index 58e85c4c1..0053487ba 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceHashCommands.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisHashCommands; import org.springframework.data.redis.connection.convert.Converters; import org.springframework.data.redis.core.Cursor; @@ -223,7 +224,7 @@ class LettuceHashCommands implements RedisHashCommands { protected ScanIteration> doScan(byte[] key, long cursorId, ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { - throw new UnsupportedOperationException("'HSCAN' cannot be called in pipeline / transaction mode."); + throw new InvalidDataAccessApiUsageException("'HSCAN' cannot be called in pipeline / transaction mode."); } io.lettuce.core.ScanCursor scanCursor = connection.getScanCursor(cursorId); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java index 30a799899..22942e1de 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceKeyCommands.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.DataType; import org.springframework.data.redis.connection.RedisKeyCommands; import org.springframework.data.redis.connection.SortParameters; @@ -149,7 +150,7 @@ class LettuceKeyCommands implements RedisKeyCommands { protected LettuceScanIteration doScan(ScanCursor cursor, ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { - throw new UnsupportedOperationException("'SCAN' cannot be called in pipeline / transaction mode."); + throw new InvalidDataAccessApiUsageException("'SCAN' cannot be called in pipeline / transaction mode."); } ScanArgs scanArgs = LettuceConverters.toScanArgs(options); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterKeyCommands.java index 6298a1b44..afb463b27 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveClusterKeyCommands.java @@ -24,6 +24,8 @@ import java.nio.ByteBuffer; import java.util.List; import org.reactivestreams.Publisher; + +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.RedisSystemException; import org.springframework.data.redis.connection.ClusterSlotHashUtil; import org.springframework.data.redis.connection.ReactiveClusterKeyCommands; @@ -122,6 +124,6 @@ class LettuceReactiveClusterKeyCommands extends LettuceReactiveKeyCommands imple @Override public Flux> move(Publisher commands) { - throw new UnsupportedOperationException("MOVE not supported in CLUSTER mode!"); + throw new InvalidDataAccessApiUsageException("MOVE not supported in CLUSTER mode!"); } } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java index 2ef2b653d..4f31ae2f4 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScriptingCommands.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.List; import org.springframework.core.convert.converter.Converter; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisScriptingCommands; import org.springframework.data.redis.connection.ReturnType; import org.springframework.util.Assert; @@ -46,7 +47,7 @@ class LettuceScriptingCommands implements RedisScriptingCommands { public void scriptKill() { if (connection.isQueueing()) { - throw new UnsupportedOperationException("Script kill not permitted in a transaction"); + throw new InvalidDataAccessApiUsageException("Script kill not permitted in a transaction"); } connection.invoke().just(RedisScriptingAsyncCommands::scriptKill); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java index ba7dc72d6..1a5c4e42c 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceServerCommands.java @@ -26,6 +26,7 @@ import java.util.Properties; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisServerCommands; import org.springframework.data.redis.core.types.RedisClientInfo; @@ -192,11 +193,6 @@ class LettuceServerCommands implements RedisServerCommands { @Override public List getClientList() { - - if (connection.isPipelined()) { - throw new UnsupportedOperationException("Cannot be called in pipeline mode."); - } - return connection.invoke().from(RedisServerAsyncCommands::clientList) .get(LettuceConverters.stringToRedisClientListConverter()); } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java index 474d0d040..6a69fd351 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceSetCommands.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisSetCommands; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.KeyBoundCursor; @@ -220,7 +221,7 @@ class LettuceSetCommands implements RedisSetCommands { protected ScanIteration doScan(byte[] key, long cursorId, ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { - throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline / transaction mode."); + throw new InvalidDataAccessApiUsageException("'SSCAN' cannot be called in pipeline / transaction mode."); } io.lettuce.core.ScanCursor scanCursor = connection.getScanCursor(cursorId); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java index 57ecbddb9..a399924fe 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceStringCommands.java @@ -21,6 +21,7 @@ import io.lettuce.core.api.async.RedisStringAsyncCommands; import java.util.List; import java.util.Map; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Range; import org.springframework.data.redis.connection.BitFieldSubCommands; import org.springframework.data.redis.connection.RedisStringCommands; @@ -275,7 +276,7 @@ class LettuceStringCommands implements RedisStringCommands { Assert.notNull(destination, "Destination key must not be null!"); if (op == BitOperation.NOT && keys.length > 1) { - throw new UnsupportedOperationException("Bitop NOT should only be performed against one key"); + throw new IllegalArgumentException("Bitop NOT should only be performed against one key"); } return connection.invoke().just(it -> { @@ -289,7 +290,7 @@ class LettuceStringCommands implements RedisStringCommands { return it.bitopXor(destination, keys); case NOT: if (keys.length != 1) { - throw new UnsupportedOperationException("Bitop NOT should only be performed against one key"); + throw new IllegalArgumentException("Bitop NOT should only be performed against one key"); } return it.bitopNot(destination, keys[0]); default: diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java index 14614056b..d57746f64 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceZSetCommands.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.RedisZSetCommands; import org.springframework.data.redis.connection.RedisZSetCommands.ZAddArgs.Flag; import org.springframework.data.redis.connection.convert.Converters; @@ -546,7 +547,7 @@ class LettuceZSetCommands implements RedisZSetCommands { protected ScanIteration doScan(byte[] key, long cursorId, ScanOptions options) { if (connection.isQueueing() || connection.isPipelined()) { - throw new UnsupportedOperationException("'ZSCAN' cannot be called in pipeline / transaction mode."); + throw new InvalidDataAccessApiUsageException("'ZSCAN' cannot be called in pipeline / transaction mode."); } io.lettuce.core.ScanCursor scanCursor = connection.getScanCursor(cursorId); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java index 475cb476f..0e2cbcfee 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java @@ -29,6 +29,7 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.lang.Nullable; /** diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/StreamConverters.java b/src/main/java/org/springframework/data/redis/connection/lettuce/StreamConverters.java index 9e6e9df34..b56081eeb 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/StreamConverters.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/StreamConverters.java @@ -25,11 +25,9 @@ import java.nio.ByteBuffer; import java.time.Duration; import java.util.ArrayList; import java.util.List; -import java.util.function.BiFunction; import org.springframework.core.convert.converter.Converter; import org.springframework.data.redis.connection.RedisStreamCommands.XClaimOptions; -import org.springframework.data.redis.connection.convert.ListConverter; import org.springframework.data.redis.connection.stream.ByteRecord; import org.springframework.data.redis.connection.stream.Consumer; import org.springframework.data.redis.connection.stream.PendingMessagesSummary; @@ -53,39 +51,6 @@ import org.springframework.util.NumberUtils; @SuppressWarnings({ "rawtypes" }) class StreamConverters { - private static final Converter>, List> MESSAGEs_TO_IDs = new ListConverter<>( - messageToIdConverter()); - - private static final BiFunction, String, org.springframework.data.redis.connection.stream.PendingMessages> PENDING_MESSAGES_CONVERTER = ( - source, groupName) -> { - - - List messages = source.stream() - .map(it -> { - - RecordId id = RecordId.of(it.getId()); - Consumer consumer = Consumer.from(groupName, it.getConsumer()); - - return new org.springframework.data.redis.connection.stream.PendingMessage(id, consumer, - Duration.ofMillis(it.getMsSinceLastDelivery()), it.getRedeliveryCount()); - - }).toList(); - - return new org.springframework.data.redis.connection.stream.PendingMessages(groupName, messages); - - }; - - private static final BiFunction PENDING_MESSAGES_SUMMARY_CONVERTER = ( - source, groupName) -> { - - org.springframework.data.domain.Range range = source.getMessageIds().isUnbounded() - ? org.springframework.data.domain.Range.unbounded() - : org.springframework.data.domain.Range.open(source.getMessageIds().getLower().getValue(), - source.getMessageIds().getUpper().getValue()); - - return new PendingMessagesSummary(groupName, source.getCount(), range, source.getConsumerMessageCount()); - }; - /** * Convert {@link StreamReadOptions} to Lettuce's {@link XReadArgs}. * @@ -126,7 +91,18 @@ class StreamConverters { */ static org.springframework.data.redis.connection.stream.PendingMessages toPendingMessages(String groupName, org.springframework.data.domain.Range range, List source) { - return PENDING_MESSAGES_CONVERTER.apply(source, groupName).withinRange(range); + + List messages = source.stream().map(it -> { + + RecordId id = RecordId.of(it.getId()); + Consumer consumer = Consumer.from(groupName, it.getConsumer()); + + return new org.springframework.data.redis.connection.stream.PendingMessage(id, consumer, + Duration.ofMillis(it.getMsSinceLastDelivery()), it.getRedeliveryCount()); + + }).toList(); + + return new org.springframework.data.redis.connection.stream.PendingMessages(groupName, messages).withinRange(range); } /** @@ -138,7 +114,13 @@ class StreamConverters { * @since 2.3 */ static PendingMessagesSummary toPendingMessagesInfo(String groupName, PendingMessages source) { - return PENDING_MESSAGES_SUMMARY_CONVERTER.apply(source, groupName); + + org.springframework.data.domain.Range range = source.getMessageIds().isUnbounded() + ? org.springframework.data.domain.Range.unbounded() + : org.springframework.data.domain.Range.open(source.getMessageIds().getLower().getValue(), + source.getMessageIds().getUpper().getValue()); + + return new PendingMessagesSummary(groupName, source.getCount(), range, source.getConsumerMessageCount()); } /** diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java index 674fcdb5f..4b5a67cd4 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionIntegrationTests.java @@ -527,7 +527,7 @@ public abstract class AbstractConnectionIntegrationTests { @Test void testBitOpNotMultipleSources() { - assertThatExceptionOfType(UnsupportedOperationException.class) + assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> connection.bitOp(BitOperation.NOT, "key3", "key1", "key2")); } diff --git a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionTransactionIntegrationTests.java index becb13afd..7b0f3f9f1 100644 --- a/src/test/java/org/springframework/data/redis/connection/AbstractConnectionTransactionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/AbstractConnectionTransactionIntegrationTests.java @@ -23,6 +23,8 @@ import java.util.List; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.springframework.dao.InvalidDataAccessApiUsageException; + /** * @author Jennifer Hickey * @author Thomas Darimont @@ -128,14 +130,15 @@ abstract public class AbstractConnectionTransactionIntegrationTests extends Abst @Test public void testWatchWhileInTx() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> connection.watch("foo".getBytes())); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) + .isThrownBy(() -> connection.watch("foo".getBytes())); } @Test public void testScriptKill() { // Impossible to call script kill in a tx because you can't issue the // exec command while Redis is running a script - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> connection.scriptKill()); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(() -> connection.scriptKill()); } @Test // DATAREDIS-417 diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java index 47ff2f7d9..7a4c82400 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisClusterConnectionTests.java @@ -1368,7 +1368,7 @@ public class JedisClusterConnectionTests implements ClusterConnectionTests { @Test // DATAREDIS-315 public void moveShouldNotBeSupported() { - assertThatExceptionOfType(UnsupportedOperationException.class) + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) .isThrownBy(() -> clusterConnection.move(KEY_1_BYTES, 3)); } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java index 9d55ab4c6..4852afc81 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionPipelineIntegrationTests.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.SettingsUtils; import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests; import org.springframework.data.redis.connection.RedisConnection; @@ -78,17 +79,17 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP // Unsupported Ops @Test public void testScriptLoadEvalSha() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testScriptLoadEvalSha); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testScriptLoadEvalSha); } @Test public void testEvalShaArrayStrings() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalShaArrayStrings); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalShaArrayStrings); } @Test public void testEvalShaArrayBytes() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalShaArrayBytes); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalShaArrayBytes); } @Test @@ -101,17 +102,17 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP @Test public void testEvalReturnString() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnString); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnString); } @Test public void testEvalReturnNumber() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnNumber); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnNumber); } @Test public void testEvalReturnSingleOK() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnSingleOK); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnSingleOK); } @Test @@ -120,47 +121,47 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP @Test public void testEvalReturnFalse() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnFalse); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnFalse); } @Test public void testEvalReturnTrue() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnTrue); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnTrue); } @Test public void testEvalReturnArrayStrings() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnArrayStrings); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnArrayStrings); } @Test public void testEvalReturnArrayNumbers() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnArrayNumbers); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnArrayNumbers); } @Test public void testEvalReturnArrayOKs() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnArrayOKs); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnArrayOKs); } @Test public void testEvalReturnArrayFalses() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnArrayFalses); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnArrayFalses); } @Test public void testEvalReturnArrayTrues() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testEvalReturnArrayTrues); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testEvalReturnArrayTrues); } @Test public void testScriptExists() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testScriptExists); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testScriptExists); } @Test public void testScriptKill() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> connection.scriptKill()); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(() -> connection.scriptKill()); } @Test @@ -169,14 +170,14 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP @Test // DATAREDIS-269 public void clientSetNameWorksCorrectly() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::clientSetNameWorksCorrectly); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::clientSetNameWorksCorrectly); } @Test @Override // DATAREDIS-268 public void testListClientsContainsAtLeastOneElement() { - assertThatExceptionOfType(UnsupportedOperationException.class) + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) .isThrownBy(super::testListClientsContainsAtLeastOneElement); } diff --git a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java index 8dc77fd22..ecd0c4ca3 100644 --- a/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/jedis/JedisConnectionTransactionIntegrationTests.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.AbstractConnectionTransactionIntegrationTests; import org.springframework.data.redis.connection.ReturnType; import org.springframework.test.context.ContextConfiguration; @@ -76,13 +77,13 @@ public class JedisConnectionTransactionIntegrationTests extends AbstractConnecti @Test public void testEvalShaArrayError() { - assertThatExceptionOfType(UnsupportedOperationException.class) + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) .isThrownBy(() -> connection.evalSha("notasha", ReturnType.MULTI, 1, "key1", "arg1")); } @Test public void testEvalArrayScriptError() { - assertThatExceptionOfType(UnsupportedOperationException.class) + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) .isThrownBy(() -> connection.eval("return {1,2", ReturnType.MULTI, 1, "foo", "bar")); } @@ -162,7 +163,7 @@ public class JedisConnectionTransactionIntegrationTests extends AbstractConnecti @Override // DATAREDIS-268 public void testListClientsContainsAtLeastOneElement() { - assertThatExceptionOfType(UnsupportedOperationException.class) + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) .isThrownBy(super::testListClientsContainsAtLeastOneElement); } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java index 476214a55..3a46192be 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnectionTests.java @@ -43,6 +43,7 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.dao.DataAccessException; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Range.Bound; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; @@ -1402,7 +1403,7 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests { @Test // DATAREDIS-315 public void moveShouldNotBeSupported() { - assertThatExceptionOfType(UnsupportedOperationException.class) + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class) .isThrownBy(() -> clusterConnection.move(KEY_1_BYTES, 3)); } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java index f1c90e671..7d906d1c1 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionIntegrationTests.java @@ -24,6 +24,7 @@ import java.util.Set; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.RedisSystemException; import org.springframework.data.redis.SettingsUtils; import org.springframework.data.redis.connection.AbstractConnectionIntegrationTests; @@ -139,7 +140,7 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra @Test public void testSelect() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> super.testSelect()); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(() -> super.testSelect()); } @Test diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java index 2cfbcb160..1dfd484b9 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineIntegrationTests.java @@ -22,6 +22,7 @@ import java.util.Arrays; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.AbstractConnectionPipelineIntegrationTests; import org.springframework.data.redis.connection.DefaultStringRedisConnection; import org.springframework.data.redis.connection.StringRedisConnection; @@ -43,7 +44,7 @@ public class LettuceConnectionPipelineIntegrationTests extends AbstractConnectio @Test public void testSelect() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> super.testSelect()); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(() -> super.testSelect()); } @Test @@ -69,11 +70,4 @@ public class LettuceConnectionPipelineIntegrationTests extends AbstractConnectio } } - @Test - @Override - // DATAREDIS-268 - public void testListClientsContainsAtLeastOneElement() { - assertThatExceptionOfType(UnsupportedOperationException.class) - .isThrownBy(() -> super.testListClientsContainsAtLeastOneElement()); - } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxFlushOnEndIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxFlushOnEndIntegrationTests.java index 335b26772..61a8767bf 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxFlushOnEndIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxFlushOnEndIntegrationTests.java @@ -24,6 +24,6 @@ import org.springframework.test.context.ContextConfiguration; * @author Mark Paluch */ @ContextConfiguration("LettuceConnectionPipelineFlushOnEndIntegrationTests-context.xml") -public class LettuceConnectionPipelineTxFlushOnEndIntegrationTests extends LettuceConnectionPipelineTxIntegrationTests { +class LettuceConnectionPipelineTxFlushOnEndIntegrationTests extends LettuceConnectionPipelineTxIntegrationTests { } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java index 692761849..17a955ce5 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionPipelineTxIntegrationTests.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.Test; * @author Jennifer Hickey * @author Christoph Strobl */ -public class LettuceConnectionPipelineTxIntegrationTests extends LettuceConnectionTransactionIntegrationTests { +class LettuceConnectionPipelineTxIntegrationTests extends LettuceConnectionTransactionIntegrationTests { @Test @Disabled("Different exception") @@ -76,12 +76,4 @@ public class LettuceConnectionPipelineTxIntegrationTests extends LettuceConnecti return txResults; } - @Test - @Override - // DATAREDIS-268 - public void testListClientsContainsAtLeastOneElement() { - assertThatExceptionOfType(UnsupportedOperationException.class) - .isThrownBy(super::testListClientsContainsAtLeastOneElement); - } - } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java index f77622014..147f2184c 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionTransactionIntegrationTests.java @@ -22,6 +22,7 @@ import java.util.Arrays; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.redis.connection.AbstractConnectionTransactionIntegrationTests; import org.springframework.data.redis.connection.DefaultStringRedisConnection; import org.springframework.data.redis.connection.StringRedisConnection; @@ -68,6 +69,6 @@ public class LettuceConnectionTransactionIntegrationTests extends AbstractConnec @Test public void testSelect() { - assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(super::testSelect); + assertThatExceptionOfType(InvalidDataAccessApiUsageException.class).isThrownBy(super::testSelect); } }