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 de4b96c5b..9e2b92f5a 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 @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.connection.lettuce; +import io.lettuce.core.AbstractRedisClient; import io.lettuce.core.ReadFrom; import io.lettuce.core.api.StatefulConnection; import io.lettuce.core.cluster.RedisClusterClient; @@ -34,7 +35,7 @@ import org.springframework.util.Assert; * @author Christoph Strobl * @since 2.0 */ -class ClusterConnectionProvider implements LettuceConnectionProvider { +class ClusterConnectionProvider implements LettuceConnectionProvider, RedisClientProvider { private final RedisClusterClient client; private final RedisCodec codec; @@ -91,7 +92,12 @@ class ClusterConnectionProvider implements LettuceConnectionProvider { throw new UnsupportedOperationException("Connection type " + connectionType + " not supported!"); } - public RedisClusterClient getClient() { + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.lettuce.RedisClientProvider#getRedisClient() + */ + @Override + public AbstractRedisClient getRedisClient() { return client; } } diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java index be1f90f57..900b809b6 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterConnection.java @@ -154,7 +154,15 @@ public class LettuceClusterConnection extends LettuceConnection implements Defau * @return access to {@link RedisClusterClient} for non-connection access. */ private RedisClusterClient getClient() { - return ((ClusterConnectionProvider) getConnectionProvider()).getClient(); + + LettuceConnectionProvider connectionProvider = getConnectionProvider(); + + if (connectionProvider instanceof RedisClientProvider) { + return (RedisClusterClient) ((RedisClientProvider) getConnectionProvider()).getRedisClient(); + } + + throw new IllegalStateException(String.format("Connection provider %s does not implement RedisClientProvider!", + connectionProvider.getClass().getName())); } /* diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettucePoolingConnectionProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettucePoolingConnectionProvider.java index d23201682..993afb116 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettucePoolingConnectionProvider.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettucePoolingConnectionProvider.java @@ -15,6 +15,7 @@ */ package org.springframework.data.redis.connection.lettuce; +import io.lettuce.core.AbstractRedisClient; import io.lettuce.core.api.StatefulConnection; import io.lettuce.core.support.ConnectionPoolSupport; @@ -42,7 +43,7 @@ import org.springframework.util.Assert; * @since 2.0 * @see #getConnection(Class) */ -class LettucePoolingConnectionProvider implements LettuceConnectionProvider, DisposableBean { +class LettucePoolingConnectionProvider implements LettuceConnectionProvider, RedisClientProvider, DisposableBean { private final static Log log = LogFactory.getLog(LettucePoolingConnectionProvider.class); @@ -86,6 +87,22 @@ class LettucePoolingConnectionProvider implements LettuceConnectionProvider, Dis } } + /* + * (non-Javadoc) + * @see org.springframework.data.redis.connection.lettuce.RedisClientProvider#getRedisClient() + */ + @Override + public AbstractRedisClient getRedisClient() { + + if (connectionProvider instanceof RedisClientProvider) { + return ((RedisClientProvider) connectionProvider).getRedisClient(); + } + + throw new IllegalStateException( + String.format("Undyerlying connection provider %s does not implement RedisClientProvider!", + connectionProvider.getClass().getName())); + } + /* * (non-Javadoc) * @see org.springframework.data.redis.connection.lettuce.LettuceConnectionProvider#release(io.lettuce.core.api.StatefulConnection) diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/RedisClientProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/RedisClientProvider.java new file mode 100644 index 000000000..2ce12d9e1 --- /dev/null +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/RedisClientProvider.java @@ -0,0 +1,34 @@ +/* + * Copyright 2018 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.redis.connection.lettuce; + +import io.lettuce.core.AbstractRedisClient; + +/** + * Extension to {@link LettuceConnectionProvider} for providers exposing {@link io.lettuce.core.RedisClient}. + * + * @author Mark Paluch + * @since 2.0.5 + */ +interface RedisClientProvider { + + /** + * Returns the underlying Redis Client. + * + * @return the {@link AbstractRedisClient}. + */ + AbstractRedisClient getRedisClient(); +} 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 e561cdb3d..f2d3b5698 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 @@ -28,6 +28,7 @@ import io.lettuce.core.cluster.RedisClusterClient; import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands; import java.nio.charset.Charset; +import java.time.Duration; import java.util.*; import java.util.concurrent.TimeUnit; @@ -41,16 +42,10 @@ import org.springframework.data.geo.Circle; import org.springframework.data.geo.Distance; import org.springframework.data.geo.GeoResults; import org.springframework.data.geo.Point; -import org.springframework.data.redis.connection.ClusterConnectionTests; -import org.springframework.data.redis.connection.ClusterSlotHashUtil; -import org.springframework.data.redis.connection.DataType; -import org.springframework.data.redis.connection.DefaultSortParameters; -import org.springframework.data.redis.connection.DefaultTuple; -import org.springframework.data.redis.connection.RedisClusterNode; +import org.springframework.data.redis.connection.*; import org.springframework.data.redis.connection.RedisClusterNode.SlotRange; import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation; import org.springframework.data.redis.connection.RedisListCommands.Position; -import org.springframework.data.redis.connection.RedisNode; import org.springframework.data.redis.connection.RedisStringCommands.BitOperation; import org.springframework.data.redis.connection.RedisStringCommands.SetOption; import org.springframework.data.redis.connection.RedisZSetCommands.Range; @@ -121,6 +116,47 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests { client.shutdown(0, 0, TimeUnit.MILLISECONDS); } + @Test // DATAREDIS-775 + public void shouldCreateConnectionWithPooling() { + + LettuceConnectionFactory factory = createConnectionFactory(); + factory.afterPropertiesSet(); + + RedisConnection connection = factory.getConnection(); + + assertThat(connection.ping(), is("PONG")); + connection.close(); + + factory.destroy(); + } + + @Test // DATAREDIS-775 + public void shouldCreateClusterConnectionWithPooling() { + + LettuceConnectionFactory factory = createConnectionFactory(); + factory.afterPropertiesSet(); + + RedisClusterConnection clusterConnection = factory.getClusterConnection(); + + assertThat(clusterConnection.ping(ClusterTestVariables.CLUSTER_NODE_1), is("PONG")); + clusterConnection.close(); + + factory.destroy(); + } + + private static LettuceConnectionFactory createConnectionFactory() { + + LettucePoolingClientConfiguration clientConfiguration = LettucePoolingClientConfiguration.builder() // + .clientResources(LettuceTestClientResources.getSharedClientResources()) // + .shutdownTimeout(Duration.ZERO) // + .build(); + + RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration(); + clusterConfiguration.addClusterNode(ClusterTestVariables.CLUSTER_NODE_1); + + return new LettuceConnectionFactory(clusterConfiguration, clientConfiguration); + } + @Test // DATAREDIS-315 public void appendShouldAddValueCorrectly() { diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestsBase.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestsBase.java index fd45ca049..6452dff0f 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestsBase.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceReactiveCommandsTestsBase.java @@ -17,6 +17,7 @@ package org.springframework.data.redis.connection.lettuce; import io.lettuce.core.api.StatefulRedisConnection; import io.lettuce.core.api.sync.RedisCommands; +import io.lettuce.core.cluster.RedisClusterClient; import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands; import io.lettuce.core.cluster.api.sync.RedisClusterCommands; @@ -122,7 +123,7 @@ public abstract class LettuceReactiveCommandsTestsBase { ClusterConnectionProvider clusterConnectionProvider = (ClusterConnectionProvider) nativeConnectionProvider; nativeCommands = nativeConnectionProvider.getConnection(StatefulRedisClusterConnection.class).sync(); this.connection = new LettuceReactiveRedisClusterConnection(connectionProvider, - clusterConnectionProvider.getClient()); + (RedisClusterClient) clusterConnectionProvider.getRedisClient()); } }