package com.lambdaworks.redis.cluster; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import java.util.stream.Stream; import com.lambdaworks.Wait; import com.lambdaworks.redis.TestSettings; import com.lambdaworks.redis.cluster.api.StatefulRedisClusterConnection; import com.lambdaworks.redis.cluster.api.async.RedisAdvancedClusterAsyncCommands; import com.lambdaworks.redis.cluster.api.async.RedisClusterAsyncCommands; import com.lambdaworks.redis.cluster.api.sync.RedisClusterCommands; import com.lambdaworks.redis.cluster.models.partitions.Partitions; import com.lambdaworks.redis.cluster.models.partitions.RedisClusterNode; /** * @author Mark Paluch */ public class ClusterSetup { /** * Setup a cluster consisting of two members (see {@link AbstractClusterTest#port5} to {@link AbstractClusterTest#port6}). * Two masters (0-11999 and 12000-16383) * * @param clusterRule * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public static void setup2Masters(ClusterRule clusterRule) throws InterruptedException, ExecutionException, TimeoutException { clusterRule.clusterReset(); clusterRule.meet(AbstractClusterTest.host, AbstractClusterTest.port5); clusterRule.meet(AbstractClusterTest.host, AbstractClusterTest.port6); RedisAdvancedClusterAsyncCommands<String, String> connection = clusterRule.getClusterClient().connectClusterAsync(); Wait.untilTrue(() -> { clusterRule.getClusterClient().reloadPartitions(); return clusterRule.getClusterClient().getPartitions().size() == 2; }).waitOrTimeout(); Partitions partitions = clusterRule.getClusterClient().getPartitions(); for (RedisClusterNode partition : partitions) { if (!partition.getSlots().isEmpty()) { RedisClusterAsyncCommands<String, String> nodeConnection = connection.getConnection(partition.getNodeId()); for (Integer slot : partition.getSlots()) { try { nodeConnection.clusterDelSlots(slot); } catch (Exception e) { } } } } RedisClusterAsyncCommands<String, String> node1 = connection.getConnection(AbstractClusterTest.host, AbstractClusterTest.port5); node1.clusterAddSlots(AbstractClusterTest.createSlots(0, 12000)); RedisClusterAsyncCommands<String, String> node2 = connection.getConnection(AbstractClusterTest.host, AbstractClusterTest.port6); node2.clusterAddSlots(AbstractClusterTest.createSlots(12000, 16384)); Wait.untilTrue(clusterRule::isStable).waitOrTimeout(); Wait.untilEquals( 2L, () -> { clusterRule.getClusterClient().reloadPartitions(); return partitionStream(clusterRule).filter( redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.MASTER)).count(); }).waitOrTimeout(); connection.close(); } /** * Setup a cluster consisting of two members (see {@link AbstractClusterTest#port5} to {@link AbstractClusterTest#port6}). * One master (0-16383) and one slave. * * @param clusterRule * @throws InterruptedException * @throws ExecutionException * @throws TimeoutException */ public static void setupMasterWithSlave(ClusterRule clusterRule) throws InterruptedException, ExecutionException, TimeoutException { clusterRule.clusterReset(); clusterRule.meet(AbstractClusterTest.host, AbstractClusterTest.port5); clusterRule.meet(AbstractClusterTest.host, AbstractClusterTest.port6); RedisAdvancedClusterAsyncCommands<String, String> connection = clusterRule.getClusterClient().connectClusterAsync(); StatefulRedisClusterConnection<String, String> statefulConnection = connection.getStatefulConnection(); Wait.untilEquals(2, () -> { clusterRule.getClusterClient().reloadPartitions(); return clusterRule.getClusterClient().getPartitions().size(); }).waitOrTimeout(); RedisClusterCommands<String, String> node1 = statefulConnection.getConnection(TestSettings.hostAddr(), AbstractClusterTest.port5).sync(); node1.clusterAddSlots(AbstractClusterTest.createSlots(0, 16384)); Wait.untilTrue(clusterRule::isStable).waitOrTimeout(); connection.getConnection(AbstractClusterTest.host, AbstractClusterTest.port6).clusterReplicate(node1.clusterMyId()) .get(); clusterRule.getClusterClient().reloadPartitions(); Wait.untilEquals( 1L, () -> { clusterRule.getClusterClient().reloadPartitions(); return partitionStream(clusterRule).filter( redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.MASTER)).count(); }).waitOrTimeout(); Wait.untilEquals( 1L, () -> { clusterRule.getClusterClient().reloadPartitions(); return partitionStream(clusterRule).filter( redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.SLAVE)).count(); }).waitOrTimeout(); connection.close(); } protected static Stream<RedisClusterNode> partitionStream(ClusterRule clusterRule) { return clusterRule.getClusterClient().getPartitions().getPartitions().stream(); } private static boolean is2Masters2Slaves(ClusterRule clusterRule) { RedisClusterClient clusterClient = clusterRule.getClusterClient(); long slaves = clusterClient.getPartitions().stream() .filter(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.SLAVE)).count(); long masters = clusterClient.getPartitions().stream() .filter(redisClusterNode -> redisClusterNode.is(RedisClusterNode.NodeFlag.MASTER)).count(); return slaves == 2 && masters == 2; } }