diff --git a/Makefile b/Makefile
index 9c1d2bae76..4d765fab64 100644
--- a/Makefile
+++ b/Makefile
@@ -211,6 +211,19 @@ cluster-enabled yes
cluster-config-file /tmp/redis_cluster_node5.conf
endef
+# UDS REDIS NODES
+define REDIS_UDS
+daemonize yes
+protected-mode no
+port 0
+pidfile /tmp/redis_uds.pid
+logfile /tmp/redis_uds.log
+unixsocket /tmp/redis_6379.sock
+unixsocketperm 777
+save ""
+appendonly no
+endef
+
#STUNNEL
define STUNNEL_CONF
cert = src/test/resources/private.pem
@@ -236,6 +249,7 @@ export REDIS_CLUSTER_NODE2_CONF
export REDIS_CLUSTER_NODE3_CONF
export REDIS_CLUSTER_NODE4_CONF
export REDIS_CLUSTER_NODE5_CONF
+export REDIS_UDS
export STUNNEL_CONF
export STUNNEL_BIN
@@ -265,6 +279,7 @@ start: stunnel cleanup
echo "$$REDIS_CLUSTER_NODE3_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE4_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE5_CONF" | redis-server -
+ echo "$$REDIS_UDS" | redis-server -
cleanup:
- rm -vf /tmp/redis_cluster_node*.conf 2>/dev/null
@@ -291,6 +306,7 @@ stop:
kill `cat /tmp/redis_cluster_node3.pid` || true
kill `cat /tmp/redis_cluster_node4.pid` || true
kill `cat /tmp/redis_cluster_node5.pid` || true
+ kill `cat /tmp/redis_uds.pid` || true
kill `cat /tmp/stunnel.pid` || true
rm -f /tmp/sentinel1.conf
rm -f /tmp/sentinel2.conf
diff --git a/pom.xml b/pom.xml
index 4f9e8bebb5..08f62d591f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,6 +48,7 @@
localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383,localhost:6384,localhost:6385
localhost:26379,localhost:26380,localhost:26381
localhost:7379,localhost:7380,localhost:7381,localhost:7382,localhost:7383,localhost:7384,localhost:7385
+ /tmp/redis_6379.sock
github
@@ -64,6 +65,11 @@
jar
compile
+
+ com.kohlschutter.junixsocket
+ junixsocket-native-common
+ 2.0.4
+
junit
diff --git a/src/main/java/redis/clients/jedis/BinaryClient.java b/src/main/java/redis/clients/jedis/BinaryClient.java
index a818eff8c5..306273f87a 100644
--- a/src/main/java/redis/clients/jedis/BinaryClient.java
+++ b/src/main/java/redis/clients/jedis/BinaryClient.java
@@ -13,6 +13,7 @@
import static redis.clients.jedis.Protocol.Keyword.STORE;
import static redis.clients.jedis.Protocol.Keyword.WITHSCORES;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -49,6 +50,10 @@ public BinaryClient(final String host) {
super(host);
}
+ public BinaryClient(final File unixDomainSocket) {
+ super(unixDomainSocket);
+ }
+
public BinaryClient(final String host, final int port) {
super(host, port);
}
diff --git a/src/main/java/redis/clients/jedis/BinaryJedis.java b/src/main/java/redis/clients/jedis/BinaryJedis.java
index 85c5b97829..9d8e2578c3 100644
--- a/src/main/java/redis/clients/jedis/BinaryJedis.java
+++ b/src/main/java/redis/clients/jedis/BinaryJedis.java
@@ -3,6 +3,7 @@
import static redis.clients.jedis.Protocol.toByteArray;
import java.io.Closeable;
+import java.io.File;
import java.io.Serializable;
import java.net.URI;
import java.util.AbstractMap;
@@ -56,6 +57,10 @@ public BinaryJedis(final String host) {
}
}
+ public BinaryJedis(final File unixDomainSocket) {
+ client = new Client(unixDomainSocket);
+ }
+
public BinaryJedis(final HostAndPort hp) {
this(hp.getHost(), hp.getPort());
}
diff --git a/src/main/java/redis/clients/jedis/Client.java b/src/main/java/redis/clients/jedis/Client.java
index 40a6c7cd4d..e567c203a2 100644
--- a/src/main/java/redis/clients/jedis/Client.java
+++ b/src/main/java/redis/clients/jedis/Client.java
@@ -2,6 +2,7 @@
import static redis.clients.jedis.Protocol.toByteArray;
+import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -30,6 +31,10 @@ public Client(final String host) {
super(host);
}
+ public Client(final File unixDomainSocket) {
+ super(unixDomainSocket);
+ }
+
public Client(final String host, final int port) {
super(host, port);
}
diff --git a/src/main/java/redis/clients/jedis/Connection.java b/src/main/java/redis/clients/jedis/Connection.java
index 2ae106867f..6291288eca 100644
--- a/src/main/java/redis/clients/jedis/Connection.java
+++ b/src/main/java/redis/clients/jedis/Connection.java
@@ -1,9 +1,11 @@
package redis.clients.jedis;
import java.io.Closeable;
+import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.SocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
@@ -13,6 +15,8 @@
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
+import org.newsclub.net.unix.AFUNIXSocket;
+import org.newsclub.net.unix.AFUNIXSocketAddress;
import redis.clients.jedis.commands.ProtocolCommand;
import redis.clients.jedis.exceptions.JedisConnectionException;
import redis.clients.jedis.exceptions.JedisDataException;
@@ -37,6 +41,7 @@ public class Connection implements Closeable {
private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private HostnameVerifier hostnameVerifier;
+ private File unixDomainSocket;
public Connection() {
}
@@ -45,6 +50,10 @@ public Connection(final String host) {
this.host = host;
}
+ public Connection(final File unixDomainSocket) {
+ this.unixDomainSocket = unixDomainSocket;
+ }
+
public Connection(final String host, final int port) {
this.host = host;
this.port = port;
@@ -166,19 +175,27 @@ public void setPort(final int port) {
public void connect() {
if (!isConnected()) {
try {
- socket = new Socket();
- // ->@wjw_add
- socket.setReuseAddress(true);
- socket.setKeepAlive(true); // Will monitor the TCP connection is
- // valid
- socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
- // ensure timely delivery of data
- socket.setSoLinger(true, 0); // Control calls close () method,
- // the underlying socket is closed
- // immediately
- // <-@wjw_add
-
- socket.connect(new InetSocketAddress(host, port), connectionTimeout);
+ SocketAddress socketAddress;
+ if (unixDomainSocket == null) {
+ socket = new Socket();
+ // ->@wjw_add
+ socket.setReuseAddress(true);
+ socket.setKeepAlive(true); // Will monitor the TCP connection is
+ // valid
+ socket.setTcpNoDelay(true); // Socket buffer Whetherclosed, to
+ // ensure timely delivery of data
+ socket.setSoLinger(true, 0); // Control calls close () method,
+ // the underlying socket is closed
+ // immediately
+ // <-@wjw_add
+ socketAddress = new InetSocketAddress(host, port);
+ } else {
+ // unix domain socket doesn't support above options
+ socket = AFUNIXSocket.newStrictInstance();
+ socketAddress = new AFUNIXSocketAddress(unixDomainSocket);
+ }
+
+ socket.connect(socketAddress, connectionTimeout);
socket.setSoTimeout(soTimeout);
if (ssl) {
@@ -201,8 +218,13 @@ public void connect() {
inputStream = new RedisInputStream(socket.getInputStream());
} catch (IOException ex) {
broken = true;
- throw new JedisConnectionException("Failed connecting to host "
- + host + ":" + port, ex);
+ if (unixDomainSocket == null) {
+ throw new JedisConnectionException("Failed connecting to host "
+ + host + ":" + port, ex);
+ } else {
+ throw new JedisConnectionException("Failed connecting to socket "
+ + unixDomainSocket, ex);
+ }
}
}
}
diff --git a/src/main/java/redis/clients/jedis/Jedis.java b/src/main/java/redis/clients/jedis/Jedis.java
index e83e891672..284730126d 100644
--- a/src/main/java/redis/clients/jedis/Jedis.java
+++ b/src/main/java/redis/clients/jedis/Jedis.java
@@ -1,5 +1,6 @@
package redis.clients.jedis;
+import java.io.File;
import java.net.URI;
import java.util.AbstractMap;
import java.util.ArrayList;
@@ -42,6 +43,10 @@ public Jedis(final String host) {
super(host);
}
+ public Jedis(final File unixDomainSocket) {
+ super(unixDomainSocket);
+ }
+
public Jedis(final HostAndPort hp) {
super(hp);
}
diff --git a/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java b/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java
index ced599cc05..01e9b8a109 100644
--- a/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java
+++ b/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java
@@ -1,5 +1,6 @@
package redis.clients.jedis.tests;
+import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -10,6 +11,7 @@ public final class HostAndPortUtil {
private static List redisHostAndPortList = new ArrayList();
private static List sentinelHostAndPortList = new ArrayList();
private static List clusterHostAndPortList = new ArrayList();
+ private static List redisUDSList = new ArrayList();
private HostAndPortUtil(){
throw new InstantiationError( "Must not instantiate this class" );
@@ -36,13 +38,17 @@ private HostAndPortUtil(){
clusterHostAndPortList.add(new HostAndPort("localhost", 7383));
clusterHostAndPortList.add(new HostAndPort("localhost", 7384));
+ redisUDSList.add(new File("/tmp/redis_6379.sock"));
+
String envRedisHosts = System.getProperty("redis-hosts");
String envSentinelHosts = System.getProperty("sentinel-hosts");
String envClusterHosts = System.getProperty("cluster-hosts");
+ String envUDSHosts = System.getProperty("uds-hosts");
redisHostAndPortList = parseHosts(envRedisHosts, redisHostAndPortList);
sentinelHostAndPortList = parseHosts(envSentinelHosts, sentinelHostAndPortList);
clusterHostAndPortList = parseHosts(envClusterHosts, clusterHostAndPortList);
+ redisUDSList = parseUDSHosts(envUDSHosts, redisUDSList);
}
public static List parseHosts(String envHosts,
@@ -80,6 +86,19 @@ public static List parseHosts(String envHosts,
return existingHostsAndPorts;
}
+ public static List parseUDSHosts(String envHosts, List existingUDSHosts) {
+ if (null != envHosts && 0 < envHosts.length()) {
+
+ String[] hostDefs = envHosts.split(",");
+
+ List envUDSHosts = new ArrayList<>();
+ for (String hostDef : hostDefs) {
+ envUDSHosts.add(new File(hostDef));
+ }
+ }
+ return existingUDSHosts;
+ }
+
public static List getRedisServers() {
return redisHostAndPortList;
}
@@ -91,4 +110,8 @@ public static List getSentinelServers() {
public static List getClusterServers() {
return clusterHostAndPortList;
}
+
+ public static List getUDSServers() {
+ return redisUDSList;
+ }
}
diff --git a/src/test/java/redis/clients/jedis/tests/UDSTest.java b/src/test/java/redis/clients/jedis/tests/UDSTest.java
new file mode 100644
index 0000000000..2cb3fb32f9
--- /dev/null
+++ b/src/test/java/redis/clients/jedis/tests/UDSTest.java
@@ -0,0 +1,18 @@
+package redis.clients.jedis.tests;
+
+import org.junit.Test;
+import redis.clients.jedis.Jedis;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+
+public class UDSTest {
+ protected static File udsHost = HostAndPortUtil.getUDSServers().get(0);
+ @Test
+ public void testCompareTo() {
+ Jedis jedis = new Jedis(udsHost);
+ assertEquals("PONG", jedis.ping());
+ jedis.close();
+ }
+}