/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.cluster; import com.hazelcast.config.Config; import com.hazelcast.config.JoinConfig; import com.hazelcast.config.NetworkConfig; import com.hazelcast.config.TcpIpConfig; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.Member; import com.hazelcast.instance.HazelcastInstanceFactory; import com.hazelcast.instance.Node; import com.hazelcast.internal.cluster.impl.ClusterServiceImpl; import com.hazelcast.test.HazelcastSerialClassRunner; import com.hazelcast.test.annotation.QuickTest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import java.util.HashSet; import java.util.Set; import static com.hazelcast.test.HazelcastTestSupport.assertClusterSize; import static com.hazelcast.test.HazelcastTestSupport.assertClusterSizeEventually; import static com.hazelcast.test.HazelcastTestSupport.closeConnectionBetween; import static com.hazelcast.test.HazelcastTestSupport.getNode; import static com.hazelcast.test.HazelcastTestSupport.randomString; import static org.junit.Assert.assertTrue; @RunWith(HazelcastSerialClassRunner.class) @Category(QuickTest.class) public class LiteMemberJoinTest { private final String name = randomString(); private final String pw = randomString(); @Before @After public void cleanup() { HazelcastInstanceFactory.terminateAll(); } @Test public void test_liteMemberIsCreated() { final Config liteConfig = new Config().setLiteMember(true); final HazelcastInstance liteInstance = Hazelcast.newHazelcastInstance(liteConfig); assertTrue(getNode(liteInstance).isLiteMember()); final Member liteMember = liteInstance.getCluster().getLocalMember(); assertTrue(liteMember.isLiteMember()); } @Test public void test_liteMemberBecomesMaster_tcp() { test_liteMemberBecomesMaster(ConfigCreator.TCP_CONFIG_CREATOR); } @Test public void test_liteMemberBecomesMaster_multicast() { test_liteMemberBecomesMaster(ConfigCreator.MULTICAST_CONFIG_CREATOR); } private void test_liteMemberBecomesMaster(final ConfigCreator configCreator) { final HazelcastInstance liteMaster = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, true)); final HazelcastInstance other = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, false)); assertTrue(getNode(liteMaster).isMaster()); assertClusterSize(2, liteMaster); assertClusterSize(2, other); final Set<Member> members = other.getCluster().getMembers(); assertLiteMemberExcluding(members, other); } @Test public void test_liteMemberJoinsToCluster_tcp() { test_liteMemberJoinsToCluster(ConfigCreator.TCP_CONFIG_CREATOR); } @Test public void test_liteMemberJoinsToCluster_multicast() { test_liteMemberJoinsToCluster(ConfigCreator.MULTICAST_CONFIG_CREATOR); } private void test_liteMemberJoinsToCluster(final ConfigCreator configCreator) { final HazelcastInstance master = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, false)); Hazelcast.newHazelcastInstance(configCreator.create(name, pw, true)); final Set<Member> members = master.getCluster().getMembers(); assertLiteMemberExcluding(members, master); } @Test public void test_liteMemberBecomesVisibleTo2ndNode_tcp() { test_liteMemberBecomesVisibleTo2ndNode(ConfigCreator.TCP_CONFIG_CREATOR); } @Test public void test_liteMemberBecomesVisibleTo2ndNode_multicast() { test_liteMemberBecomesVisibleTo2ndNode(ConfigCreator.MULTICAST_CONFIG_CREATOR); } private void test_liteMemberBecomesVisibleTo2ndNode(final ConfigCreator configCreator) { final HazelcastInstance master = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, false)); final HazelcastInstance other = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, false)); final HazelcastInstance other2 = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, true)); assertClusterSize(3, master, other2); assertClusterSizeEventually(3, other); final Set<Member> members = other.getCluster().getMembers(); assertLiteMemberExcluding(members, master, other); } @Test public void test_liteMemberBecomesVisibleTo3rdNode_tcp() { test_liteMemberBecomesVisibleTo3rdNode(ConfigCreator.TCP_CONFIG_CREATOR); } @Test public void test_liteMemberBecomesVisibleTo3rdNode_multicast() { test_liteMemberBecomesVisibleTo3rdNode(ConfigCreator.MULTICAST_CONFIG_CREATOR); } private void test_liteMemberBecomesVisibleTo3rdNode(final ConfigCreator configCreator) { final HazelcastInstance master = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, false)); Hazelcast.newHazelcastInstance(configCreator.create(name, pw, true)); final HazelcastInstance other = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, false)); final Set<Member> members = other.getCluster().getMembers(); assertLiteMemberExcluding(members, master, other); } @Test public void test_liteMemberReconnects_tcp() { test_liteMemberReconnects(ConfigCreator.TCP_CONFIG_CREATOR); } @Test public void test_liteMemberReconnects_multicast() { test_liteMemberReconnects(ConfigCreator.MULTICAST_CONFIG_CREATOR); } private void test_liteMemberReconnects(final ConfigCreator configCreator) { final HazelcastInstance master = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, false)); final HazelcastInstance liteInstance = Hazelcast.newHazelcastInstance(configCreator.create(name, pw, true)); closeConnectionBetween(master, liteInstance); assertClusterSizeEventually(1, master); assertClusterSizeEventually(1, liteInstance); reconnect(master, liteInstance); assertClusterSizeEventually(2, master, liteInstance); final Set<Member> members = master.getCluster().getMembers(); assertLiteMemberExcluding(members, master); } private void reconnect(final HazelcastInstance instance1, final HazelcastInstance instance2) { final Node node1 = getNode(instance1); final Node node2 = getNode(instance2); final ClusterServiceImpl clusterService = node1.getClusterService(); clusterService.merge(node2.address); } private void assertLiteMemberExcluding(final Set<Member> members, final HazelcastInstance... membersToExclude) { final Set<Member> membersCopy = new HashSet<Member>(members); assertTrue((members.size() - 1) == membersToExclude.length); for (HazelcastInstance memberToExclude : membersToExclude) { assertTrue(membersCopy.remove(memberToExclude.getCluster().getLocalMember())); } final Member liteMember = membersCopy.iterator().next(); assertTrue(liteMember.isLiteMember()); } private enum ConfigCreator { TCP_CONFIG_CREATOR { @Override public Config create(String name, String pw, boolean liteMember) { Config config = new Config(); config.getGroupConfig().setName(name); config.getGroupConfig().setPassword(pw); config.setLiteMember(liteMember); NetworkConfig networkConfig = config.getNetworkConfig(); JoinConfig join = networkConfig.getJoin(); join.getMulticastConfig().setEnabled(false); TcpIpConfig tcpIpConfig = join.getTcpIpConfig(); tcpIpConfig.setEnabled(true); tcpIpConfig.addMember("127.0.0.1"); return config; } }, MULTICAST_CONFIG_CREATOR { @Override public Config create(String name, String pw, boolean liteMember) { Config config = new Config(); config.getGroupConfig().setName(name); config.getGroupConfig().setPassword(pw); config.setLiteMember(liteMember); NetworkConfig networkConfig = config.getNetworkConfig(); JoinConfig join = networkConfig.getJoin(); join.getTcpIpConfig().setEnabled(false); join.getMulticastConfig().setEnabled(true); return config; } }; public abstract Config create(String name, String pw, boolean liteMember); } }