From a91d73d161c6beaaee9cbda914fbed5ab93ea5d6 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 21 Jul 2020 10:11:52 +0200 Subject: [PATCH] Remove Spring support classes #1358 Lettuce no longer ships own Spring support classes. We recommend using Lettuce through Spring Data Redis. --- pom.xml | 54 ------ .../asciidoc/integration-extension.asciidoc | 5 - src/main/asciidoc/new-features.adoc | 2 + .../lettuce/core/protocol/CommandHandler.java | 4 + .../support/ClientResourcesFactoryBean.java | 83 --------- .../support/LettuceFactoryBeanSupport.java | 118 ------------ .../core/support/RedisClientFactoryBean.java | 74 -------- .../RedisClusterClientFactoryBean.java | 125 ------------- .../apigenerator/CompilationUnitFactory.java | 2 +- .../core/ClientMetricsIntegrationTests.java | 2 +- .../core/RedisClientFactoryBeanUnitTests.java | 176 ------------------ .../io/lettuce/core/RedisClientUnitTests.java | 17 +- ...yncConnectionProviderIntegrationTests.java | 9 +- .../cluster/ClusterNodeEndpointUnitTests.java | 2 +- .../TopologyRefreshIntegrationTests.java | 2 +- .../dynamic/ParameterBinderUnitTests.java | 14 +- .../SentinelTopologyRefreshUnitTests.java | 2 +- .../MasterSlaveSentinelIntegrationTests.java | 2 +- ...faultCommandLatencyCollectorUnitTests.java | 2 +- .../protocol/CommandHandlerUnitTests.java | 8 +- .../ConnectionFailureIntegrationTests.java | 9 +- .../protocol/DefaultEndpointUnitTests.java | 2 +- .../pubsub/PubSubCommandHandlerUnitTests.java | 4 +- .../DefaultClientResourcesUnitTests.java | 11 +- ...ConnectionPoolSupportIntegrationTests.java | 2 +- ...ConnectionPoolSupportIntegrationTests.java | 2 +- ...edisClusterClientFactoryBeanUnitTests.java | 137 -------------- .../core/support/SpringIntegrationTests.java | 67 ------- .../core/tracing/BraveTracingUnitTests.java | 2 +- .../io/lettuce/examples/MySpringBean.java | 45 ----- .../io/lettuce/examples/SpringExample.java | 47 ----- .../io/lettuce/test/ConnectionTestUtil.java | 2 +- .../io/lettuce/test/ReflectionTestUtils.java | 159 ++++++++++++++++ .../test/condition/RedisConditions.java | 24 +-- .../SpringIntegrationTests-context.xml | 37 ---- 35 files changed, 231 insertions(+), 1022 deletions(-) delete mode 100644 src/main/java/io/lettuce/core/support/ClientResourcesFactoryBean.java delete mode 100644 src/main/java/io/lettuce/core/support/LettuceFactoryBeanSupport.java delete mode 100644 src/main/java/io/lettuce/core/support/RedisClientFactoryBean.java delete mode 100644 src/main/java/io/lettuce/core/support/RedisClusterClientFactoryBean.java delete mode 100644 src/test/java/io/lettuce/core/RedisClientFactoryBeanUnitTests.java delete mode 100644 src/test/java/io/lettuce/core/support/RedisClusterClientFactoryBeanUnitTests.java delete mode 100644 src/test/java/io/lettuce/core/support/SpringIntegrationTests.java delete mode 100644 src/test/java/io/lettuce/examples/MySpringBean.java delete mode 100644 src/test/java/io/lettuce/examples/SpringExample.java create mode 100644 src/test/java/io/lettuce/test/ReflectionTestUtils.java delete mode 100644 src/test/resources/io/lettuce/core/support/SpringIntegrationTests-context.xml diff --git a/pom.xml b/pom.xml index 1afa9c524a..58be755e9a 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,6 @@ 3.0.4 1.0.3 1.7.25 - 4.3.26.RELEASE UTF-8 @@ -112,14 +111,6 @@ import - - org.springframework - spring-framework-bom - ${spring.version} - pom - import - - io.zipkin.brave brave-bom @@ -259,26 +250,6 @@ true - - - - org.springframework - spring-beans - true - - - commons-logging - commons-logging - - - - - - org.springframework - spring-context - true - - @@ -447,31 +418,6 @@ test - - org.springframework - spring-core - test - - - - org.springframework - spring-aop - test - - - - org.springframework - spring-test - test - - - - org.springframework - spring-expression - ${spring.version} - test - - diff --git a/src/main/asciidoc/integration-extension.asciidoc b/src/main/asciidoc/integration-extension.asciidoc index b66fccd3cc..4839d122f8 100644 --- a/src/main/asciidoc/integration-extension.asciidoc +++ b/src/main/asciidoc/integration-extension.asciidoc @@ -8,8 +8,3 @@ include::{ext-doc}/Codecs.asciidoc[leveloffset=+1] [[cdi-support]] === CDI Support include::{ext-doc}/CDI-Support.asciidoc[leveloffset=+1] - -[[spring-support]] -=== Spring Support -include::{ext-doc}/Spring-Support.asciidoc[leveloffset=+1] - diff --git a/src/main/asciidoc/new-features.adoc b/src/main/asciidoc/new-features.adoc index 6009f90ba8..ba1255af17 100644 --- a/src/main/asciidoc/new-features.adoc +++ b/src/main/asciidoc/new-features.adoc @@ -14,6 +14,8 @@ Use methods accepting `Duration` instead. * Lots of internal refinements. * `xpending` methods return now `List` and `PendingMessages` +* Spring support removed. +Use Spring Data Redis for a seamless Spring integration with Lettuce. [[new-features.5-3-0]] == What's new in Lettuce 5.3 diff --git a/src/main/java/io/lettuce/core/protocol/CommandHandler.java b/src/main/java/io/lettuce/core/protocol/CommandHandler.java index 6794847fb9..a20667c885 100644 --- a/src/main/java/io/lettuce/core/protocol/CommandHandler.java +++ b/src/main/java/io/lettuce/core/protocol/CommandHandler.java @@ -152,6 +152,10 @@ protected void setState(LifecycleState lifecycleState) { } } + void setBuffer(ByteBuf buffer) { + this.buffer = buffer; + } + @Override public Collection> drainQueue() { return drainCommands(stack); diff --git a/src/main/java/io/lettuce/core/support/ClientResourcesFactoryBean.java b/src/main/java/io/lettuce/core/support/ClientResourcesFactoryBean.java deleted file mode 100644 index 7c275ec593..0000000000 --- a/src/main/java/io/lettuce/core/support/ClientResourcesFactoryBean.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011-2020 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.support; - -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.config.AbstractFactoryBean; - -import io.lettuce.core.resource.ClientResources; -import io.lettuce.core.resource.DefaultClientResources; - -/** - * {@link FactoryBean} that creates a {@link ClientResources} instance representing the infrastructure resources (thread pools) - * for a Redis Client. - * - * @author Mark Paluch - */ -public class ClientResourcesFactoryBean extends AbstractFactoryBean { - - private int ioThreadPoolSize = DefaultClientResources.DEFAULT_IO_THREADS; - - private int computationThreadPoolSize = DefaultClientResources.DEFAULT_COMPUTATION_THREADS; - - public int getIoThreadPoolSize() { - return ioThreadPoolSize; - } - - /** - * Sets the thread pool size (number of threads to use) for I/O operations (default value is the number of CPUs). - * - * @param ioThreadPoolSize the thread pool size - */ - public void setIoThreadPoolSize(int ioThreadPoolSize) { - this.ioThreadPoolSize = ioThreadPoolSize; - } - - public int getComputationThreadPoolSize() { - return computationThreadPoolSize; - } - - /** - * Sets the thread pool size (number of threads to use) for computation operations (default value is the number of CPUs). - * - * @param computationThreadPoolSize the thread pool size - */ - public void setComputationThreadPoolSize(int computationThreadPoolSize) { - this.computationThreadPoolSize = computationThreadPoolSize; - } - - @Override - public Class getObjectType() { - return ClientResources.class; - } - - @Override - protected ClientResources createInstance() throws Exception { - return DefaultClientResources.builder().computationThreadPoolSize(computationThreadPoolSize) - .ioThreadPoolSize(ioThreadPoolSize).build(); - } - - @Override - protected void destroyInstance(ClientResources instance) throws Exception { - instance.shutdown().get(); - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/src/main/java/io/lettuce/core/support/LettuceFactoryBeanSupport.java b/src/main/java/io/lettuce/core/support/LettuceFactoryBeanSupport.java deleted file mode 100644 index 8db6eb17e7..0000000000 --- a/src/main/java/io/lettuce/core/support/LettuceFactoryBeanSupport.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2011-2020 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.support; - -import java.net.URI; - -import org.springframework.beans.factory.config.AbstractFactoryBean; - -import io.lettuce.core.RedisURI; -import io.lettuce.core.resource.ClientResources; - -/** - * Adapter for Springs {@link org.springframework.beans.factory.FactoryBean} interface to allow easy setup of - * {@link io.lettuce.core.RedisClient} factories via Spring configuration. - * - * @author Mark Paluch - * @since 3.0 - */ -public abstract class LettuceFactoryBeanSupport extends AbstractFactoryBean { - - public static final String URI_SCHEME_REDIS_SENTINEL = "redis-sentinel"; - - private char[] password = new char[0]; - - private URI uri; - - private RedisURI redisURI; - - private ClientResources clientResources; - - @Override - public void afterPropertiesSet() throws Exception { - if (getRedisURI() == null && getUri() == null) { - throw new IllegalArgumentException("Either uri or redisURI must be set"); - } - super.afterPropertiesSet(); - } - - public URI getUri() { - return uri; - } - - /** - * Set the URI for connecting Redis. The URI follows the URI conventions. See {@link RedisURI} for URL schemes. Either the - * URI of the RedisURI must be set in order to connect to Redis. - * - * @param uri the URI - */ - public void setUri(URI uri) { - this.uri = uri; - } - - public RedisURI getRedisURI() { - return redisURI; - } - - /** - * Set the RedisURI for connecting Redis. See {@link RedisURI} for URL schemes. Either the URI of the RedisURI must be set - * in order to connect to Redis. - * - * @param redisURI the RedisURI - */ - public void setRedisURI(RedisURI redisURI) { - this.redisURI = redisURI; - } - - public String getPassword() { - return new String(password); - } - - /** - * Sets the password to use for a Redis connection. If the password is set, it has higher precedence than the password - * provided within the URI meaning the password from the URI is replaced by this one. - * - * @param password the password - */ - public void setPassword(String password) { - - if (password == null) { - this.password = new char[0]; - } else { - this.password = password.toCharArray(); - } - } - - public ClientResources getClientResources() { - return clientResources; - } - - /** - * Set shared client resources to reuse across different client instances. If not set, each client instance will provide - * their own {@link ClientResources} instance. - * - * @param clientResources the client resources - */ - public void setClientResources(ClientResources clientResources) { - this.clientResources = clientResources; - } - - @Override - public boolean isSingleton() { - return true; - } - -} diff --git a/src/main/java/io/lettuce/core/support/RedisClientFactoryBean.java b/src/main/java/io/lettuce/core/support/RedisClientFactoryBean.java deleted file mode 100644 index 1e54d419f4..0000000000 --- a/src/main/java/io/lettuce/core/support/RedisClientFactoryBean.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011-2020 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.support; - -import static io.lettuce.core.internal.LettuceStrings.isNotEmpty; - -import io.lettuce.core.RedisClient; -import io.lettuce.core.RedisURI; - -/** - * Factory Bean for {@link RedisClient} instances. Needs either a {@link java.net.URI} or a {@link RedisURI} as input and allows - * to reuse {@link io.lettuce.core.resource.ClientResources}. URI Formats: {@code - * redis-sentinel://host[:port][,host2[:port2]][/databaseNumber]#sentinelMasterId - * } - * - * {@code - * redis://host[:port][/databaseNumber] - * } - * - * @see RedisURI - * @see ClientResourcesFactoryBean - * @author Mark Paluch - * @since 3.0 - */ -public class RedisClientFactoryBean extends LettuceFactoryBeanSupport { - - @Override - public void afterPropertiesSet() throws Exception { - - if (getRedisURI() == null) { - RedisURI redisURI = RedisURI.create(getUri()); - - if (isNotEmpty(getPassword())) { - redisURI.setPassword(getPassword()); - } - setRedisURI(redisURI); - } - - super.afterPropertiesSet(); - } - - @Override - protected void destroyInstance(RedisClient instance) throws Exception { - instance.shutdown(); - } - - @Override - public Class getObjectType() { - return RedisClient.class; - } - - @Override - protected RedisClient createInstance() throws Exception { - - if (getClientResources() != null) { - return RedisClient.create(getClientResources(), getRedisURI()); - } - return RedisClient.create(getRedisURI()); - } - -} diff --git a/src/main/java/io/lettuce/core/support/RedisClusterClientFactoryBean.java b/src/main/java/io/lettuce/core/support/RedisClusterClientFactoryBean.java deleted file mode 100644 index f3f5682521..0000000000 --- a/src/main/java/io/lettuce/core/support/RedisClusterClientFactoryBean.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2011-2020 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.support; - -import static io.lettuce.core.internal.LettuceStrings.isNotEmpty; - -import java.net.URI; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import io.lettuce.core.RedisURI; -import io.lettuce.core.cluster.RedisClusterClient; -import io.lettuce.core.cluster.RedisClusterURIUtil; -import io.lettuce.core.internal.LettuceAssert; - -/** - * Factory Bean for {@link RedisClusterClient} instances. Needs either a {@link URI} or a {@link RedisURI} as input and allows - * to reuse {@link io.lettuce.core.resource.ClientResources}. URI Format: {@code - * redis://[password@]host[:port][,host2[:port2]] - * } - * - * {@code - * rediss://[password@]host[:port][,host2[:port2]] - * } - * - * @see RedisURI - * @see ClientResourcesFactoryBean - * @author Mark Paluch - * @since 3.0 - */ -public class RedisClusterClientFactoryBean extends LettuceFactoryBeanSupport { - - private boolean verifyPeer = false; - - private Collection redisURIs; - - @Override - public void afterPropertiesSet() throws Exception { - - if (redisURIs == null) { - - if (getUri() != null) { - URI uri = getUri(); - - LettuceAssert.isTrue(!uri.getScheme().equals(RedisURI.URI_SCHEME_REDIS_SENTINEL), - "Sentinel mode not supported when using RedisClusterClient"); - - List redisURIs = RedisClusterURIUtil.toRedisURIs(uri); - - for (RedisURI redisURI : redisURIs) { - applyProperties(uri.getScheme(), redisURI); - } - - this.redisURIs = redisURIs; - } else { - - URI uri = getRedisURI().toURI(); - RedisURI redisURI = RedisURI.create(uri); - applyProperties(uri.getScheme(), redisURI); - this.redisURIs = Collections.singleton(redisURI); - } - } - - super.afterPropertiesSet(); - } - - private void applyProperties(String scheme, RedisURI redisURI) { - - if (isNotEmpty(getPassword())) { - redisURI.setPassword(getPassword()); - } - - if (RedisURI.URI_SCHEME_REDIS_SECURE.equals(scheme) || RedisURI.URI_SCHEME_REDIS_SECURE_ALT.equals(scheme) - || RedisURI.URI_SCHEME_REDIS_TLS_ALT.equals(scheme)) { - redisURI.setVerifyPeer(verifyPeer); - } - } - - protected Collection getRedisURIs() { - return redisURIs; - } - - @Override - protected void destroyInstance(RedisClusterClient instance) throws Exception { - instance.shutdown(); - } - - @Override - public Class getObjectType() { - return RedisClusterClient.class; - } - - @Override - protected RedisClusterClient createInstance() throws Exception { - - if (getClientResources() != null) { - return RedisClusterClient.create(getClientResources(), redisURIs); - } - - return RedisClusterClient.create(redisURIs); - } - - public boolean isVerifyPeer() { - return verifyPeer; - } - - public void setVerifyPeer(boolean verifyPeer) { - this.verifyPeer = verifyPeer; - } - -} diff --git a/src/test/java/io/lettuce/apigenerator/CompilationUnitFactory.java b/src/test/java/io/lettuce/apigenerator/CompilationUnitFactory.java index 87e039c888..c63f24f107 100644 --- a/src/test/java/io/lettuce/apigenerator/CompilationUnitFactory.java +++ b/src/test/java/io/lettuce/apigenerator/CompilationUnitFactory.java @@ -24,7 +24,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import org.springframework.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.github.javaparser.JavaParser; import com.github.javaparser.ast.*; diff --git a/src/test/java/io/lettuce/core/ClientMetricsIntegrationTests.java b/src/test/java/io/lettuce/core/ClientMetricsIntegrationTests.java index 03cbecbd79..2b2b33c5ff 100644 --- a/src/test/java/io/lettuce/core/ClientMetricsIntegrationTests.java +++ b/src/test/java/io/lettuce/core/ClientMetricsIntegrationTests.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import reactor.core.Disposable; import io.lettuce.core.api.StatefulRedisConnection; diff --git a/src/test/java/io/lettuce/core/RedisClientFactoryBeanUnitTests.java b/src/test/java/io/lettuce/core/RedisClientFactoryBeanUnitTests.java deleted file mode 100644 index 6c6559ba1b..0000000000 --- a/src/test/java/io/lettuce/core/RedisClientFactoryBeanUnitTests.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2011-2020 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 static org.assertj.core.api.Assertions.assertThat; - -import java.net.URI; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import io.lettuce.core.support.RedisClientFactoryBean; -import io.lettuce.test.resource.FastShutdown; - -/** - * @author Mark Paluch - */ -class RedisClientFactoryBeanUnitTests { - - private RedisClientFactoryBean sut = new RedisClientFactoryBean(); - - @AfterEach - void tearDown() throws Exception { - FastShutdown.shutdown(sut.getObject()); - sut.destroy(); - } - - @Test - void testSimpleUri() throws Exception { - String uri = "redis://localhost/2"; - - sut.setUri(URI.create(uri)); - sut.setPassword("password"); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(2); - assertThat(redisURI.getHost()).isEqualTo("localhost"); - assertThat(redisURI.getPort()).isEqualTo(RedisURI.DEFAULT_REDIS_PORT); - assertThat(new String(redisURI.getPassword())).isEqualTo("password"); - } - - @Test - void testSimpleUriWithoutDB() throws Exception { - String uri = "redis://localhost/"; - - sut.setUri(URI.create(uri)); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(0); - } - - @Test - void testSimpleUriWithoutDB2() throws Exception { - String uri = "redis://localhost/"; - - sut.setUri(URI.create(uri)); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(0); - } - - @Test - void testSimpleUriWithPort() throws Exception { - String uri = "redis://localhost:1234/0"; - - sut.setUri(URI.create(uri)); - sut.setPassword("password"); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(0); - assertThat(redisURI.getHost()).isEqualTo("localhost"); - assertThat(redisURI.getPort()).isEqualTo(1234); - assertThat(new String(redisURI.getPassword())).isEqualTo("password"); - } - - @Test - void testSentinelUri() throws Exception { - String uri = "redis-sentinel://localhost/1#myMaster"; - - sut.setUri(URI.create(uri)); - sut.setPassword("password"); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(1); - - RedisURI sentinelUri = redisURI.getSentinels().get(0); - assertThat(sentinelUri.getHost()).isEqualTo("localhost"); - assertThat(sentinelUri.getPort()).isEqualTo(RedisURI.DEFAULT_SENTINEL_PORT); - assertThat(new String(redisURI.getPassword())).isEqualTo("password"); - assertThat(redisURI.getSentinelMasterId()).isEqualTo("myMaster"); - } - - @Test - void testSentinelUriWithPort() throws Exception { - String uri = "redis-sentinel://localhost:1234/1#myMaster"; - - sut.setUri(URI.create(uri)); - sut.setPassword("password"); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(1); - - RedisURI sentinelUri = redisURI.getSentinels().get(0); - assertThat(sentinelUri.getHost()).isEqualTo("localhost"); - assertThat(sentinelUri.getPort()).isEqualTo(1234); - assertThat(new String(redisURI.getPassword())).isEqualTo("password"); - assertThat(redisURI.getSentinelMasterId()).isEqualTo("myMaster"); - } - - @Test - void testMultipleSentinelUri() throws Exception { - String uri = "redis-sentinel://localhost,localhost2,localhost3/1#myMaster"; - - sut.setUri(URI.create(uri)); - sut.setPassword("password"); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(1); - assertThat(redisURI.getSentinels()).hasSize(3); - - RedisURI sentinelUri = redisURI.getSentinels().get(0); - assertThat(sentinelUri.getHost()).isEqualTo("localhost"); - assertThat(sentinelUri.getPort()).isEqualTo(RedisURI.DEFAULT_SENTINEL_PORT); - assertThat(redisURI.getSentinelMasterId()).isEqualTo("myMaster"); - } - - @Test - void testMultipleSentinelUriWithPorts() throws Exception { - String uri = "redis-sentinel://localhost,localhost2:1234,localhost3/1#myMaster"; - - sut.setUri(URI.create(uri)); - sut.setPassword("password"); - sut.afterPropertiesSet(); - - RedisURI redisURI = sut.getRedisURI(); - - assertThat(redisURI.getDatabase()).isEqualTo(1); - assertThat(redisURI.getSentinels()).hasSize(3); - - RedisURI sentinelUri1 = redisURI.getSentinels().get(0); - assertThat(sentinelUri1.getHost()).isEqualTo("localhost"); - assertThat(sentinelUri1.getPort()).isEqualTo(RedisURI.DEFAULT_SENTINEL_PORT); - - RedisURI sentinelUri2 = redisURI.getSentinels().get(1); - assertThat(sentinelUri2.getHost()).isEqualTo("localhost2"); - assertThat(sentinelUri2.getPort()).isEqualTo(1234); - assertThat(redisURI.getSentinelMasterId()).isEqualTo("myMaster"); - } -} diff --git a/src/test/java/io/lettuce/core/RedisClientUnitTests.java b/src/test/java/io/lettuce/core/RedisClientUnitTests.java index e121dc4b14..8013a2ca7a 100644 --- a/src/test/java/io/lettuce/core/RedisClientUnitTests.java +++ b/src/test/java/io/lettuce/core/RedisClientUnitTests.java @@ -23,6 +23,7 @@ import static org.mockito.Mockito.when; import java.io.Closeable; +import java.lang.reflect.Field; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -30,10 +31,10 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; import io.lettuce.core.internal.AsyncCloseable; import io.lettuce.core.resource.ClientResources; +import io.lettuce.test.ReflectionTestUtils; import io.netty.util.concurrent.ImmediateEventExecutor; /** @@ -52,7 +53,7 @@ class RedisClientUnitTests { AsyncCloseable asyncCloseable; @Test - void shutdownShouldDeferResourcesShutdown() { + void shutdownShouldDeferResourcesShutdown() throws Exception { when(clientResources.eventExecutorGroup()).thenReturn(ImmediateEventExecutor.INSTANCE); @@ -60,7 +61,10 @@ void shutdownShouldDeferResourcesShutdown() { when(asyncCloseable.closeAsync()).thenReturn(completableFuture); RedisClient redisClient = RedisClient.create(clientResources, "redis://foo"); - ReflectionTestUtils.setField(redisClient, "sharedResources", false); + + Field field = AbstractRedisClient.class.getDeclaredField("sharedResources"); + field.setAccessible(true); + field.set(redisClient, false); Set closeableResources = (Set) ReflectionTestUtils.getField(redisClient, "closeableResources"); closeableResources.add(asyncCloseable); @@ -73,7 +77,7 @@ void shutdownShouldDeferResourcesShutdown() { } @Test - void shutdownShutsDownResourcesAfterChannels() { + void shutdownShutsDownResourcesAfterChannels() throws Exception { when(clientResources.eventExecutorGroup()).thenReturn(ImmediateEventExecutor.INSTANCE); @@ -81,7 +85,10 @@ void shutdownShutsDownResourcesAfterChannels() { when(asyncCloseable.closeAsync()).thenReturn(completableFuture); RedisClient redisClient = RedisClient.create(clientResources, "redis://foo"); - ReflectionTestUtils.setField(redisClient, "sharedResources", false); + + Field field = AbstractRedisClient.class.getDeclaredField("sharedResources"); + field.setAccessible(true); + field.set(redisClient, false); Set closeableResources = (Set) ReflectionTestUtils.getField(redisClient, "closeableResources"); closeableResources.add(asyncCloseable); diff --git a/src/test/java/io/lettuce/core/cluster/AsyncConnectionProviderIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/AsyncConnectionProviderIntegrationTests.java index ca9e4ba710..d5cd6bc022 100644 --- a/src/test/java/io/lettuce/core/cluster/AsyncConnectionProviderIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/AsyncConnectionProviderIntegrationTests.java @@ -28,12 +28,11 @@ import javax.inject.Inject; +import org.apache.commons.lang3.time.StopWatch; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.util.SocketUtils; -import org.springframework.util.StopWatch; import reactor.core.publisher.Mono; import io.lettuce.core.ConnectionFuture; @@ -71,7 +70,7 @@ class AsyncConnectionProviderIntegrationTests { @BeforeEach void before() throws Exception { - serverSocket = new ServerSocket(SocketUtils.findAvailableTcpPort(), 1); + serverSocket = new ServerSocket(9393, 1); client = RedisClusterClient.create(resources, "redis://localhost"); client.setOptions(ClusterClientOptions.builder().protocolVersion(ProtocolVersion.RESP2).build()); @@ -153,7 +152,7 @@ void connectShouldFail() throws Exception { stopWatch.stop(); - assertThat(stopWatch.getLastTaskTimeMillis()).isBetween(0L, 1200L); + assertThat(TimeUnit.NANOSECONDS.toMillis(stopWatch.getNanoTime())).isBetween(0L, 1200L); sut.close(); @@ -199,7 +198,7 @@ void connectShouldFailConcurrently() throws Exception { stopWatch.stop(); - assertThat(stopWatch.getLastTaskTimeMillis()).isBetween(0L, 1300L); + assertThat(TimeUnit.NANOSECONDS.toMillis(stopWatch.getNanoTime())).isBetween(0L, 1300L); sut.close(); socket.close(); diff --git a/src/test/java/io/lettuce/core/cluster/ClusterNodeEndpointUnitTests.java b/src/test/java/io/lettuce/core/cluster/ClusterNodeEndpointUnitTests.java index 9ecba5f1d0..286891a09e 100644 --- a/src/test/java/io/lettuce/core/cluster/ClusterNodeEndpointUnitTests.java +++ b/src/test/java/io/lettuce/core/cluster/ClusterNodeEndpointUnitTests.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.ClientOptions; import io.lettuce.core.RedisChannelWriter; 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 bd15113f07..46f7c668c3 100644 --- a/src/test/java/io/lettuce/core/cluster/topology/TopologyRefreshIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/topology/TopologyRefreshIntegrationTests.java @@ -32,7 +32,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.category.SlowTests; import io.lettuce.core.RedisClient; diff --git a/src/test/java/io/lettuce/core/dynamic/ParameterBinderUnitTests.java b/src/test/java/io/lettuce/core/dynamic/ParameterBinderUnitTests.java index cb3978445c..e43a3444e8 100644 --- a/src/test/java/io/lettuce/core/dynamic/ParameterBinderUnitTests.java +++ b/src/test/java/io/lettuce/core/dynamic/ParameterBinderUnitTests.java @@ -18,18 +18,18 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import java.util.Base64; import java.util.Collections; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.util.Base64Utils; -import org.springframework.util.ReflectionUtils; import io.lettuce.core.*; import io.lettuce.core.codec.StringCodec; import io.lettuce.core.dynamic.segment.CommandSegment; import io.lettuce.core.dynamic.segment.CommandSegments; +import io.lettuce.core.dynamic.support.ReflectionUtils; import io.lettuce.core.protocol.CommandArgs; import io.lettuce.core.protocol.CommandType; @@ -159,8 +159,8 @@ void bindsValueRangeCorrectly() { Range.from(Range.Boundary.including("lower"), Range.Boundary.excluding("upper"))); assertThat(args.toCommandString()).isEqualTo( - String.format("%s %s", Base64Utils.encodeToString("[lower".getBytes()), - Base64Utils.encodeToString("(upper".getBytes()))); + String.format("%s %s", Base64.getEncoder().encodeToString("[lower".getBytes()), + Base64.getEncoder().encodeToString("(upper".getBytes()))); } @Test @@ -172,7 +172,8 @@ void bindsUnboundedValueRangeCorrectly() { CommandArgs args = bind(commandMethod, Range.unbounded()); assertThat(args.toCommandString()).isEqualTo( - String.format("%s %s", Base64Utils.encodeToString("-".getBytes()), Base64Utils.encodeToString("+".getBytes()))); + String.format("%s %s", Base64.getEncoder().encodeToString("-".getBytes()), + Base64.getEncoder().encodeToString("+".getBytes()))); } @Test @@ -192,7 +193,8 @@ void bindsProtocolKeywordCorrectly() { } private CommandArgs bind(Object object) { - CommandMethod commandMethod = DeclaredCommandMethod.create(ReflectionUtils.findMethod(MyCommands.class, "justObject", + CommandMethod commandMethod = DeclaredCommandMethod + .create(ReflectionUtils.findMethod(MyCommands.class, "justObject", Object.class)); return bind(commandMethod, object); } diff --git a/src/test/java/io/lettuce/core/masterreplica/SentinelTopologyRefreshUnitTests.java b/src/test/java/io/lettuce/core/masterreplica/SentinelTopologyRefreshUnitTests.java index 0734b32b4d..2de38ca975 100644 --- a/src/test/java/io/lettuce/core/masterreplica/SentinelTopologyRefreshUnitTests.java +++ b/src/test/java/io/lettuce/core/masterreplica/SentinelTopologyRefreshUnitTests.java @@ -36,7 +36,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.ConnectionFuture; import io.lettuce.core.RedisClient; diff --git a/src/test/java/io/lettuce/core/masterslave/MasterSlaveSentinelIntegrationTests.java b/src/test/java/io/lettuce/core/masterslave/MasterSlaveSentinelIntegrationTests.java index 5debedcd02..bebeb5f5de 100644 --- a/src/test/java/io/lettuce/core/masterslave/MasterSlaveSentinelIntegrationTests.java +++ b/src/test/java/io/lettuce/core/masterslave/MasterSlaveSentinelIntegrationTests.java @@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.*; import io.lettuce.core.codec.StringCodec; diff --git a/src/test/java/io/lettuce/core/metrics/DefaultCommandLatencyCollectorUnitTests.java b/src/test/java/io/lettuce/core/metrics/DefaultCommandLatencyCollectorUnitTests.java index 0cf0fdaa8b..ef2af4c014 100644 --- a/src/test/java/io/lettuce/core/metrics/DefaultCommandLatencyCollectorUnitTests.java +++ b/src/test/java/io/lettuce/core/metrics/DefaultCommandLatencyCollectorUnitTests.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.metrics.DefaultCommandLatencyCollector.PauseDetectorWrapper; import io.lettuce.core.protocol.CommandType; diff --git a/src/test/java/io/lettuce/core/protocol/CommandHandlerUnitTests.java b/src/test/java/io/lettuce/core/protocol/CommandHandlerUnitTests.java index b0a2262460..ea5cd71028 100644 --- a/src/test/java/io/lettuce/core/protocol/CommandHandlerUnitTests.java +++ b/src/test/java/io/lettuce/core/protocol/CommandHandlerUnitTests.java @@ -43,7 +43,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.springframework.test.util.ReflectionTestUtils; import io.lettuce.core.ClientOptions; import io.lettuce.core.RedisException; @@ -55,6 +54,7 @@ import io.lettuce.core.resource.ClientResources; import io.lettuce.core.tracing.Tracing; import io.lettuce.test.Delay; +import io.lettuce.test.ReflectionTestUtils; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.Unpooled; @@ -184,7 +184,7 @@ void testExceptionWithQueue() throws Exception { assertThat(stack).isEmpty(); command.get(); - assertThat(ReflectionTestUtils.getField(command, "exception")).isNotNull(); + assertThat((Object) ReflectionTestUtils.getField(command, "exception")).isNotNull(); } @Test @@ -462,7 +462,7 @@ void shouldNotDiscardReadBytes() throws Exception { // set the command handler buffer capacity to 30, make it easy to test ByteBuf internalBuffer = context.alloc().buffer(30); - ReflectionTestUtils.setField(sut, "buffer", internalBuffer); + sut.setBuffer(internalBuffer); // mock a multi reply, which will reach the buffer usage ratio ByteBuf msg = context.alloc().buffer(100); @@ -491,7 +491,7 @@ void shouldDiscardReadBytes() throws Exception { // set the command handler buffer capacity to 30, make it easy to test ByteBuf internalBuffer = context.alloc().buffer(30); - ReflectionTestUtils.setField(sut, "buffer", internalBuffer); + sut.setBuffer(internalBuffer); // mock a multi reply, which will reach the buffer usage ratio ByteBuf msg = context.alloc().buffer(100); diff --git a/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java b/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java index 5ca5f94fcc..23efeaee25 100644 --- a/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java +++ b/src/test/java/io/lettuce/core/protocol/ConnectionFailureIntegrationTests.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; +import java.lang.reflect.Field; import java.net.InetSocketAddress; import java.time.Duration; import java.util.Comparator; @@ -33,7 +34,9 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.util.ReflectionTestUtils; +import org.junit.platform.commons.util.ReflectionUtils; + +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.*; import io.lettuce.core.api.StatefulRedisConnection; @@ -161,7 +164,9 @@ void failOnReconnectShouldSendEvents() throws Exception { ReconnectionListener reconnectionListener = events::offer; - ReflectionTestUtils.setField(connectionWatchdog, "reconnectionListener", reconnectionListener); + Field field = ConnectionWatchdog.class.getDeclaredField("reconnectionListener"); + field.setAccessible(true); + field.set(connectionWatchdog, reconnectionListener); redisUri.setPort(TestSettings.nonexistentPort()); diff --git a/src/test/java/io/lettuce/core/protocol/DefaultEndpointUnitTests.java b/src/test/java/io/lettuce/core/protocol/DefaultEndpointUnitTests.java index 55faab26c6..b48b258171 100644 --- a/src/test/java/io/lettuce/core/protocol/DefaultEndpointUnitTests.java +++ b/src/test/java/io/lettuce/core/protocol/DefaultEndpointUnitTests.java @@ -40,7 +40,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import edu.umd.cs.mtc.MultithreadedTestCase; import edu.umd.cs.mtc.TestFramework; diff --git a/src/test/java/io/lettuce/core/pubsub/PubSubCommandHandlerUnitTests.java b/src/test/java/io/lettuce/core/pubsub/PubSubCommandHandlerUnitTests.java index ef5cde1e8a..bc78fade2d 100644 --- a/src/test/java/io/lettuce/core/pubsub/PubSubCommandHandlerUnitTests.java +++ b/src/test/java/io/lettuce/core/pubsub/PubSubCommandHandlerUnitTests.java @@ -33,7 +33,6 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; import org.mockito.stubbing.Answer; -import org.springframework.test.util.ReflectionTestUtils; import io.lettuce.core.ClientOptions; import io.lettuce.core.codec.StringCodec; @@ -45,6 +44,7 @@ import io.lettuce.core.protocol.RedisCommand; import io.lettuce.core.resource.ClientResources; import io.lettuce.core.tracing.Tracing; +import io.lettuce.test.ReflectionTestUtils; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.Unpooled; @@ -118,7 +118,7 @@ void shouldCompleteCommandExceptionallyOnOutputFailure() throws Exception { sut.channelRead(context, responseBytes(":1000\r\n")); - assertThat(ReflectionTestUtils.getField(command, "exception")).isInstanceOf(IllegalStateException.class); + assertThat((Object) ReflectionTestUtils.getField(command, "exception")).isInstanceOf(IllegalStateException.class); } @Test diff --git a/src/test/java/io/lettuce/core/resource/DefaultClientResourcesUnitTests.java b/src/test/java/io/lettuce/core/resource/DefaultClientResourcesUnitTests.java index 3fc5a71b48..24e1e9761e 100644 --- a/src/test/java/io/lettuce/core/resource/DefaultClientResourcesUnitTests.java +++ b/src/test/java/io/lettuce/core/resource/DefaultClientResourcesUnitTests.java @@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; -import org.springframework.test.util.ReflectionTestUtils; import reactor.test.StepVerifier; import io.lettuce.core.event.Event; @@ -223,14 +222,14 @@ void considersSharedStateFromMutation() { ClientResources clientResources = ClientResources.create(); HashedWheelTimer timer = (HashedWheelTimer) clientResources.timer(); - assertThat(ReflectionTestUtils.getField(timer, "workerState")).isEqualTo(0); + assertThat(timer).hasFieldOrPropertyWithValue("workerState", 0); ClientResources copy = clientResources.mutate().build(); assertThat(copy.timer()).isSameAs(timer); copy.shutdown().awaitUninterruptibly(); - assertThat(ReflectionTestUtils.getField(timer, "workerState")).isEqualTo(2); + assertThat(timer).hasFieldOrPropertyWithValue("workerState", 2); } @Test @@ -239,7 +238,7 @@ void considersDecoupledSharedStateFromMutation() { ClientResources clientResources = ClientResources.create(); HashedWheelTimer timer = (HashedWheelTimer) clientResources.timer(); - assertThat(ReflectionTestUtils.getField(timer, "workerState")).isEqualTo(0); + assertThat(timer).hasFieldOrPropertyWithValue("workerState", 0); ClientResources copy = clientResources.mutate().timer(new HashedWheelTimer()).build(); HashedWheelTimer copyTimer = (HashedWheelTimer) copy.timer(); @@ -247,8 +246,8 @@ void considersDecoupledSharedStateFromMutation() { copy.shutdown().awaitUninterruptibly(); - assertThat(ReflectionTestUtils.getField(timer, "workerState")).isEqualTo(0); - assertThat(ReflectionTestUtils.getField(copyTimer, "workerState")).isEqualTo(0); + assertThat(timer).hasFieldOrPropertyWithValue("workerState", 0); + assertThat(copyTimer).hasFieldOrPropertyWithValue("workerState", 0); copyTimer.stop(); timer.stop(); diff --git a/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java b/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java index 64777e10a3..a090d1f04c 100644 --- a/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java +++ b/src/test/java/io/lettuce/core/support/AsyncConnectionPoolSupportIntegrationTests.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.springframework.test.util.ReflectionTestUtils; import io.lettuce.core.*; import io.lettuce.core.api.StatefulRedisConnection; @@ -35,6 +34,7 @@ import io.lettuce.core.api.sync.RedisCommands; import io.lettuce.core.cluster.StatefulRedisClusterConnectionImpl; import io.lettuce.core.codec.StringCodec; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.test.TestFutures; import io.lettuce.test.resource.FastShutdown; import io.lettuce.test.resource.TestClientResources; diff --git a/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java b/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java index 0bf4328466..01ebb442d4 100644 --- a/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java +++ b/src/test/java/io/lettuce/core/support/ConnectionPoolSupportIntegrationTests.java @@ -28,7 +28,7 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.*; import io.lettuce.core.api.StatefulRedisConnection; diff --git a/src/test/java/io/lettuce/core/support/RedisClusterClientFactoryBeanUnitTests.java b/src/test/java/io/lettuce/core/support/RedisClusterClientFactoryBeanUnitTests.java deleted file mode 100644 index 91183094f2..0000000000 --- a/src/test/java/io/lettuce/core/support/RedisClusterClientFactoryBeanUnitTests.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2011-2020 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.support; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import java.net.URI; -import java.util.Collection; -import java.util.Iterator; - -import org.junit.jupiter.api.Test; - -import io.lettuce.core.RedisURI; - -/** - * @author Mark Paluch - */ -class RedisClusterClientFactoryBeanUnitTests { - - private RedisClusterClientFactoryBean sut = new RedisClusterClientFactoryBean(); - - @Test - void invalidUri() { - - sut.setUri(URI.create("http://www.web.de")); - assertThatThrownBy(() -> sut.afterPropertiesSet()).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void sentinelUri() { - - sut.setUri(URI.create(RedisURI.URI_SCHEME_REDIS_SENTINEL + "://www.web.de")); - assertThatThrownBy(() -> sut.afterPropertiesSet()).isInstanceOf(IllegalArgumentException.class); - } - - @Test - void validUri() throws Exception { - - sut.setUri(URI.create(RedisURI.URI_SCHEME_REDIS + "://password@host")); - sut.afterPropertiesSet(); - assertThat(getRedisURI().getHost()).isEqualTo("host"); - assertThat(getRedisURI().getPassword()).isEqualTo("password".toCharArray()); - - sut.destroy(); - } - - @Test - void validUriPasswordOverride() throws Exception { - - sut.setUri(URI.create(RedisURI.URI_SCHEME_REDIS + "://password@host")); - sut.setPassword("thepassword"); - - sut.afterPropertiesSet(); - assertThat(getRedisURI().getHost()).isEqualTo("host"); - assertThat(getRedisURI().getPassword()).isEqualTo("thepassword".toCharArray()); - - sut.destroy(); - } - - @Test - void multiNodeUri() throws Exception { - - sut.setUri(URI.create(RedisURI.URI_SCHEME_REDIS + "://password@host1,host2")); - sut.afterPropertiesSet(); - - Collection redisUris = sut.getRedisURIs(); - assertThat(redisUris).hasSize(2); - - Iterator iterator = redisUris.iterator(); - RedisURI host1 = iterator.next(); - RedisURI host2 = iterator.next(); - - assertThat(host1.getHost()).isEqualTo("host1"); - assertThat(host1.getPassword()).isEqualTo("password".toCharArray()); - - assertThat(host2.getHost()).isEqualTo("host2"); - assertThat(host2.getPassword()).isEqualTo("password".toCharArray()); - - sut.destroy(); - } - - @Test - void multiNodeUriPasswordOverride() throws Exception { - - sut.setUri(URI.create(RedisURI.URI_SCHEME_REDIS + "://password@host1,host2")); - sut.setPassword("thepassword"); - - sut.afterPropertiesSet(); - - Collection redisUris = sut.getRedisURIs(); - assertThat(redisUris).hasSize(2); - - Iterator iterator = redisUris.iterator(); - RedisURI host1 = iterator.next(); - RedisURI host2 = iterator.next(); - - assertThat(host1.getHost()).isEqualTo("host1"); - assertThat(host1.getPassword()).isEqualTo("thepassword".toCharArray()); - - assertThat(host2.getHost()).isEqualTo("host2"); - assertThat(host2.getPassword()).isEqualTo("thepassword".toCharArray()); - - sut.destroy(); - } - - @Test - void supportsSsl() throws Exception { - - sut.setUri(URI.create(RedisURI.URI_SCHEME_REDIS_SECURE + "://password@host")); - sut.afterPropertiesSet(); - - assertThat(getRedisURI().getHost()).isEqualTo("host"); - assertThat(getRedisURI().getPassword()).isEqualTo("password".toCharArray()); - assertThat(getRedisURI().isVerifyPeer()).isFalse(); - assertThat(getRedisURI().isSsl()).isTrue(); - - sut.destroy(); - } - - private RedisURI getRedisURI() { - return sut.getRedisURIs().iterator().next(); - } -} diff --git a/src/test/java/io/lettuce/core/support/SpringIntegrationTests.java b/src/test/java/io/lettuce/core/support/SpringIntegrationTests.java deleted file mode 100644 index c8477f1908..0000000000 --- a/src/test/java/io/lettuce/core/support/SpringIntegrationTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011-2020 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.support; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import io.lettuce.core.RedisClient; -import io.lettuce.core.cluster.RedisClusterClient; - -/** - * @author Mark Paluch - * @since 3.0 - */ -@RunWith(SpringRunner.class) -@ContextConfiguration -public class SpringIntegrationTests { - - @Autowired - @Qualifier("RedisClient1") - private RedisClient redisClient1; - - @Autowired - @Qualifier("RedisClient2") - private RedisClient redisClient2; - - @Autowired - @Qualifier("RedisClient3") - private RedisClient redisClient3; - - @Autowired - @Qualifier("RedisClusterClient1") - private RedisClusterClient redisClusterClient1; - - @Autowired - @Qualifier("RedisClusterClient2") - private RedisClusterClient redisClusterClient2; - - @Test - public void testSpring() { - - assertThat(redisClient1).isNotNull(); - assertThat(redisClient2).isNotNull(); - assertThat(redisClient3).isNotNull(); - assertThat(redisClusterClient1).isNotNull(); - assertThat(redisClusterClient2).isNotNull(); - } -} diff --git a/src/test/java/io/lettuce/core/tracing/BraveTracingUnitTests.java b/src/test/java/io/lettuce/core/tracing/BraveTracingUnitTests.java index 99bbc3f512..a38bf972a6 100644 --- a/src/test/java/io/lettuce/core/tracing/BraveTracingUnitTests.java +++ b/src/test/java/io/lettuce/core/tracing/BraveTracingUnitTests.java @@ -25,7 +25,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.protocol.AsyncCommand; import zipkin2.Span; diff --git a/src/test/java/io/lettuce/examples/MySpringBean.java b/src/test/java/io/lettuce/examples/MySpringBean.java deleted file mode 100644 index b7ad7f2dc2..0000000000 --- a/src/test/java/io/lettuce/examples/MySpringBean.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011-2020 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.examples; - -import org.springframework.beans.factory.annotation.Autowired; - -import io.lettuce.core.RedisClient; -import io.lettuce.core.api.StatefulRedisConnection; -import io.lettuce.core.api.sync.RedisCommands; - -/** - * @author Mark Paluch - */ -public class MySpringBean { - - private RedisClient redisClient; - - @Autowired - public void setRedisClient(RedisClient redisClient) { - this.redisClient = redisClient; - } - - public String ping() { - - StatefulRedisConnection connection = redisClient.connect(); - - RedisCommands sync = connection.sync(); - String result = sync.ping(); - connection.close(); - return result; - } -} diff --git a/src/test/java/io/lettuce/examples/SpringExample.java b/src/test/java/io/lettuce/examples/SpringExample.java deleted file mode 100644 index 599d1bf017..0000000000 --- a/src/test/java/io/lettuce/examples/SpringExample.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011-2020 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.examples; - -import org.springframework.context.support.ClassPathXmlApplicationContext; - -import io.lettuce.core.RedisClient; -import io.lettuce.core.api.StatefulRedisConnection; -import io.lettuce.core.api.sync.RedisCommands; - -/** - * @author Mark Paluch - */ -public class SpringExample { - - public static void main(String[] args) { - - ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( - "com/lambdaworks/examples/SpringTest-context.xml"); - - RedisClient client = context.getBean(RedisClient.class); - - StatefulRedisConnection connection = client.connect(); - - RedisCommands sync = connection.sync(); - System.out.println("PING: " + sync.ping()); - connection.close(); - - MySpringBean mySpringBean = context.getBean(MySpringBean.class); - System.out.println("PING: " + mySpringBean.ping()); - - context.close(); - } -} diff --git a/src/test/java/io/lettuce/test/ConnectionTestUtil.java b/src/test/java/io/lettuce/test/ConnectionTestUtil.java index eac6fba457..5889db41d0 100644 --- a/src/test/java/io/lettuce/test/ConnectionTestUtil.java +++ b/src/test/java/io/lettuce/test/ConnectionTestUtil.java @@ -18,7 +18,7 @@ import java.lang.reflect.UndeclaredThrowableException; import java.util.Queue; -import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.test.ReflectionTestUtils; import io.lettuce.core.RedisChannelHandler; import io.lettuce.core.RedisChannelWriter; diff --git a/src/test/java/io/lettuce/test/ReflectionTestUtils.java b/src/test/java/io/lettuce/test/ReflectionTestUtils.java new file mode 100644 index 0000000000..14141b713f --- /dev/null +++ b/src/test/java/io/lettuce/test/ReflectionTestUtils.java @@ -0,0 +1,159 @@ +/* + * Copyright 2020 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 io.lettuce.test; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + +import io.lettuce.core.dynamic.support.ReflectionUtils; +import io.lettuce.core.internal.LettuceAssert; + +/** + * Reflection test utility. + */ +public final class ReflectionTestUtils { + + /** + * Get the value of the {@linkplain Field field} with the given {@code name} from the provided {@code targetObject}. + *

