/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.zookeeper.test; import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.zookeeper.PortAssignment; import org.apache.zookeeper.TestableZooKeeper; import org.apache.zookeeper.server.quorum.Election; import org.apache.zookeeper.server.quorum.QuorumPeer; import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType; import org.apache.zookeeper.server.quorum.QuorumPeer.QuorumServer; import org.junit.Assert; import org.junit.Test; import com.sun.management.UnixOperatingSystemMXBean; public class QuorumBase extends ClientBase { private static final Logger LOG = LoggerFactory.getLogger(QuorumBase.class); File s1dir, s2dir, s3dir, s4dir, s5dir; QuorumPeer s1, s2, s3, s4, s5; protected int port1; protected int port2; protected int port3; protected int port4; protected int port5; protected int portLE1; protected int portLE2; protected int portLE3; protected int portLE4; protected int portLE5; @Test // This just avoids complaints by junit public void testNull() { } @Override public void setUp() throws Exception { setUp(false); } protected void setUp(boolean withObservers) throws Exception { LOG.info("QuorumBase.setup " + getTestName()); setupTestEnv(); JMXEnv.setUp(); setUpAll(); port1 = PortAssignment.unique(); port2 = PortAssignment.unique(); port3 = PortAssignment.unique(); port4 = PortAssignment.unique(); port5 = PortAssignment.unique(); portLE1 = PortAssignment.unique(); portLE2 = PortAssignment.unique(); portLE3 = PortAssignment.unique(); portLE4 = PortAssignment.unique(); portLE5 = PortAssignment.unique(); hostPort = "127.0.0.1:" + port1 + ",127.0.0.1:" + port2 + ",127.0.0.1:" + port3 + ",127.0.0.1:" + port4 + ",127.0.0.1:" + port5; LOG.info("Ports are: " + hostPort); s1dir = ClientBase.createTmpDir(); s2dir = ClientBase.createTmpDir(); s3dir = ClientBase.createTmpDir(); s4dir = ClientBase.createTmpDir(); s5dir = ClientBase.createTmpDir(); startServers(withObservers); OperatingSystemMXBean osMbean = ManagementFactory.getOperatingSystemMXBean(); if (osMbean != null && osMbean instanceof UnixOperatingSystemMXBean) { UnixOperatingSystemMXBean unixos = (UnixOperatingSystemMXBean)osMbean; LOG.info("Initial fdcount is: " + unixos.getOpenFileDescriptorCount()); } LOG.info("Setup finished"); } void startServers() throws Exception { startServers(false); } void startServers(boolean withObservers) throws Exception { int tickTime = 2000; int initLimit = 3; int syncLimit = 3; HashMap<Long,QuorumServer> peers = new HashMap<Long,QuorumServer>(); peers.put(Long.valueOf(1), new QuorumServer(1, new InetSocketAddress("127.0.0.1", port1 + 1000), new InetSocketAddress("127.0.0.1", portLE1 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(2), new QuorumServer(2, new InetSocketAddress("127.0.0.1", port2 + 1000), new InetSocketAddress("127.0.0.1", portLE2 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(3), new QuorumServer(3, new InetSocketAddress("127.0.0.1", port3 + 1000), new InetSocketAddress("127.0.0.1", portLE3 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(4), new QuorumServer(4, new InetSocketAddress("127.0.0.1", port4 + 1000), new InetSocketAddress("127.0.0.1", portLE4 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(5), new QuorumServer(5, new InetSocketAddress("127.0.0.1", port5 + 1000), new InetSocketAddress("127.0.0.1", portLE5 + 1000), LearnerType.PARTICIPANT)); if (withObservers) { peers.get(Long.valueOf(4)).type = LearnerType.OBSERVER; peers.get(Long.valueOf(5)).type = LearnerType.OBSERVER; } LOG.info("creating QuorumPeer 1 port " + port1); s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit); Assert.assertEquals(port1, s1.getClientPort()); LOG.info("creating QuorumPeer 2 port " + port2); s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit); Assert.assertEquals(port2, s2.getClientPort()); LOG.info("creating QuorumPeer 3 port " + port3); s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit); Assert.assertEquals(port3, s3.getClientPort()); LOG.info("creating QuorumPeer 4 port " + port4); s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit); Assert.assertEquals(port4, s4.getClientPort()); LOG.info("creating QuorumPeer 5 port " + port5); s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit); Assert.assertEquals(port5, s5.getClientPort()); if (withObservers) { s4.setLearnerType(LearnerType.OBSERVER); s5.setLearnerType(LearnerType.OBSERVER); } LOG.info("QuorumPeer 1 voting view: " + s1.getVotingView()); LOG.info("QuorumPeer 2 voting view: " + s2.getVotingView()); LOG.info("QuorumPeer 3 voting view: " + s3.getVotingView()); LOG.info("QuorumPeer 4 voting view: " + s4.getVotingView()); LOG.info("QuorumPeer 5 voting view: " + s5.getVotingView()); LOG.info("start QuorumPeer 1"); s1.start(); LOG.info("start QuorumPeer 2"); s2.start(); LOG.info("start QuorumPeer 3"); s3.start(); LOG.info("start QuorumPeer 4"); s4.start(); LOG.info("start QuorumPeer 5"); s5.start(); LOG.info("started QuorumPeer 5"); LOG.info ("Checking ports " + hostPort); for (String hp : hostPort.split(",")) { Assert.assertTrue("waiting for server up", ClientBase.waitForServerUp(hp, CONNECTION_TIMEOUT)); LOG.info(hp + " is accepting client connections"); } // interesting to see what's there... JMXEnv.dump(); // make sure we have these 5 servers listed Set<String> ensureNames = new LinkedHashSet<String>(); for (int i = 1; i <= 5; i++) { ensureNames.add("InMemoryDataTree"); } for (int i = 1; i <= 5; i++) { ensureNames.add("name0=ReplicatedServer_id" + i + ",name1=replica." + i + ",name2="); } for (int i = 1; i <= 5; i++) { for (int j = 1; j <= 5; j++) { ensureNames.add("name0=ReplicatedServer_id" + i + ",name1=replica." + j); } } for (int i = 1; i <= 5; i++) { ensureNames.add("name0=ReplicatedServer_id" + i); } JMXEnv.ensureAll(ensureNames.toArray(new String[ensureNames.size()])); } public void setupServers() throws IOException { setupServer(1); setupServer(2); setupServer(3); setupServer(4); setupServer(5); } HashMap<Long,QuorumServer> peers = null; public void setupServer(int i) throws IOException { int tickTime = 2000; int initLimit = 3; int syncLimit = 3; if(peers == null){ peers = new HashMap<Long,QuorumServer>(); peers.put(Long.valueOf(1), new QuorumServer(1, new InetSocketAddress("127.0.0.1", port1 + 1000), new InetSocketAddress("127.0.0.1", portLE1 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(2), new QuorumServer(2, new InetSocketAddress("127.0.0.1", port2 + 1000), new InetSocketAddress("127.0.0.1", portLE2 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(3), new QuorumServer(3, new InetSocketAddress("127.0.0.1", port3 + 1000), new InetSocketAddress("127.0.0.1", portLE3 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(4), new QuorumServer(4, new InetSocketAddress("127.0.0.1", port4 + 1000), new InetSocketAddress("127.0.0.1", portLE4 + 1000), LearnerType.PARTICIPANT)); peers.put(Long.valueOf(5), new QuorumServer(5, new InetSocketAddress("127.0.0.1", port5 + 1000), new InetSocketAddress("127.0.0.1", portLE5 + 1000), LearnerType.PARTICIPANT)); } switch(i){ case 1: LOG.info("creating QuorumPeer 1 port " + port1); s1 = new QuorumPeer(peers, s1dir, s1dir, port1, 3, 1, tickTime, initLimit, syncLimit); Assert.assertEquals(port1, s1.getClientPort()); break; case 2: LOG.info("creating QuorumPeer 2 port " + port2); s2 = new QuorumPeer(peers, s2dir, s2dir, port2, 3, 2, tickTime, initLimit, syncLimit); Assert.assertEquals(port2, s2.getClientPort()); break; case 3: LOG.info("creating QuorumPeer 3 port " + port3); s3 = new QuorumPeer(peers, s3dir, s3dir, port3, 3, 3, tickTime, initLimit, syncLimit); Assert.assertEquals(port3, s3.getClientPort()); break; case 4: LOG.info("creating QuorumPeer 4 port " + port4); s4 = new QuorumPeer(peers, s4dir, s4dir, port4, 3, 4, tickTime, initLimit, syncLimit); Assert.assertEquals(port4, s4.getClientPort()); break; case 5: LOG.info("creating QuorumPeer 5 port " + port5); s5 = new QuorumPeer(peers, s5dir, s5dir, port5, 3, 5, tickTime, initLimit, syncLimit); Assert.assertEquals(port5, s5.getClientPort()); } } @Override public void tearDown() throws Exception { LOG.info("TearDown started"); OperatingSystemMXBean osMbean = ManagementFactory.getOperatingSystemMXBean(); if (osMbean != null && osMbean instanceof UnixOperatingSystemMXBean) { UnixOperatingSystemMXBean unixos = (UnixOperatingSystemMXBean)osMbean; LOG.info("fdcount after test is: " + unixos.getOpenFileDescriptorCount()); } shutdownServers(); for (String hp : hostPort.split(",")) { Assert.assertTrue("waiting for server down", ClientBase.waitForServerDown(hp, ClientBase.CONNECTION_TIMEOUT)); LOG.info(hp + " is no longer accepting client connections"); } JMXEnv.tearDown(); } public void shutdownServers() { shutdown(s1); shutdown(s2); shutdown(s3); shutdown(s4); shutdown(s5); } public static void shutdown(QuorumPeer qp) { try { LOG.info("Shutting down quorum peer " + qp.getName()); qp.shutdown(); Election e = qp.getElectionAlg(); if (e != null) { LOG.info("Shutting down leader election " + qp.getName()); e.shutdown(); } else { LOG.info("No election available to shutdown " + qp.getName()); } LOG.info("Waiting for " + qp.getName() + " to exit thread"); qp.join(30000); if (qp.isAlive()) { Assert.fail("QP failed to shutdown in 30 seconds: " + qp.getName()); } } catch (InterruptedException e) { LOG.debug("QP interrupted: " + qp.getName(), e); } } protected TestableZooKeeper createClient() throws IOException, InterruptedException { return createClient(hostPort); } protected TestableZooKeeper createClient(String hp) throws IOException, InterruptedException { CountdownWatcher watcher = new CountdownWatcher(); return createClient(watcher, hp); } }