diff --git a/src/main/asciidoc/reference/redis.adoc b/src/main/asciidoc/reference/redis.adoc index 96be9c7ee..d9fcdd233 100644 --- a/src/main/asciidoc/reference/redis.adoc +++ b/src/main/asciidoc/reference/redis.adoc @@ -133,7 +133,7 @@ class WriteToMasterReadFromReplicaConfiguration { } ---- -TIP: For environments reporting non-public addresses through the `INFO` command (for example, when using AWS), use `RedisStaticMasterReplicaConfiguration` instead of `RedisStandaloneConfiguration`. +TIP: For environments reporting non-public addresses through the `INFO` command (for example, when using AWS), use `RedisStaticMasterReplicaConfiguration` instead of `RedisStandaloneConfiguration`. Please note that `RedisStaticMasterReplicaConfiguration` does not support Pub/Sub because of missing Pub/Sub message propagation across individual servers. [[redis:sentinel]] == Redis Sentinel Support diff --git a/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java b/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java index 2efa63f84..129d2acb7 100644 --- a/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java +++ b/src/main/java/org/springframework/data/redis/connection/RedisStaticMasterReplicaConfiguration.java @@ -27,6 +27,7 @@ import org.springframework.util.Assert; * Master / Replica configuration to nodes know to not change address. Eg. when connecting to * AWS ElastiCache with Read Replicas.
* Note: Redis is undergoing a nomenclature change where the term replica is used synonymously to slave. + * Please also note that a Master/Replica connection cannot be used for Pub/Sub operations. * * @author Mark Paluch * @author Christoph Strobl diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java b/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java index 16aa041fe..31d10f052 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/StaticMasterReplicaConnectionProvider.java @@ -22,6 +22,7 @@ import io.lettuce.core.api.StatefulConnection; import io.lettuce.core.codec.RedisCodec; import io.lettuce.core.masterreplica.MasterReplica; import io.lettuce.core.masterreplica.StatefulRedisMasterReplicaConnection; +import io.lettuce.core.pubsub.StatefulRedisPubSubConnection; import java.util.Collection; import java.util.Optional; @@ -70,6 +71,10 @@ class StaticMasterReplicaConnectionProvider implements LettuceConnectionProvider @Override public > T getConnection(Class connectionType) { + if (connectionType.equals(StatefulRedisPubSubConnection.class)) { + throw new UnsupportedOperationException("Pub/Sub connections not supported with Master/Replica configurations"); + } + if (StatefulConnection.class.isAssignableFrom(connectionType)) { StatefulRedisMasterReplicaConnection connection = MasterReplica.connect(client, codec, nodes); diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java index ae735cec5..9de79f1f2 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryTests.java @@ -475,6 +475,28 @@ public class LettuceConnectionFactoryTests { factory.destroy(); } + @Test // DATAREDIS-1093 + public void pubSubDoesNotSupportMasterReplicaConnections() { + + assumeTrue(String.format("No replicas connected to %s:%s.", SettingsUtils.getHost(), SettingsUtils.getPort()), + connection.info("replication").getProperty("connected_slaves", "0").compareTo("0") > 0); + + RedisStaticMasterReplicaConfiguration elastiCache = new RedisStaticMasterReplicaConfiguration( + SettingsUtils.getHost()).node(SettingsUtils.getHost(), SettingsUtils.getPort() + 1); + + LettuceConnectionFactory factory = new LettuceConnectionFactory(elastiCache); + factory.setClientResources(LettuceTestClientResources.getSharedClientResources()); + factory.afterPropertiesSet(); + + RedisConnection connection = factory.getConnection(); + + assertThatThrownBy(() -> connection.pSubscribe((message, pattern) -> { + }, "foo".getBytes())).isInstanceOf(RedisSystemException.class).hasCauseInstanceOf(UnsupportedOperationException.class); + + connection.close(); + factory.destroy(); + } + @Test // DATAREDIS-762, DATAREDIS-869 public void factoryUsesElastiCacheMasterWithoutMaster() {