DATAREDIS-682 - Connect to Redis using unix domain sockets.
We now support Redis connections using OS-native transports through unix domain sockets when using the Lettuce driver. Domain sockets do not require a roundtrip through the networking layer but directly use native epoll or kqueue interfaces.
LettuceConnectionFactory factory = new LettuceConnectionFactory(new RedisSocketConfiguration("/var/run/redis.sock"));
Unix domain socket support requires netty's native epoll/kqueue dependencies matching the runtime environment:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<classifier>linux-x86_64</classifier>
<version>${netty}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-kqueue</artifactId>
<classifier>osx-x86_64</classifier>
<version>${netty}</version>
</dependency>
Original Pull Request: #286
This commit is contained in:
committed by
Christoph Strobl
parent
5c16a6044c
commit
d08ab93421
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-2017 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.
|
||||
@@ -17,19 +17,25 @@ package org.springframework.data.redis;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.data.redis.connection.RedisSocketConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
|
||||
/**
|
||||
* Utility class exposing connection settings to connect Redis instances during test execution. Settings can be adjusted
|
||||
* by overriding these in {@literal org/springframework/data/redis/test.properties}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public abstract class SettingsUtils {
|
||||
|
||||
private final static Properties DEFAULTS = new Properties();
|
||||
private static final Properties SETTINGS;
|
||||
|
||||
static {
|
||||
DEFAULTS.put("host", "127.0.0.1");
|
||||
DEFAULTS.put("port", "6379");
|
||||
DEFAULTS.put("socket", "work/redis-6379.sock");
|
||||
|
||||
SETTINGS = new Properties(DEFAULTS);
|
||||
|
||||
@@ -40,15 +46,44 @@ public abstract class SettingsUtils {
|
||||
}
|
||||
}
|
||||
|
||||
private SettingsUtils() {}
|
||||
|
||||
/**
|
||||
* @return the Redis hostname.
|
||||
*/
|
||||
public static String getHost() {
|
||||
return SETTINGS.getProperty("host");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Redis port.
|
||||
*/
|
||||
public static int getPort() {
|
||||
return Integer.valueOf(SETTINGS.getProperty("port"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return path to the unix domain socket.
|
||||
*/
|
||||
public static String getSocket() {
|
||||
return SETTINGS.getProperty("socket");
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link RedisStandaloneConfiguration} initialized with test endpoint settings.
|
||||
*
|
||||
* @return a new {@link RedisStandaloneConfiguration} initialized with test endpoint settings.
|
||||
*/
|
||||
public static RedisStandaloneConfiguration standaloneConfiguration() {
|
||||
return new RedisStandaloneConfiguration(getHost(), getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@link RedisSocketConfiguration} initialized with test endpoint settings.
|
||||
*
|
||||
* @return a new {@link RedisSocketConfiguration} initialized with test endpoint settings.
|
||||
*/
|
||||
public static RedisSocketConfiguration socketConfiguration() {
|
||||
return new RedisSocketConfiguration(getSocket());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,15 @@ import static org.hamcrest.core.Is.*;
|
||||
import static org.hamcrest.core.IsEqual.*;
|
||||
import static org.hamcrest.core.IsNull.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
import io.lettuce.core.EpollProvider;
|
||||
import io.lettuce.core.KqueueProvider;
|
||||
import io.lettuce.core.RedisException;
|
||||
import io.lettuce.core.api.async.RedisAsyncCommands;
|
||||
import io.lettuce.core.api.reactive.BaseRedisReactiveCommands;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Duration;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
@@ -362,6 +366,25 @@ public class LettuceConnectionFactoryTests {
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-687
|
||||
public void connectsThroughRedisSocket() {
|
||||
|
||||
assumeTrue(EpollProvider.isAvailable() || KqueueProvider.isAvailable());
|
||||
assumeTrue(new File(SettingsUtils.getSocket()).exists());
|
||||
|
||||
LettuceClientConfiguration configuration = LettuceTestClientConfiguration.create();
|
||||
|
||||
LettuceConnectionFactory factory = new LettuceConnectionFactory(SettingsUtils.socketConfiguration(), configuration);
|
||||
factory.setShareNativeConnection(false);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
RedisConnection connection = factory.getConnection();
|
||||
assertThat(connection.ping(), is(equalTo("PONG")));
|
||||
|
||||
connection.close();
|
||||
factory.destroy();
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-576
|
||||
public void connectionAppliesClientName() {
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisClusterConnection;
|
||||
import org.springframework.data.redis.connection.RedisPassword;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisSocketConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
@@ -285,6 +286,21 @@ public class LettuceConnectionFactoryUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-682
|
||||
public void socketShouldBeSetOnStandaloneClient() {
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(new RedisSocketConfiguration());
|
||||
connectionFactory.afterPropertiesSet();
|
||||
ConnectionFactoryTracker.add(connectionFactory);
|
||||
|
||||
AbstractRedisClient client = (AbstractRedisClient) getField(connectionFactory, "client");
|
||||
assertThat(client, instanceOf(RedisClient.class));
|
||||
|
||||
RedisURI redisUri = (RedisURI) getField(client, "redisURI");
|
||||
|
||||
assertThat(redisUri.getSocket(), is("/tmp/redis.sock"));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-574
|
||||
public void shouldReadStandalonePassword() {
|
||||
|
||||
@@ -337,6 +353,20 @@ public class LettuceConnectionFactoryUnitTests {
|
||||
assertThat(envConfig.getPassword(), is(equalTo(RedisPassword.of("bar"))));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-682
|
||||
public void shouldWriteSocketPassword() {
|
||||
|
||||
RedisSocketConfiguration envConfig = new RedisSocketConfiguration();
|
||||
envConfig.setPassword(RedisPassword.of("foo"));
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig,
|
||||
LettuceClientConfiguration.defaultConfiguration());
|
||||
connectionFactory.setPassword("bar");
|
||||
|
||||
assertThat(connectionFactory.getPassword(), is(equalTo("bar")));
|
||||
assertThat(envConfig.getPassword(), is(equalTo(RedisPassword.of("bar"))));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-574
|
||||
public void shouldReadClusterPassword() {
|
||||
|
||||
@@ -415,6 +445,20 @@ public class LettuceConnectionFactoryUnitTests {
|
||||
assertThat(envConfig.getDatabase(), is(3));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-682
|
||||
public void shouldWriteSocketDatabaseIndex() {
|
||||
|
||||
RedisSocketConfiguration envConfig = new RedisSocketConfiguration();
|
||||
envConfig.setDatabase(2);
|
||||
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(envConfig,
|
||||
LettuceClientConfiguration.defaultConfiguration());
|
||||
connectionFactory.setDatabase(3);
|
||||
|
||||
assertThat(connectionFactory.getDatabase(), is(3));
|
||||
assertThat(envConfig.getDatabase(), is(3));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-574
|
||||
public void shouldApplyClientConfiguration() {
|
||||
|
||||
@@ -456,6 +500,19 @@ public class LettuceConnectionFactoryUnitTests {
|
||||
assertThat(connectionFactory.getClusterConfiguration(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-682
|
||||
public void shouldReturnSocketConfiguration() {
|
||||
|
||||
RedisSocketConfiguration configuration = new RedisSocketConfiguration("/var/redis/socket");
|
||||
LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(configuration,
|
||||
LettuceClientConfiguration.defaultConfiguration());
|
||||
|
||||
assertThat(connectionFactory.getStandaloneConfiguration(), is(notNullValue()));
|
||||
assertThat(connectionFactory.getSocketConfiguration(), is(configuration));
|
||||
assertThat(connectionFactory.getSentinelConfiguration(), is(nullValue()));
|
||||
assertThat(connectionFactory.getClusterConfiguration(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test // DATAREDIS-574
|
||||
public void shouldReturnSentinelConfiguration() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user