Accept cluster nodes without hostname.

RedisNode can now be constructed using an empty hostname. This can happen when a node is in failover state. RedisNode exposes hasValidHost() to check whether the node has a valid hostname.

Also, introduce copy constructor to avoid mutations caused by the builder.

Closes #1985
Original Pull Request: #1991
This commit is contained in:
Mark Paluch
2021-03-03 14:39:43 +01:00
committed by Christoph Strobl
parent b8eabee2b0
commit b5ea3f6826
6 changed files with 69 additions and 4 deletions

View File

@@ -27,6 +27,8 @@ import org.springframework.data.redis.connection.RedisClusterNode.LinkState;
import org.springframework.data.redis.connection.RedisNode.NodeType;
/**
* Unit tests for {@link Converters}.
*
* @author Christoph Strobl
* @author Mark Paluch
*/
@@ -56,6 +58,8 @@ class ConvertersUnitTests {
private static final String CLUSTER_NODE_IMPORTING_SLOT = "ef570f86c7b1a953846668debc177a3a16733420 127.0.0.1:6379 myself,master - 0 0 1 connected [5461-<-0f2ee5df45d18c50aca07228cc18b1da96fd5e84]";
private static final String CLUSTER_NODE_WITHOUT_HOST = "ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected";
@Test // DATAREDIS-315
void toSetOfRedis30ClusterNodesShouldConvertSingleStringNodesResponseCorrectly() {
@@ -194,6 +198,23 @@ class ConvertersUnitTests {
RedisClusterNode node = nodes.next();
assertThat(node.getId()).isEqualTo("ef570f86c7b1a953846668debc177a3a16733420");
assertThat(node.getHost()).isEqualTo("127.0.0.1");
assertThat(node.hasValidHost()).isTrue();
assertThat(node.getPort()).isEqualTo(6379);
assertThat(node.getType()).isEqualTo(NodeType.MASTER);
assertThat(node.getFlags()).contains(Flag.MASTER);
assertThat(node.getLinkState()).isEqualTo(LinkState.CONNECTED);
assertThat(node.getSlotRange().getSlots().size()).isEqualTo(0);
}
@Test // GH-1985
void toSetOfRedisClusterNodesShouldAllowEmptyHostname() {
Iterator<RedisClusterNode> nodes = Converters.toSetOfRedisClusterNodes(CLUSTER_NODE_WITHOUT_HOST).iterator();
RedisClusterNode node = nodes.next();
assertThat(node.getId()).isEqualTo("ef570f86c7b1a953846668debc177a3a16733420");
assertThat(node.getHost()).isEmpty();
assertThat(node.hasValidHost()).isFalse();
assertThat(node.getPort()).isEqualTo(6379);
assertThat(node.getType()).isEqualTo(NodeType.MASTER);
assertThat(node.getFlags()).contains(Flag.MASTER);

View File

@@ -383,6 +383,25 @@ class JedisClusterConnectionUnitTests {
verify(con1Mock, times(2)).clusterNodes();
}
@Test // GH-1985
void nodeWithoutHostShouldRejectConnectionAttempt() {
reset(con1Mock, con2Mock, con3Mock);
when(con1Mock.clusterNodes())
.thenReturn("ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected");
when(con2Mock.clusterNodes())
.thenReturn("ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected");
when(con3Mock.clusterNodes())
.thenReturn("ef570f86c7b1a953846668debc177a3a16733420 :6379 fail,master - 0 0 1 connected");
JedisClusterConnection connection = new JedisClusterConnection(clusterMock);
assertThatThrownBy(() -> connection.ping(new RedisClusterNode("ef570f86c7b1a953846668debc177a3a16733420")))
.isInstanceOf(DataAccessResourceFailureException.class)
.hasMessageContaining("ef570f86c7b1a953846668debc177a3a16733420");
}
static class StubJedisCluster extends JedisCluster {
JedisClusterConnectionHandler connectionHandler;