Migrate RedisConnectionFactory to Lifecycle beans.
Closes: #2503 Original pull request: #2627
This commit is contained in:
committed by
Mark Paluch
parent
bc382ae042
commit
908a4d0d8a
@@ -34,6 +34,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
@@ -42,9 +43,9 @@ import javax.net.ssl.SSLSocketFactory;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
@@ -85,7 +86,7 @@ import org.springframework.util.ObjectUtils;
|
||||
* @see JedisClientConfiguration
|
||||
* @see Jedis
|
||||
*/
|
||||
public class JedisConnectionFactory implements InitializingBean, DisposableBean, RedisConnectionFactory {
|
||||
public class JedisConnectionFactory implements RedisConnectionFactory, InitializingBean, DisposableBean, SmartLifecycle {
|
||||
|
||||
private final static Log log = LogFactory.getLog(JedisConnectionFactory.class);
|
||||
private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new PassThroughExceptionTranslationStrategy(
|
||||
@@ -104,8 +105,11 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
private @Nullable ClusterTopologyProvider topologyProvider;
|
||||
private @Nullable ClusterCommandExecutor clusterCommandExecutor;
|
||||
|
||||
private boolean initialized;
|
||||
private boolean destroyed;
|
||||
enum State {
|
||||
CREATED, STARTING, STARTED, STOPPING, STOPPED, DESTROYED;
|
||||
}
|
||||
|
||||
private AtomicReference<State> state = new AtomicReference<>(State.CREATED);
|
||||
|
||||
/**
|
||||
* Constructs a new {@link JedisConnectionFactory} instance with default settings (default connection pooling).
|
||||
@@ -287,24 +291,80 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
State current = state.getAndUpdate(state -> {
|
||||
if (State.CREATED.equals(state) || State.STOPPED.equals(state)) {
|
||||
return State.STARTING;
|
||||
}
|
||||
return state;
|
||||
});
|
||||
|
||||
if (State.CREATED.equals(current) || State.STOPPED.equals(current)) {
|
||||
|
||||
if (getUsePool() && !isRedisClusterAware()) {
|
||||
this.pool = createPool();
|
||||
}
|
||||
|
||||
if (isRedisClusterAware()) {
|
||||
|
||||
this.cluster = createCluster();
|
||||
this.topologyProvider = createTopologyProvider(this.cluster);
|
||||
this.clusterCommandExecutor = new ClusterCommandExecutor(this.topologyProvider,
|
||||
new JedisClusterConnection.JedisClusterNodeResourceProvider(this.cluster, this.topologyProvider),
|
||||
EXCEPTION_TRANSLATION);
|
||||
}
|
||||
|
||||
state.set(State.STARTED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
if (state.compareAndSet(State.STARTED, State.STOPPING)) {
|
||||
if (getUsePool() && !isRedisClusterAware()) {
|
||||
if (pool != null) {
|
||||
try {
|
||||
this.pool.close();
|
||||
} catch (Exception ex) {
|
||||
log.warn("Cannot properly close Jedis pool", ex);
|
||||
}
|
||||
this.pool = null;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.clusterCommandExecutor != null) {
|
||||
try {
|
||||
this.clusterCommandExecutor.destroy();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.cluster != null) {
|
||||
|
||||
this.topologyProvider = null;
|
||||
|
||||
try {
|
||||
cluster.close();
|
||||
} catch (Exception ex) {
|
||||
log.warn("Cannot properly close Jedis cluster", ex);
|
||||
}
|
||||
}
|
||||
state.set(State.STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return State.STARTED.equals(state.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
clientConfig = createClientConfig(getDatabase(), getRedisUsername(), getRedisPassword());
|
||||
|
||||
if (getUsePool() && !isRedisClusterAware()) {
|
||||
this.pool = createPool();
|
||||
}
|
||||
|
||||
if (isRedisClusterAware()) {
|
||||
|
||||
this.cluster = createCluster();
|
||||
this.topologyProvider = createTopologyProvider(this.cluster);
|
||||
this.clusterCommandExecutor = new ClusterCommandExecutor(this.topologyProvider,
|
||||
new JedisClusterConnection.JedisClusterNodeResourceProvider(this.cluster, this.topologyProvider),
|
||||
EXCEPTION_TRANSLATION);
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
JedisClientConfig createSentinelClientConfig(SentinelConfiguration sentinelConfiguration) {
|
||||
@@ -415,32 +475,8 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
|
||||
public void destroy() {
|
||||
|
||||
if (getUsePool() && pool != null) {
|
||||
|
||||
try {
|
||||
pool.destroy();
|
||||
} catch (Exception ex) {
|
||||
log.warn("Cannot properly close Jedis pool", ex);
|
||||
}
|
||||
pool = null;
|
||||
}
|
||||
|
||||
if (cluster != null) {
|
||||
|
||||
try {
|
||||
cluster.close();
|
||||
} catch (Exception ex) {
|
||||
log.warn("Cannot properly close Jedis cluster", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
clusterCommandExecutor.destroy();
|
||||
} catch (Exception ex) {
|
||||
log.warn("Cannot properly close cluster command executor", ex);
|
||||
}
|
||||
}
|
||||
|
||||
this.destroyed = true;
|
||||
stop();
|
||||
state.set(State.DESTROYED);
|
||||
}
|
||||
|
||||
public RedisConnection getConnection() {
|
||||
@@ -866,8 +902,19 @@ public class JedisConnectionFactory implements InitializingBean, DisposableBean,
|
||||
}
|
||||
|
||||
private void assertInitialized() {
|
||||
Assert.state(this.initialized, "JedisConnectionFactory was not initialized through afterPropertiesSet()");
|
||||
Assert.state(!this.destroyed, "JedisConnectionFactory was destroyed and cannot be used anymore");
|
||||
|
||||
State current = state.get();
|
||||
|
||||
if (State.STARTED.equals(current)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (current) {
|
||||
case CREATED, STOPPED -> throw new IllegalStateException(String.format("JedisConnectionFactory has been %s. Use start() to initialize it", current));
|
||||
case DESTROYED -> throw new IllegalStateException(
|
||||
"JedisConnectionFactory was destroyed and cannot be used anymore");
|
||||
default -> throw new IllegalStateException(String.format("JedisConnectionFactory is %s", current));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,11 +26,13 @@ import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.redis.ExceptionTranslationStrategy;
|
||||
@@ -116,8 +118,8 @@ import org.apache.commons.logging.LogFactory;
|
||||
* @author Andrea Como
|
||||
* @author Chris Bono
|
||||
*/
|
||||
public class LettuceConnectionFactory
|
||||
implements InitializingBean, DisposableBean, RedisConnectionFactory, ReactiveRedisConnectionFactory {
|
||||
public class LettuceConnectionFactory implements RedisConnectionFactory, ReactiveRedisConnectionFactory,
|
||||
InitializingBean, DisposableBean, SmartLifecycle {
|
||||
|
||||
private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new PassThroughExceptionTranslationStrategy(
|
||||
LettuceExceptionConverter.INSTANCE);
|
||||
@@ -144,8 +146,11 @@ public class LettuceConnectionFactory
|
||||
|
||||
private @Nullable ClusterCommandExecutor clusterCommandExecutor;
|
||||
|
||||
private boolean initialized;
|
||||
private boolean destroyed;
|
||||
enum State {
|
||||
CREATED, STARTING, STARTED, STOPPING, STOPPED, DESTROYED;
|
||||
}
|
||||
|
||||
private AtomicReference<State> state = new AtomicReference<>(State.CREATED);
|
||||
|
||||
/**
|
||||
* Constructs a new {@link LettuceConnectionFactory} instance with default settings.
|
||||
@@ -333,33 +338,78 @@ public class LettuceConnectionFactory
|
||||
return LettuceConverters.createRedisStandaloneConfiguration(redisUri);
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() {
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
this.client = createClient();
|
||||
State current = state.getAndUpdate(state -> {
|
||||
if (State.CREATED.equals(state) || State.STOPPED.equals(state)) {
|
||||
return State.STARTING;
|
||||
}
|
||||
return state;
|
||||
});
|
||||
|
||||
this.connectionProvider = new ExceptionTranslatingConnectionProvider(createConnectionProvider(client, CODEC));
|
||||
this.reactiveConnectionProvider = new ExceptionTranslatingConnectionProvider(
|
||||
createConnectionProvider(client, LettuceReactiveRedisConnection.CODEC));
|
||||
if (State.CREATED.equals(current) || State.STOPPED.equals(current)) {
|
||||
|
||||
if (isClusterAware()) {
|
||||
this.client = createClient();
|
||||
|
||||
this.clusterCommandExecutor = new ClusterCommandExecutor(
|
||||
new LettuceClusterTopologyProvider((RedisClusterClient) client),
|
||||
new LettuceClusterConnection.LettuceClusterNodeResourceProvider(this.connectionProvider),
|
||||
EXCEPTION_TRANSLATION);
|
||||
}
|
||||
this.connectionProvider = new ExceptionTranslatingConnectionProvider(createConnectionProvider(client, CODEC));
|
||||
this.reactiveConnectionProvider = new ExceptionTranslatingConnectionProvider(
|
||||
createConnectionProvider(client, LettuceReactiveRedisConnection.CODEC));
|
||||
|
||||
this.initialized = true;
|
||||
if (isClusterAware()) {
|
||||
|
||||
if (getEagerInitialization() && getShareNativeConnection()) {
|
||||
initConnection();
|
||||
this.clusterCommandExecutor = new ClusterCommandExecutor(
|
||||
new LettuceClusterTopologyProvider((RedisClusterClient) client),
|
||||
new LettuceClusterConnection.LettuceClusterNodeResourceProvider(this.connectionProvider),
|
||||
EXCEPTION_TRANSLATION);
|
||||
}
|
||||
|
||||
state.set(State.STARTED);
|
||||
|
||||
if (getEagerInitialization() && getShareNativeConnection()) {
|
||||
initConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
if (state.compareAndSet(State.STARTED, State.STOPPING)) {
|
||||
resetConnection();
|
||||
dispose(connectionProvider);
|
||||
dispose(reactiveConnectionProvider);
|
||||
try {
|
||||
Duration quietPeriod = clientConfiguration.getShutdownQuietPeriod();
|
||||
Duration timeout = clientConfiguration.getShutdownTimeout();
|
||||
client.shutdown(quietPeriod.toMillis(), timeout.toMillis(), TimeUnit.MILLISECONDS);
|
||||
state.set(State.STOPPED);
|
||||
} catch (Exception e) {
|
||||
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn((client != null ? ClassUtils.getShortName(client.getClass()) : "LettuceClient")
|
||||
+ " did not shut down gracefully.", e);
|
||||
}
|
||||
}
|
||||
state.set(State.STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return State.STARTED.equals(state.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
// customization hook. initialization happens in start
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
|
||||
resetConnection();
|
||||
|
||||
stop();
|
||||
client = null;
|
||||
if (clusterCommandExecutor != null) {
|
||||
|
||||
try {
|
||||
@@ -368,23 +418,7 @@ public class LettuceConnectionFactory
|
||||
log.warn("Cannot properly close cluster command executor", ex);
|
||||
}
|
||||
}
|
||||
|
||||
dispose(connectionProvider);
|
||||
dispose(reactiveConnectionProvider);
|
||||
|
||||
try {
|
||||
Duration quietPeriod = clientConfiguration.getShutdownQuietPeriod();
|
||||
Duration timeout = clientConfiguration.getShutdownTimeout();
|
||||
client.shutdown(quietPeriod.toMillis(), timeout.toMillis(), TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn((client != null ? ClassUtils.getShortName(client.getClass()) : "LettuceClient")
|
||||
+ " did not shut down gracefully.", e);
|
||||
}
|
||||
}
|
||||
|
||||
this.destroyed = true;
|
||||
state.set(State.DESTROYED);
|
||||
}
|
||||
|
||||
private void dispose(LettuceConnectionProvider connectionProvider) {
|
||||
@@ -532,8 +566,6 @@ public class LettuceConnectionFactory
|
||||
*/
|
||||
public void resetConnection() {
|
||||
|
||||
assertInitialized();
|
||||
|
||||
Optionals.toStream(Optional.ofNullable(connection), Optional.ofNullable(reactiveConnection))
|
||||
.forEach(SharedConnection::resetConnection);
|
||||
|
||||
@@ -1267,8 +1299,19 @@ public class LettuceConnectionFactory
|
||||
}
|
||||
|
||||
private void assertInitialized() {
|
||||
Assert.state(this.initialized, "LettuceConnectionFactory was not initialized through afterPropertiesSet()");
|
||||
Assert.state(!this.destroyed, "LettuceConnectionFactory was destroyed and cannot be used anymore");
|
||||
|
||||
State current = state.get();
|
||||
|
||||
if (State.STARTED.equals(current)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (current) {
|
||||
case CREATED, STOPPED -> throw new IllegalStateException(String.format("LettuceConnectionFactory has been %s. Use start() to initialize it", current));
|
||||
case DESTROYED -> throw new IllegalStateException(
|
||||
"LettuceConnectionFactory was destroyed and cannot be used anymore");
|
||||
default -> throw new IllegalStateException(String.format("LettuceConnectionFactory is %s", current));
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyToAll(RedisURI source, Consumer<RedisURI> action) {
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
package org.springframework.data.redis.support.collections;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.SmartFactoryBean;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.util.Lazy;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -30,8 +31,9 @@ import org.springframework.util.StringUtils;
|
||||
* Otherwise uses the provided type (default is list).
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class RedisCollectionFactoryBean implements InitializingBean, BeanNameAware, FactoryBean<RedisStore> {
|
||||
public class RedisCollectionFactoryBean implements SmartFactoryBean<RedisStore>, BeanNameAware, InitializingBean {
|
||||
|
||||
/**
|
||||
* Collection types supported by this factory.
|
||||
@@ -73,13 +75,15 @@ public class RedisCollectionFactoryBean implements InitializingBean, BeanNameAwa
|
||||
abstract DataType dataType();
|
||||
}
|
||||
|
||||
private @Nullable RedisStore store;
|
||||
private @Nullable Lazy<RedisStore> store;
|
||||
private @Nullable CollectionType type = null;
|
||||
private @Nullable RedisTemplate<String, ?> template;
|
||||
private @Nullable String key;
|
||||
private @Nullable String beanName;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
if (!StringUtils.hasText(key)) {
|
||||
key = beanName;
|
||||
}
|
||||
@@ -87,19 +91,23 @@ public class RedisCollectionFactoryBean implements InitializingBean, BeanNameAwa
|
||||
Assert.hasText(key, "Collection key is required - no key or bean name specified");
|
||||
Assert.notNull(template, "Redis template is required");
|
||||
|
||||
DataType dt = template.type(key);
|
||||
store = Lazy.of(() -> {
|
||||
|
||||
// can't create store
|
||||
Assert.isTrue(!DataType.STRING.equals(dt), "Cannot create store on keys of type 'string'");
|
||||
DataType dt = template.type(key);
|
||||
|
||||
store = createStore(dt);
|
||||
// can't create store
|
||||
Assert.isTrue(!DataType.STRING.equals(dt), "Cannot create store on keys of type 'string'");
|
||||
|
||||
if (store == null) {
|
||||
if (type == null) {
|
||||
type = CollectionType.LIST;
|
||||
RedisStore tmp = createStore(dt);
|
||||
|
||||
if (tmp == null) {
|
||||
if (type == null) {
|
||||
type = CollectionType.LIST;
|
||||
}
|
||||
tmp = createStore(type.dataType());
|
||||
}
|
||||
store = createStore(type.dataType());
|
||||
}
|
||||
return tmp;
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -123,18 +131,17 @@ public class RedisCollectionFactoryBean implements InitializingBean, BeanNameAwa
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RedisStore getObject() {
|
||||
return store;
|
||||
return store.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return (store != null ? store.getClass() : RedisStore.class);
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
return (store != null ? store.get().getClass() : RedisStore.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
/**
|
||||
@@ -40,6 +41,12 @@ public abstract class ConnectionFactoryTracker {
|
||||
throw new UnsupportedOperationException("Cannot track managed resource");
|
||||
}
|
||||
|
||||
if(factory instanceof SmartLifecycle smartLifecycle) {
|
||||
if(!smartLifecycle.isRunning() && smartLifecycle.isAutoStartup()) {
|
||||
smartLifecycle.start();
|
||||
}
|
||||
}
|
||||
|
||||
connFactories.add(factory);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,19 +21,20 @@ import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.ConnectionFactoryTracker;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConnection;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnRedisAvailable;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnRedisSentinelAvailable;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnRedisVersion;
|
||||
import org.springframework.data.redis.util.ConnectionVerifier;
|
||||
|
||||
/**
|
||||
* Integration tests for Redis 6 ACL.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@EnabledOnRedisVersion("6.0")
|
||||
@EnabledOnRedisAvailable(6382)
|
||||
@@ -45,15 +46,11 @@ class JedisAclIntegrationTests {
|
||||
RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6382);
|
||||
standaloneConfiguration.setPassword("foobared");
|
||||
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(standaloneConfiguration);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
connection.close();
|
||||
|
||||
connectionFactory.destroy();
|
||||
ConnectionVerifier.create(new JedisConnectionFactory(standaloneConfiguration)) //
|
||||
.execute(connection -> {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}) //
|
||||
.verifyAndClose();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1046
|
||||
@@ -63,15 +60,11 @@ class JedisAclIntegrationTests {
|
||||
standaloneConfiguration.setUsername("spring");
|
||||
standaloneConfiguration.setPassword("data");
|
||||
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(standaloneConfiguration);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
connection.close();
|
||||
|
||||
connectionFactory.destroy();
|
||||
ConnectionVerifier.create(new JedisConnectionFactory(standaloneConfiguration)) //
|
||||
.execute(connection -> {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}) //
|
||||
.verifyAndClose();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1145
|
||||
@@ -86,11 +79,11 @@ class JedisAclIntegrationTests {
|
||||
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(sentinelConfiguration);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
ConnectionFactoryTracker.add(connectionFactory);
|
||||
|
||||
RedisSentinelConnection connection = connectionFactory.getSentinelConnection();
|
||||
|
||||
assertThat(connection.masters()).isNotEmpty();
|
||||
connection.close();
|
||||
try (RedisSentinelConnection connection = connectionFactory.getSentinelConnection()) {
|
||||
assertThat(connection.masters()).isNotEmpty();
|
||||
}
|
||||
|
||||
connectionFactory.destroy();
|
||||
}
|
||||
@@ -102,15 +95,13 @@ class JedisAclIntegrationTests {
|
||||
standaloneConfiguration.setUsername("spring");
|
||||
standaloneConfiguration.setPassword("data");
|
||||
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(standaloneConfiguration);
|
||||
connectionFactory.setUsePool(true);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(standaloneConfiguration,
|
||||
JedisClientConfiguration.builder().usePooling().build());
|
||||
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
connection.close();
|
||||
|
||||
connectionFactory.destroy();
|
||||
ConnectionVerifier.create(connectionFactory) //
|
||||
.execute(connection -> {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}) //
|
||||
.verifyAndClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.lang.Nullable;
|
||||
* Integration tests for {@link JedisConnectionFactory}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
class JedisConnectionFactoryIntegrationTests {
|
||||
|
||||
@@ -49,8 +50,11 @@ class JedisConnectionFactoryIntegrationTests {
|
||||
new RedisStandaloneConfiguration(SettingsUtils.getHost(), SettingsUtils.getPort()),
|
||||
JedisClientConfiguration.defaultConfiguration());
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
assertThat(factory.getConnection().ping()).isEqualTo("PONG");
|
||||
try (RedisConnection connection = factory.getConnection()) {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-575
|
||||
@@ -60,9 +64,32 @@ class JedisConnectionFactoryIntegrationTests {
|
||||
new RedisStandaloneConfiguration(SettingsUtils.getHost(), SettingsUtils.getPort()),
|
||||
JedisClientConfiguration.builder().clientName("clientName").build());
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
assertThat(connection.getClientName()).isEqualTo("clientName");
|
||||
}
|
||||
|
||||
@Test // GH-2503
|
||||
void startStopStartConnectionFactory() {
|
||||
|
||||
factory = new JedisConnectionFactory(
|
||||
new RedisStandaloneConfiguration(SettingsUtils.getHost(), SettingsUtils.getPort()),
|
||||
JedisClientConfiguration.defaultConfiguration());
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
factory.start();
|
||||
assertThat(factory.isRunning()).isTrue();
|
||||
|
||||
factory.stop();
|
||||
assertThat(factory.isRunning()).isFalse();
|
||||
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> factory.getConnection());
|
||||
|
||||
factory.start();
|
||||
assertThat(factory.isRunning()).isTrue();
|
||||
try (RedisConnection connection = factory.getConnection()) {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConnection;
|
||||
@@ -60,14 +59,16 @@ class JedisConnectionFactorySentinelIntegrationTests {
|
||||
|
||||
factory = new JedisConnectionFactory(configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
connection.flushAll();
|
||||
connection.set("key5".getBytes(), "value5".getBytes());
|
||||
try (RedisConnection connection = factory.getConnection()) {
|
||||
|
||||
connection.select(0);
|
||||
assertThat(connection.exists("key5".getBytes())).isFalse();
|
||||
connection.close();
|
||||
connection.serverCommands().flushAll();
|
||||
connection.stringCommands().set("key5".getBytes(), "value5".getBytes());
|
||||
|
||||
connection.select(0);
|
||||
assertThat(connection.keyCommands().exists("key5".getBytes())).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // GH-2103
|
||||
@@ -79,10 +80,11 @@ class JedisConnectionFactorySentinelIntegrationTests {
|
||||
|
||||
factory = new JedisConnectionFactory(configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisSentinelConnection sentinelConnection = factory.getSentinelConnection();
|
||||
assertThat(sentinelConnection.masters()).isNotNull();
|
||||
sentinelConnection.close();
|
||||
try (RedisSentinelConnection sentinelConnection = factory.getSentinelConnection()) {
|
||||
assertThat(sentinelConnection.masters()).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-574, DATAREDIS-765
|
||||
@@ -94,11 +96,13 @@ class JedisConnectionFactorySentinelIntegrationTests {
|
||||
|
||||
factory = new JedisConnectionFactory(SENTINEL_CONFIG, clientConfiguration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
try (RedisConnection connection = factory.getConnection()) {
|
||||
|
||||
assertThat(factory.getUsePool()).isTrue();
|
||||
assertThat(connection.getClientName()).isEqualTo("clientName");
|
||||
assertThat(factory.getUsePool()).isTrue();
|
||||
assertThat(connection.getClientName()).isEqualTo("clientName");
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-324
|
||||
@@ -106,8 +110,11 @@ class JedisConnectionFactorySentinelIntegrationTests {
|
||||
|
||||
factory = new JedisConnectionFactory(SENTINEL_CONFIG);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
assertThat(factory.getConnection().ping()).isEqualTo("PONG");
|
||||
try (RedisConnection connection = factory.getConnection()) {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-552
|
||||
@@ -116,18 +123,25 @@ class JedisConnectionFactorySentinelIntegrationTests {
|
||||
factory = new JedisConnectionFactory(SENTINEL_CONFIG);
|
||||
factory.setClientName("clientName");
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
assertThat(factory.getConnection().getClientName()).isEqualTo("clientName");
|
||||
try (RedisConnection connection = factory.getConnection()) {
|
||||
assertThat(connection.serverCommands().getClientName()).isEqualTo("clientName");
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1127
|
||||
void shouldNotFailOnFirstSentinelDown() {
|
||||
void shouldNotFailOnFirstSentinelDown() throws IOException {
|
||||
|
||||
RedisSentinelConfiguration oneDownSentinelConfig = new RedisSentinelConfiguration().master("mymaster")
|
||||
.sentinel("127.0.0.1", 1).sentinel("127.0.0.1", 26379);
|
||||
|
||||
factory = new JedisConnectionFactory(oneDownSentinelConfig);
|
||||
factory.afterPropertiesSet();
|
||||
assertThat(factory.getSentinelConnection().isOpen()).isTrue();
|
||||
factory.start();
|
||||
|
||||
try (RedisSentinelConnection sentinelConnection = factory.getSentinelConnection()) {
|
||||
assertThat(sentinelConnection.isOpen()).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
@@ -39,6 +40,7 @@ import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisPassword;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory.State;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
@@ -62,6 +64,7 @@ class JedisConnectionFactoryUnitTests {
|
||||
|
||||
connectionFactory = initSpyedConnectionFactory(SINGLE_SENTINEL_CONFIG, new JedisPoolConfig());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
verify(connectionFactory, times(1)).createRedisSentinelPool(eq(SINGLE_SENTINEL_CONFIG));
|
||||
verify(connectionFactory, never()).createRedisPool();
|
||||
@@ -72,6 +75,7 @@ class JedisConnectionFactoryUnitTests {
|
||||
|
||||
connectionFactory = initSpyedConnectionFactory((RedisSentinelConfiguration) null, new JedisPoolConfig());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
verify(connectionFactory, times(1)).createRedisPool();
|
||||
verify(connectionFactory, never()).createRedisSentinelPool(any(RedisSentinelConfiguration.class));
|
||||
@@ -90,6 +94,7 @@ class JedisConnectionFactoryUnitTests {
|
||||
|
||||
connectionFactory = initSpyedConnectionFactory(CLUSTER_CONFIG, new JedisPoolConfig());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
verify(connectionFactory, times(1)).createCluster(eq(CLUSTER_CONFIG), any(GenericObjectPoolConfig.class));
|
||||
verify(connectionFactory, never()).createRedisPool();
|
||||
@@ -101,6 +106,7 @@ class JedisConnectionFactoryUnitTests {
|
||||
JedisCluster clusterMock = mock(JedisCluster.class);
|
||||
JedisConnectionFactory factory = new JedisConnectionFactory();
|
||||
ReflectionTestUtils.setField(factory, "cluster", clusterMock);
|
||||
ReflectionTestUtils.setField(factory, "state", new AtomicReference(State.STARTED));
|
||||
|
||||
factory.destroy();
|
||||
|
||||
@@ -321,6 +327,16 @@ class JedisConnectionFactoryUnitTests {
|
||||
assertThatIllegalStateException().isThrownBy(connectionFactory::getSentinelConnection);
|
||||
}
|
||||
|
||||
@Test // GH-2503
|
||||
void afterPropertiesSetDoesNotTriggerConnectionInitialization() {
|
||||
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
|
||||
connectionFactory.afterPropertiesSet();
|
||||
|
||||
assertThat(connectionFactory.isRunning()).isFalse();
|
||||
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> connectionFactory.getConnection());
|
||||
}
|
||||
|
||||
private JedisConnectionFactory initSpyedConnectionFactory(RedisSentinelConfiguration sentinelConfig,
|
||||
JedisPoolConfig poolConfig) {
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.junit.jupiter.api.AfterEach;
|
||||
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.RedisConnectionFailureException;
|
||||
import org.springframework.data.redis.SettingsUtils;
|
||||
@@ -46,6 +45,7 @@ import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.data.redis.connection.StringRedisConnection.StringTuple;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnRedisSentinelAvailable;
|
||||
import org.springframework.data.redis.util.ConnectionVerifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
@@ -99,12 +99,13 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
|
||||
|
||||
@Test
|
||||
void testCreateConnectionWithDb() {
|
||||
|
||||
JedisConnectionFactory factory2 = new JedisConnectionFactory();
|
||||
factory2.setDatabase(1);
|
||||
factory2.afterPropertiesSet();
|
||||
// No way to really verify we are in the selected DB
|
||||
factory2.getConnection().ping();
|
||||
factory2.destroy();
|
||||
|
||||
ConnectionVerifier.create(factory2) //
|
||||
.execute(RedisConnection::ping) //
|
||||
.verifyAndClose();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-714
|
||||
@@ -113,6 +114,7 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
|
||||
JedisConnectionFactory factory2 = new JedisConnectionFactory();
|
||||
factory2.setDatabase(77);
|
||||
factory2.afterPropertiesSet();
|
||||
factory2.start();
|
||||
|
||||
try {
|
||||
assertThatExceptionOfType(RedisConnectionFailureException.class).isThrownBy(factory2::getConnection);
|
||||
@@ -132,11 +134,16 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
|
||||
factory2.setHostName(SettingsUtils.getHost());
|
||||
factory2.setPort(SettingsUtils.getPort());
|
||||
factory2.afterPropertiesSet();
|
||||
factory2.start();
|
||||
|
||||
RedisConnection conn2 = factory2.getConnection();
|
||||
conn2.close();
|
||||
factory2.getConnection();
|
||||
factory2.destroy();
|
||||
try {
|
||||
|
||||
RedisConnection conn2 = factory2.getConnection();
|
||||
conn2.close();
|
||||
factory2.getConnection();
|
||||
} finally {
|
||||
factory2.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -330,15 +337,17 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
|
||||
factory2.setHostName(SettingsUtils.getHost());
|
||||
factory2.setPort(SettingsUtils.getPort());
|
||||
factory2.afterPropertiesSet();
|
||||
factory2.start();
|
||||
|
||||
RedisConnection conn = factory2.getConnection();
|
||||
try {
|
||||
try (RedisConnection conn = factory2.getConnection()) {
|
||||
conn.get(null);
|
||||
} catch (Exception e) {}
|
||||
conn.close();
|
||||
// Make sure we don't end up with broken connection
|
||||
factory2.getConnection().dbSize();
|
||||
factory2.destroy();
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
// Make sure we don't end up with broken connection
|
||||
factory2.getConnection().dbSize();
|
||||
factory2.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // GH-2356
|
||||
@@ -351,19 +360,17 @@ public class JedisConnectionIntegrationTests extends AbstractConnectionIntegrati
|
||||
factory.setUsePool(true);
|
||||
factory.setHostName(SettingsUtils.getHost());
|
||||
factory.setPort(SettingsUtils.getPort());
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
RedisConnection conn = factory.getConnection();
|
||||
|
||||
JedisSubscription subscriptionMock = mock(JedisSubscription.class);
|
||||
doThrow(new IllegalStateException()).when(subscriptionMock).close();
|
||||
ReflectionTestUtils.setField(conn, "subscription", subscriptionMock);
|
||||
|
||||
conn.close();
|
||||
|
||||
// Make sure we don't end up with broken connection
|
||||
factory.getConnection().dbSize();
|
||||
factory.destroy();
|
||||
ConnectionVerifier.create(factory) //
|
||||
.execute(connection -> {
|
||||
JedisSubscription subscriptionMock = mock(JedisSubscription.class);
|
||||
doThrow(new IllegalStateException()).when(subscriptionMock).close();
|
||||
ReflectionTestUtils.setField(connection, "subscription", subscriptionMock);
|
||||
}) //
|
||||
.verifyAndRun(connectionFactory -> {
|
||||
connectionFactory.getConnection().dbSize();
|
||||
connectionFactory.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -23,11 +23,10 @@ import org.junit.jupiter.api.AfterEach;
|
||||
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;
|
||||
import org.springframework.data.redis.util.ConnectionVerifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
@@ -68,12 +67,13 @@ public class JedisConnectionPipelineIntegrationTests extends AbstractConnectionP
|
||||
factory2.setHostName(SettingsUtils.getHost());
|
||||
factory2.setPort(SettingsUtils.getPort());
|
||||
factory2.setDatabase(1);
|
||||
factory2.afterPropertiesSet();
|
||||
RedisConnection conn2 = factory2.getConnection();
|
||||
conn2.openPipeline();
|
||||
conn2.close();
|
||||
factory2.getConnection();
|
||||
factory2.destroy();
|
||||
|
||||
ConnectionVerifier.create(factory2) //
|
||||
.execute(conn2 -> conn2.openPipeline()) //
|
||||
.verifyAndRun(connectionFactory -> {
|
||||
connectionFactory.getConnection();
|
||||
connectionFactory.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
// Unsupported Ops
|
||||
|
||||
@@ -64,6 +64,7 @@ public class JedisConnectionFactoryExtension implements ParameterResolver {
|
||||
CLIENT_CONFIGURATION);
|
||||
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
@@ -75,6 +76,7 @@ public class JedisConnectionFactoryExtension implements ParameterResolver {
|
||||
CLIENT_CONFIGURATION);
|
||||
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
@@ -86,6 +88,7 @@ public class JedisConnectionFactoryExtension implements ParameterResolver {
|
||||
CLIENT_CONFIGURATION);
|
||||
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConnection;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
@@ -33,6 +32,7 @@ import org.springframework.data.redis.test.condition.EnabledOnCommand;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnRedisAvailable;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnRedisSentinelAvailable;
|
||||
import org.springframework.data.redis.test.extension.LettuceTestClientResources;
|
||||
import org.springframework.data.redis.util.ConnectionVerifier;
|
||||
|
||||
/**
|
||||
* Integration tests for Redis 6 ACL.
|
||||
@@ -50,16 +50,17 @@ class LettuceAclIntegrationTests {
|
||||
RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6382);
|
||||
standaloneConfiguration.setPassword("foobared");
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration);
|
||||
connectionFactory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder()
|
||||
.clientResources(LettuceTestClientResources.getSharedClientResources()).build();
|
||||
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration,
|
||||
clientConfiguration);
|
||||
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
connection.close();
|
||||
|
||||
connectionFactory.destroy();
|
||||
ConnectionVerifier.create(connectionFactory) //
|
||||
.execute(connection -> {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}) //
|
||||
.verifyAndClose();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1046
|
||||
@@ -69,16 +70,17 @@ class LettuceAclIntegrationTests {
|
||||
standaloneConfiguration.setUsername("spring");
|
||||
standaloneConfiguration.setPassword("data");
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration);
|
||||
connectionFactory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder()
|
||||
.clientResources(LettuceTestClientResources.getSharedClientResources()).build();
|
||||
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration,
|
||||
clientConfiguration);
|
||||
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
connection.close();
|
||||
|
||||
connectionFactory.destroy();
|
||||
ConnectionVerifier.create(connectionFactory) //
|
||||
.execute(connection -> {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}) //
|
||||
.verifyAndClose();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1145
|
||||
@@ -96,13 +98,13 @@ class LettuceAclIntegrationTests {
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(sentinelConfiguration, configuration);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
RedisSentinelConnection connection = connectionFactory.getSentinelConnection();
|
||||
|
||||
assertThat(connection.masters()).isNotEmpty();
|
||||
connection.close();
|
||||
|
||||
connectionFactory.destroy();
|
||||
try (RedisSentinelConnection connection = connectionFactory.getSentinelConnection()) {
|
||||
assertThat(connection.masters()).isNotEmpty();
|
||||
} finally {
|
||||
connectionFactory.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-1046
|
||||
@@ -113,15 +115,16 @@ class LettuceAclIntegrationTests {
|
||||
masterReplicaConfiguration.setUsername("spring");
|
||||
masterReplicaConfiguration.setPassword("data");
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(masterReplicaConfiguration);
|
||||
connectionFactory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder()
|
||||
.clientResources(LettuceTestClientResources.getSharedClientResources()).build();
|
||||
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(masterReplicaConfiguration,
|
||||
clientConfiguration);
|
||||
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
connection.close();
|
||||
|
||||
connectionFactory.destroy();
|
||||
ConnectionVerifier.create(connectionFactory) //
|
||||
.execute(connection -> {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}) //
|
||||
.verifyAndClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ import org.springframework.data.redis.test.condition.EnabledOnRedisClusterAvaila
|
||||
import org.springframework.data.redis.test.extension.LettuceExtension;
|
||||
import org.springframework.data.redis.test.extension.LettuceTestClientResources;
|
||||
import org.springframework.data.redis.test.util.HexStringUtils;
|
||||
import org.springframework.data.redis.util.ConnectionVerifier;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
@@ -156,14 +157,11 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
void shouldCreateConnectionWithPooling() {
|
||||
|
||||
LettuceConnectionFactory factory = createConnectionFactory();
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
connection.close();
|
||||
|
||||
factory.destroy();
|
||||
ConnectionVerifier.create(factory) //
|
||||
.execute(connection -> {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}).verifyAndClose();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-775
|
||||
@@ -171,13 +169,17 @@ public class LettuceClusterConnectionTests implements ClusterConnectionTests {
|
||||
|
||||
LettuceConnectionFactory factory = createConnectionFactory();
|
||||
factory.afterPropertiesSet();
|
||||
try {
|
||||
|
||||
RedisClusterConnection clusterConnection = factory.getClusterConnection();
|
||||
factory.start();
|
||||
RedisClusterConnection clusterConnection = factory.getClusterConnection();
|
||||
|
||||
assertThat(clusterConnection.ping(ClusterTestVariables.CLUSTER_NODE_1)).isEqualTo("PONG");
|
||||
clusterConnection.close();
|
||||
assertThat(clusterConnection.ping(ClusterTestVariables.CLUSTER_NODE_1)).isEqualTo("PONG");
|
||||
clusterConnection.close();
|
||||
} finally {
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-315
|
||||
|
||||
@@ -68,6 +68,7 @@ class LettuceClusterKeyspaceNotificationsTests {
|
||||
factory = new CustomLettuceConnectionFactory(SettingsUtils.clusterConfiguration());
|
||||
factory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
|
||||
@@ -71,6 +71,7 @@ class LettuceConnectionFactoryTests {
|
||||
factory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
factory.afterPropertiesSet();
|
||||
factory.setShutdownTimeout(0);
|
||||
factory.start();
|
||||
connection = new DefaultStringRedisConnection(factory.getConnection());
|
||||
}
|
||||
|
||||
@@ -212,7 +213,7 @@ class LettuceConnectionFactoryTests {
|
||||
connectionFactory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
connectionFactory.setShutdownTimeout(0);
|
||||
customizer.accept(connectionFactory);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
return connectionFactory;
|
||||
}
|
||||
@@ -264,9 +265,9 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
@Test
|
||||
void testGetConnectionException() {
|
||||
factory.resetConnection();
|
||||
factory.stop();
|
||||
factory.setHostName("fakeHost");
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
try {
|
||||
factory.getConnection();
|
||||
fail("Expected connection failure exception");
|
||||
@@ -277,7 +278,7 @@ class LettuceConnectionFactoryTests {
|
||||
void testGetConnectionNotSharedBadHostname() {
|
||||
factory.setShareNativeConnection(false);
|
||||
factory.setHostName("fakeHost");
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
factory.getConnection();
|
||||
}
|
||||
|
||||
@@ -285,7 +286,7 @@ class LettuceConnectionFactoryTests {
|
||||
void testGetSharedConnectionNotShared() {
|
||||
factory.setShareNativeConnection(false);
|
||||
factory.setHostName("fakeHost");
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
assertThat(factory.getSharedConnection()).isNull();
|
||||
}
|
||||
|
||||
@@ -295,7 +296,7 @@ class LettuceConnectionFactoryTests {
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory();
|
||||
factory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
factory.setDatabase(2);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
@@ -319,7 +320,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory();
|
||||
factory.setShutdownTimeout(0);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
@@ -337,7 +338,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory();
|
||||
factory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
@@ -355,7 +356,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), configuration);
|
||||
factory.setShareNativeConnection(false);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
@@ -385,7 +386,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.socketConfiguration(), configuration);
|
||||
factory.setShareNativeConnection(false);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
@@ -407,7 +408,7 @@ class LettuceConnectionFactoryTests {
|
||||
SettingsUtils.getHost()).node(SettingsUtils.getHost(), SettingsUtils.getPort() + 1);
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache, configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
@@ -432,7 +433,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache,
|
||||
LettuceTestClientConfiguration.defaultConfiguration());
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
@@ -456,7 +457,7 @@ class LettuceConnectionFactoryTests {
|
||||
SettingsUtils.getHost(), SettingsUtils.getPort() + 1);
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache, configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
@@ -484,7 +485,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.standaloneConfiguration(),
|
||||
configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
|
||||
@@ -506,7 +507,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisStandaloneConfiguration(), configuration);
|
||||
factory.setShareNativeConnection(false);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
@@ -522,7 +523,7 @@ class LettuceConnectionFactoryTests {
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisStandaloneConfiguration());
|
||||
factory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
factory.setClientName("clientName");
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
ConnectionFactoryTracker.add(factory);
|
||||
|
||||
@@ -542,7 +543,7 @@ class LettuceConnectionFactoryTests {
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache, configuration);
|
||||
factory.setEagerInitialization(true);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
assertThat(factory.getSharedConnection()).isNotNull();
|
||||
assertThat(factory.getSharedClusterConnection()).isNull();
|
||||
@@ -560,7 +561,7 @@ class LettuceConnectionFactoryTests {
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.clusterConfiguration(),
|
||||
configuration);
|
||||
factory.setEagerInitialization(true);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
assertThat(factory.getSharedConnection()).isNull();
|
||||
assertThat(factory.getSharedClusterConnection()).isNotNull();
|
||||
@@ -569,4 +570,17 @@ class LettuceConnectionFactoryTests {
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
@Test // GH-2503
|
||||
void startStopStartConnectionFactory() {
|
||||
|
||||
assertThat(factory.isRunning()).isTrue();
|
||||
factory.stop();
|
||||
assertThat(factory.isRunning()).isFalse();
|
||||
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> factory.getConnection());
|
||||
factory.start();
|
||||
assertThat(factory.isRunning()).isTrue();
|
||||
try (RedisConnection connection = factory.getConnection()) {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,6 +412,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
LettuceTestClientConfiguration.builder().useSsl().disablePeerVerification().build());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
ConnectionFactoryTracker.add(connectionFactory);
|
||||
connectionFactory.start();
|
||||
|
||||
AbstractRedisClient client = (AbstractRedisClient) getField(connectionFactory, "client");
|
||||
assertThat(client).isInstanceOf(RedisClient.class);
|
||||
@@ -429,6 +430,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
LettuceTestClientConfiguration.builder().useSsl().startTls().build());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
ConnectionFactoryTracker.add(connectionFactory);
|
||||
connectionFactory.start();
|
||||
|
||||
AbstractRedisClient client = (AbstractRedisClient) getField(connectionFactory, "client");
|
||||
assertThat(client).isInstanceOf(RedisClient.class);
|
||||
@@ -867,6 +869,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
};
|
||||
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
new DirectFieldAccessor(connectionFactory).setPropertyValue("client", clientMock);
|
||||
|
||||
@@ -898,6 +901,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
|
||||
connectionFactory.setValidateConnection(true);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
try (RedisConnection connection = connectionFactory.getConnection()) {
|
||||
connection.ping();
|
||||
@@ -927,6 +931,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
|
||||
connectionFactory.setValidateConnection(true);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
connectionFactory.getConnection().close();
|
||||
|
||||
@@ -954,6 +959,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
connectionFactory.setEagerInitialization(true);
|
||||
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
verify(connectionProviderMock, times(2)).getConnection(StatefulConnection.class);
|
||||
}
|
||||
@@ -974,6 +980,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
};
|
||||
connectionFactory.setClientResources(LettuceTestClientResources.getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
assertThatExceptionOfType(RedisConnectionFailureException.class)
|
||||
.isThrownBy(() -> connectionFactory.getConnection().ping()).withCauseInstanceOf(PoolException.class);
|
||||
@@ -994,6 +1001,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
|
||||
connectionFactory.setClientResources(getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
connectionFactory.destroy();
|
||||
|
||||
verify((DisposableBean) connectionProviderMock, times(2)).destroy();
|
||||
@@ -1079,6 +1087,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
};
|
||||
connectionFactory.setClientResources(getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
LettuceReactiveRedisConnection reactiveConnection = connectionFactory.getReactiveConnection();
|
||||
|
||||
@@ -1091,12 +1100,14 @@ class LettuceConnectionFactoryUnitTests {
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
|
||||
connectionFactory.setClientResources(getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
assertThat(connectionFactory.getNativeClient()).isInstanceOf(RedisClient.class);
|
||||
|
||||
connectionFactory = new LettuceConnectionFactory(clusterConfig);
|
||||
connectionFactory.setClientResources(getSharedClientResources());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
assertThat(connectionFactory.getRequiredNativeClient()).isInstanceOf(RedisClusterClient.class);
|
||||
}
|
||||
@@ -1107,7 +1118,7 @@ class LettuceConnectionFactoryUnitTests {
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(connectionFactory::getRequiredNativeClient)
|
||||
.withMessageContaining("was not initialized through");
|
||||
.withMessageContaining("Use start() to initialize");
|
||||
}
|
||||
|
||||
@Test // GH-2057
|
||||
@@ -1226,6 +1237,16 @@ class LettuceConnectionFactoryUnitTests {
|
||||
assertThat(configuration).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test // GH-2503
|
||||
void afterPropertiesSetDoesNotTriggerConnectionInitialization() {
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory();
|
||||
connectionFactory.afterPropertiesSet();
|
||||
|
||||
assertThat(connectionFactory.isRunning()).isFalse();
|
||||
assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> connectionFactory.getConnection());
|
||||
}
|
||||
|
||||
static class CustomRedisConfiguration implements RedisConfiguration, WithHostAndPort {
|
||||
|
||||
private String hostName;
|
||||
|
||||
@@ -125,6 +125,7 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra
|
||||
factory2.setShutdownTimeout(0);
|
||||
factory2.setShareNativeConnection(false);
|
||||
factory2.afterPropertiesSet();
|
||||
factory2.start();
|
||||
RedisConnection connection = factory2.getConnection();
|
||||
// Use the connection to make sure the channel is initialized, else nothing happens on close
|
||||
connection.ping();
|
||||
@@ -134,7 +135,10 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra
|
||||
connection.set("foo".getBytes(), "bar".getBytes());
|
||||
fail("Exception should be thrown trying to use a closed connection");
|
||||
} catch (RedisSystemException e) {}
|
||||
finally {
|
||||
|
||||
factory2.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,6 +157,7 @@ public class LettuceConnectionIntegrationTests extends AbstractConnectionIntegra
|
||||
factory2.setShutdownTimeout(0);
|
||||
factory2.setDatabase(1);
|
||||
factory2.afterPropertiesSet();
|
||||
factory2.start();
|
||||
StringRedisConnection conn2 = new DefaultStringRedisConnection(factory2.getConnection());
|
||||
try {
|
||||
assertThat(conn2.get("foo")).isEqualTo("bar");
|
||||
|
||||
@@ -57,6 +57,7 @@ public class LettuceConnectionPipelineIntegrationTests extends AbstractConnectio
|
||||
LettuceTestClientConfiguration.builder().build());
|
||||
factory2.setDatabase(1);
|
||||
factory2.afterPropertiesSet();
|
||||
factory2.start();
|
||||
StringRedisConnection conn2 = new DefaultStringRedisConnection(factory2.getConnection());
|
||||
try {
|
||||
assertThat(conn2.get("foo")).isEqualTo("bar");
|
||||
|
||||
@@ -55,6 +55,8 @@ public class LettuceConnectionTransactionIntegrationTests extends AbstractConnec
|
||||
factory2.setShutdownTimeout(0);
|
||||
factory2.setDatabase(1);
|
||||
factory2.afterPropertiesSet();
|
||||
factory2.start();
|
||||
|
||||
StringRedisConnection conn2 = new DefaultStringRedisConnection(factory2.getConnection());
|
||||
try {
|
||||
assertThat(conn2.get("foo")).isEqualTo("bar");
|
||||
|
||||
@@ -120,14 +120,19 @@ public class LettuceSentinelIntegrationTests extends AbstractConnectionIntegrati
|
||||
connectionFactory.setShareNativeConnection(false);
|
||||
connectionFactory.setDatabase(5);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
try(RedisConnection directConnection = connectionFactory.getConnection()) {
|
||||
|
||||
assertThat(directConnection.exists("foo".getBytes())).isFalse();
|
||||
directConnection.select(0);
|
||||
|
||||
assertThat(directConnection.exists("foo".getBytes())).isTrue();
|
||||
} finally {
|
||||
connectionFactory.destroy();
|
||||
}
|
||||
|
||||
RedisConnection directConnection = connectionFactory.getConnection();
|
||||
assertThat(directConnection.exists("foo".getBytes())).isFalse();
|
||||
directConnection.select(0);
|
||||
|
||||
assertThat(directConnection.exists("foo".getBytes())).isTrue();
|
||||
directConnection.close();
|
||||
connectionFactory.destroy();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-973
|
||||
@@ -144,16 +149,19 @@ public class LettuceSentinelIntegrationTests extends AbstractConnectionIntegrati
|
||||
connectionFactory.setShareNativeConnection(false);
|
||||
connectionFactory.setDatabase(5);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
LettuceReactiveRedisConnection reactiveConnection = connectionFactory.getReactiveConnection();
|
||||
try(LettuceReactiveRedisConnection reactiveConnection = connectionFactory.getReactiveConnection()) {
|
||||
|
||||
reactiveConnection.keyCommands().exists(ByteBuffer.wrap("foo".getBytes())) //
|
||||
.as(StepVerifier::create) //
|
||||
.expectNext(false) //
|
||||
.verifyComplete();
|
||||
reactiveConnection.keyCommands().exists(ByteBuffer.wrap("foo".getBytes())) //
|
||||
.as(StepVerifier::create) //
|
||||
.expectNext(false) //
|
||||
.verifyComplete();
|
||||
|
||||
} finally {
|
||||
connectionFactory.destroy();
|
||||
}
|
||||
|
||||
reactiveConnection.close();
|
||||
connectionFactory.destroy();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -253,16 +261,14 @@ public class LettuceSentinelIntegrationTests extends AbstractConnectionIntegrati
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SENTINEL_CONFIG, configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
try(RedisConnection connection = factory.getConnection()) {
|
||||
|
||||
try {
|
||||
assertThat(connection.ping()).isEqualTo("PONG");
|
||||
assertThat(connection.info().getProperty("role")).isEqualTo("slave");
|
||||
} finally {
|
||||
connection.close();
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
factory.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver {
|
||||
ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(
|
||||
SettingsUtils.standaloneConfiguration(), configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
@@ -78,6 +80,7 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver {
|
||||
ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.sentinelConfiguration(),
|
||||
configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
@@ -90,6 +93,7 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver {
|
||||
ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.clusterConfiguration(),
|
||||
configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
@@ -102,6 +106,7 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver {
|
||||
ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(
|
||||
SettingsUtils.standaloneConfiguration(), configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
@@ -114,6 +119,7 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver {
|
||||
ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.sentinelConfiguration(),
|
||||
configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
@@ -126,6 +132,7 @@ public class LettuceConnectionFactoryExtension implements ParameterResolver {
|
||||
ManagedLettuceConnectionFactory factory = new ManagedLettuceConnectionFactory(SettingsUtils.clusterConfiguration(),
|
||||
configuration);
|
||||
factory.afterPropertiesSet();
|
||||
factory.start();
|
||||
ShutdownQueue.register(factory);
|
||||
|
||||
return factory;
|
||||
|
||||
@@ -67,7 +67,6 @@ abstract public class AbstractOperationsTestParams {
|
||||
ObjectFactory<byte[]> rawFactory = new RawObjectFactory();
|
||||
ObjectFactory<Person> personFactory = new PersonObjectFactory();
|
||||
|
||||
|
||||
RedisTemplate<String, String> stringTemplate = new StringRedisTemplate();
|
||||
stringTemplate.setConnectionFactory(connectionFactory);
|
||||
stringTemplate.afterPropertiesSet();
|
||||
|
||||
@@ -82,6 +82,7 @@ public class DefaultReactiveHashOperationsIntegrationTests<K, HK, HV> {
|
||||
lettuceConnectionFactory.setPort(SettingsUtils.getPort());
|
||||
lettuceConnectionFactory.setHostName(SettingsUtils.getHost());
|
||||
lettuceConnectionFactory.afterPropertiesSet();
|
||||
lettuceConnectionFactory.start();
|
||||
|
||||
RedisSerializationContext<String, String> serializationContext = RedisSerializationContext
|
||||
.fromSerializer(StringRedisSerializer.UTF_8);
|
||||
|
||||
@@ -66,6 +66,7 @@ class RedisMessageListenerContainerFailureIntegrationTests {
|
||||
|
||||
connectionFactory = new JedisConnectionFactory(configuration);
|
||||
connectionFactory.afterPropertiesSet();
|
||||
connectionFactory.start();
|
||||
|
||||
container = new RedisMessageListenerContainer();
|
||||
container.setConnectionFactory(connectionFactory);
|
||||
|
||||
@@ -27,10 +27,12 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
|
||||
import org.springframework.data.redis.test.condition.EnabledOnRedisClusterAvailable;
|
||||
import org.springframework.lang.NonNullApi;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
@@ -54,17 +56,19 @@ class RedisRepositoryClusterIntegrationTests extends RedisRepositoryIntegrationT
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
RedisTemplate<?, ?> redisTemplate() {
|
||||
|
||||
RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(CLUSTER_NODES);
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(clusterConfig);
|
||||
|
||||
connectionFactory.afterPropertiesSet();
|
||||
RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) {
|
||||
|
||||
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(connectionFactory);
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
@Bean
|
||||
RedisConnectionFactory connectionFactory() {
|
||||
RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(CLUSTER_NODES);
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(clusterConfig);
|
||||
return connectionFactory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.data.convert.ConfigurableTypeInformationMapper;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
@@ -61,10 +62,12 @@ public class RedisRepositoryIntegrationTests extends RedisRepositoryIntegrationT
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
RedisTemplate<?, ?> redisTemplate() {
|
||||
RedisConnectionFactory connectionFactory() {
|
||||
return new JedisConnectionFactory();
|
||||
}
|
||||
|
||||
JedisConnectionFactory connectionFactory = new JedisConnectionFactory();
|
||||
connectionFactory.afterPropertiesSet();
|
||||
@Bean
|
||||
RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) {
|
||||
|
||||
RedisTemplate<String, String> template = new RedisTemplate<>();
|
||||
template.setDefaultSerializer(StringRedisSerializer.UTF_8);
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2023 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 org.springframework.data.redis.util;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class ConnectionVerifier<T extends RedisConnectionFactory> {
|
||||
|
||||
private final T connectionFactory;
|
||||
private final List<Consumer<RedisConnection>> steps = new ArrayList<>(3);
|
||||
|
||||
private Consumer<T> initFactoryFunction = this::initializeFactoryIfRequired;
|
||||
|
||||
ConnectionVerifier(T connectionFactory) {
|
||||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
public static <V extends RedisConnectionFactory> ConnectionVerifier<V> create(V connectionFactory) {
|
||||
return new ConnectionVerifier<>(connectionFactory);
|
||||
}
|
||||
|
||||
public ConnectionVerifier<T> initializeFactory(Consumer<T> initFunction) {
|
||||
|
||||
this.initFactoryFunction = initFunction;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConnectionVerifier<T> execute(Consumer<RedisConnection> connectionConsumer) {
|
||||
this.steps.add(connectionConsumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void verify() {
|
||||
verifyAndRun(it -> {});
|
||||
}
|
||||
|
||||
public void verifyAndClose() {
|
||||
verifyAndRun(this::disposeFactoryIfNeeded);
|
||||
}
|
||||
|
||||
public void verifyAndRun(Consumer<T> disposeFunction) {
|
||||
|
||||
initFactoryFunction.accept(connectionFactory);
|
||||
|
||||
try (RedisConnection connection = connectionFactory.getConnection()) {
|
||||
steps.forEach(step -> step.accept(connection));
|
||||
} finally {
|
||||
disposeFunction.accept(connectionFactory);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeFactoryIfRequired(T factory) {
|
||||
|
||||
if (factory instanceof InitializingBean initializingBean) {
|
||||
try {
|
||||
initializingBean.afterPropertiesSet();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (factory instanceof SmartLifecycle smartLifecycle) {
|
||||
if (smartLifecycle.isAutoStartup() && !smartLifecycle.isRunning()) {
|
||||
smartLifecycle.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeFactoryIfNeeded(T it) {
|
||||
|
||||
if (it instanceof DisposableBean bean) {
|
||||
try {
|
||||
bean.destroy();
|
||||
} catch (Exception e) {
|
||||
throw new DataAccessResourceFailureException("Cannot close resource", e);
|
||||
}
|
||||
} else if (it instanceof Closeable closeable) {
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (IOException e) {
|
||||
throw new DataAccessResourceFailureException("Cannot close resource", e);
|
||||
}
|
||||
} else if (it instanceof SmartLifecycle smartLifecycle && smartLifecycle.isRunning()) {
|
||||
smartLifecycle.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user