+ * This method delegates to {@link #getField(Object, Class, String)}, supplying {@code null} for the {@code targetClass} + * argument. + * + * @param targetObject the target object from which to get the field; never {@code null} + * @param name the name of the field to get; never {@code null} + * @return the field's current value + * @see #getField(Class, String) + */ + public static T getField(Object targetObject, String name) { + return getField(targetObject, null, name); + } + + /** + * Get the value of the static {@linkplain Field field} with the given {@code name} from the provided {@code targetClass}. + *

+ * This method delegates to {@link #getField(Object, Class, String)}, supplying {@code null} for the {@code targetObject} + * argument. + * + * @param targetClass the target class from which to get the static field; never {@code null} + * @param name the name of the field to get; never {@code null} + * @return the field's current value + * @see #getField(Object, String) + */ + public static T getField(Class targetClass, String name) { + return getField(null, targetClass, name); + } + + /** + * Get the value of the {@linkplain Field field} with the given {@code name} from the provided + * {@code targetObject}/{@code targetClass}. + *

+ * This method traverses the class hierarchy in search of the desired field. In addition, an attempt will be made to make + * non-{@code public} fields accessible, thus allowing one to get {@code protected}, {@code private}, and + * package-private fields. + * + * @param targetObject the target object from which to get the field; may be {@code null} if the field is static + * @param targetClass the target class from which to get the field; may be {@code null} if the field is an instance field + * @param name the name of the field to get; never {@code null} + * @return the field's current value + */ + public static T getField(Object targetObject, Class targetClass, String name) { + LettuceAssert.isTrue(targetObject != null || targetClass != null, + "Either targetObject or targetClass for the field must be specified"); + + if (targetClass == null) { + targetClass = targetObject.getClass(); + } + + Field field = findField(targetClass, name); + if (field == null) { + throw new IllegalArgumentException(String.format("Could not find field '%s' on %s or target class [%s]", name, + safeToString(targetObject), targetClass)); + } + + makeAccessible(field); + + try { + return (T) field.get(targetObject); + } catch (IllegalAccessException ex) { + ReflectionUtils.handleReflectionException(ex); + throw new IllegalStateException( + "Unexpected reflection exception - " + ex.getClass().getName() + ": " + ex.getMessage()); + } + } + + // Field handling + + /** + * Attempt to find a {@link Field field} on the supplied {@link Class} with the supplied {@code name}. Searches all + * superclasses up to {@link Object}. + * + * @param clazz the class to introspect + * @param name the name of the field + * @return the corresponding Field object, or {@code null} if not found + */ + public static Field findField(Class clazz, String name) { + return findField(clazz, name, null); + } + + /** + * Attempt to find a {@link Field field} on the supplied {@link Class} with the supplied {@code name} and/or {@link Class + * type}. Searches all superclasses up to {@link Object}. + * + * @param clazz the class to introspect + * @param name the name of the field (may be {@code null} if type is specified) + * @param type the type of the field (may be {@code null} if name is specified) + * @return the corresponding Field object, or {@code null} if not found + */ + public static Field findField(Class clazz, String name, Class type) { + LettuceAssert.notNull(clazz, "Class must not be null"); + LettuceAssert.isTrue(name != null || type != null, "Either name or type of the field must be specified"); + Class searchType = clazz; + while (Object.class != searchType && searchType != null) { + Field[] fields = searchType.getDeclaredFields(); + for (Field field : fields) { + if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) { + return field; + } + } + searchType = searchType.getSuperclass(); + } + return null; + } + + /** + * Make the given field accessible, explicitly setting it accessible if necessary. The {@code setAccessible(true)} method is + * only called when actually necessary, to avoid unnecessary conflicts with a JVM SecurityManager (if active). + * + * @param field the field to make accessible + * @see java.lang.reflect.Field#setAccessible + */ + private static void makeAccessible(Field field) { + if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) + || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) { + field.setAccessible(true); + } + } + + private static String safeToString(Object target) { + try { + return String.format("target object [%s]", target); + } catch (Exception ex) { + return String.format("target of type [%s] whose toString() method threw [%s]", + (target != null ? target.getClass().getName() : "unknown"), ex); + } + } + +} diff --git a/src/test/java/io/lettuce/test/condition/RedisConditions.java b/src/test/java/io/lettuce/test/condition/RedisConditions.java index 43da6f3212..8fad068b29 100644 --- a/src/test/java/io/lettuce/test/condition/RedisConditions.java +++ b/src/test/java/io/lettuce/test/condition/RedisConditions.java @@ -23,13 +23,12 @@ import java.util.Properties; import java.util.stream.Collectors; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - 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.sync.RedisClusterCommands; +import io.lettuce.core.internal.LettuceAssert; +import io.lettuce.core.internal.LettuceStrings; import io.lettuce.core.models.command.CommandDetail; import io.lettuce.core.models.command.CommandDetailParser; @@ -149,18 +148,19 @@ public static class Version implements Comparable { */ Version(int... parts) { - Assert.notNull(parts, "Parts must not be null!"); - Assert.isTrue(parts.length > 0 && parts.length < 5, String.format("Invalid parts length. 0 < %s < 5", parts.length)); + LettuceAssert.notNull(parts, "Parts must not be null!"); + LettuceAssert.isTrue(parts.length > 0 && parts.length < 5, + String.format("Invalid parts length. 0 < %s < 5", parts.length)); this.major = parts[0]; this.minor = parts.length > 1 ? parts[1] : 0; this.bugfix = parts.length > 2 ? parts[2] : 0; this.build = parts.length > 3 ? parts[3] : 0; - Assert.isTrue(major >= 0, "Major version must be greater or equal zero!"); - Assert.isTrue(minor >= 0, "Minor version must be greater or equal zero!"); - Assert.isTrue(bugfix >= 0, "Bugfix version must be greater or equal zero!"); - Assert.isTrue(build >= 0, "Build version must be greater or equal zero!"); + LettuceAssert.isTrue(major >= 0, "Major version must be greater or equal zero!"); + LettuceAssert.isTrue(minor >= 0, "Minor version must be greater or equal zero!"); + LettuceAssert.isTrue(bugfix >= 0, "Bugfix version must be greater or equal zero!"); + LettuceAssert.isTrue(build >= 0, "Build version must be greater or equal zero!"); } /** @@ -171,7 +171,7 @@ public static class Version implements Comparable { */ public static Version parse(String version) { - Assert.hasText(version, "Version must not be null o empty!"); + LettuceAssert.notEmpty(version, "Version must not be null o empty!"); String[] parts = version.trim().split("\\."); int[] intParts = new int[parts.length]; @@ -180,7 +180,7 @@ public static Version parse(String version) { String input = i == parts.length - 1 ? parts[i].replaceAll("\\D.*", "") : parts[i]; - if (StringUtils.hasText(input)) { + if (LettuceStrings.isNotEmpty(input)) { try { intParts[i] = Integer.parseInt(input); } catch (IllegalArgumentException o_O) { @@ -330,7 +330,7 @@ public String toString() { digits.add(build); } - return StringUtils.collectionToDelimitedString(digits, "."); + return digits.stream().map(Object::toString).collect(Collectors.joining(".")); } } } diff --git a/src/test/resources/io/lettuce/core/support/SpringIntegrationTests-context.xml b/src/test/resources/io/lettuce/core/support/SpringIntegrationTests-context.xml deleted file mode 100644 index 9264b08065..0000000000 --- a/src/test/resources/io/lettuce/core/support/SpringIntegrationTests-context.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -