001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import java.io.File; 021import java.io.IOException; 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.fs.Path; 024import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster; 025import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 026import org.apache.yetus.audience.InterfaceAudience; 027 028/** 029 * Helpers for testing HBase that do not depend on specific server/etc. things. The main difference 030 * from {@link HBaseCommonTestingUtility} is that we can start a zookeeper cluster. 031 * @deprecated since 3.0.0, will be removed in 4.0.0. Use 032 * {@link org.apache.hadoop.hbase.testing.TestingHBaseCluster} instead. 033 */ 034@InterfaceAudience.Public 035@Deprecated 036public class HBaseZKTestingUtility extends HBaseCommonTestingUtility { 037 private MiniZooKeeperCluster zkCluster; 038 039 /** 040 * Set if we were passed a zkCluster. If so, we won't shutdown zk as part of general shutdown. 041 */ 042 private boolean passedZkCluster; 043 044 protected ZKWatcher zooKeeperWatcher; 045 046 /** Directory (a subdirectory of dataTestDir) used by the dfs cluster if any */ 047 protected File clusterTestDir; 048 049 public HBaseZKTestingUtility() { 050 this(HBaseConfiguration.create()); 051 } 052 053 public HBaseZKTestingUtility(Configuration conf) { 054 super(conf); 055 } 056 057 /** 058 * @return Where the cluster will write data on the local subsystem. Creates it if it does not 059 * exist already. A subdir of {@code HBaseCommonTestingUtility#getBaseTestDir()} 060 */ 061 Path getClusterTestDir() { 062 if (clusterTestDir == null) { 063 setupClusterTestDir(); 064 } 065 return new Path(clusterTestDir.getAbsolutePath()); 066 } 067 068 /** 069 * Creates a directory for the cluster, under the test data 070 */ 071 protected void setupClusterTestDir() { 072 if (clusterTestDir != null) { 073 return; 074 } 075 076 // Using randomUUID ensures that multiple clusters can be launched by 077 // a same test, if it stops & starts them 078 Path testDir = getDataTestDir("cluster_" + getRandomUUID().toString()); 079 clusterTestDir = new File(testDir.toString()).getAbsoluteFile(); 080 // Have it cleaned up on exit 081 boolean b = deleteOnExit(); 082 if (b) { 083 clusterTestDir.deleteOnExit(); 084 } 085 LOG.info("Created new mini-cluster data directory: " + clusterTestDir + ", deleteOnExit=" + b); 086 } 087 088 /** 089 * Call this if you only want a zk cluster. 090 * @see #shutdownMiniZKCluster() 091 * @return zk cluster started. 092 */ 093 public MiniZooKeeperCluster startMiniZKCluster() throws Exception { 094 return startMiniZKCluster(1); 095 } 096 097 /** 098 * Call this if you only want a zk cluster. 099 * @see #shutdownMiniZKCluster() 100 * @return zk cluster started. 101 */ 102 public MiniZooKeeperCluster startMiniZKCluster(int zooKeeperServerNum, int... clientPortList) 103 throws Exception { 104 setupClusterTestDir(); 105 return startMiniZKCluster(clusterTestDir, zooKeeperServerNum, clientPortList); 106 } 107 108 /** 109 * Start a mini ZK cluster. If the property "test.hbase.zookeeper.property.clientPort" is set the 110 * port mentioned is used as the default port for ZooKeeper. 111 */ 112 private MiniZooKeeperCluster startMiniZKCluster(File dir, int zooKeeperServerNum, 113 int[] clientPortList) throws Exception { 114 if (this.zkCluster != null) { 115 throw new IOException("Cluster already running at " + dir); 116 } 117 this.passedZkCluster = false; 118 this.zkCluster = new MiniZooKeeperCluster(this.getConfiguration()); 119 int defPort = this.conf.getInt("test.hbase.zookeeper.property.clientPort", 0); 120 if (defPort > 0) { 121 // If there is a port in the config file, we use it. 122 this.zkCluster.setDefaultClientPort(defPort); 123 } 124 125 if (clientPortList != null) { 126 // Ignore extra client ports 127 int clientPortListSize = Math.min(clientPortList.length, zooKeeperServerNum); 128 for (int i = 0; i < clientPortListSize; i++) { 129 this.zkCluster.addClientPort(clientPortList[i]); 130 } 131 } 132 int clientPort = this.zkCluster.startup(dir, zooKeeperServerNum); 133 this.conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, Integer.toString(clientPort)); 134 return this.zkCluster; 135 } 136 137 public MiniZooKeeperCluster getZkCluster() { 138 return zkCluster; 139 } 140 141 public void setZkCluster(MiniZooKeeperCluster zkCluster) { 142 this.passedZkCluster = true; 143 this.zkCluster = zkCluster; 144 conf.setInt(HConstants.ZOOKEEPER_CLIENT_PORT, zkCluster.getClientPort()); 145 } 146 147 /** 148 * Shuts down zk cluster created by call to {@link #startMiniZKCluster()} or does nothing. 149 * @see #startMiniZKCluster() 150 */ 151 public void shutdownMiniZKCluster() throws IOException { 152 if (!passedZkCluster && this.zkCluster != null) { 153 this.zkCluster.shutdown(); 154 this.zkCluster = null; 155 } 156 } 157 158 /** 159 * Returns a ZKWatcher instance. This instance is shared between HBaseTestingUtility instance 160 * users. Don't close it, it will be closed automatically when the cluster shutdowns 161 * @return The ZKWatcher instance. 162 */ 163 public synchronized ZKWatcher getZooKeeperWatcher() throws IOException { 164 if (zooKeeperWatcher == null) { 165 zooKeeperWatcher = new ZKWatcher(conf, "testing utility", new Abortable() { 166 @Override 167 public void abort(String why, Throwable e) { 168 throw new RuntimeException("Unexpected abort in HBaseZKTestingUtility:" + why, e); 169 } 170 171 @Override 172 public boolean isAborted() { 173 return false; 174 } 175 }); 176 } 177 return zooKeeperWatcher; 178 } 179 180 /** 181 * Gets a ZKWatcher. 182 */ 183 public static ZKWatcher getZooKeeperWatcher(HBaseZKTestingUtility testUtil) throws IOException { 184 return new ZKWatcher(testUtil.getConfiguration(), "unittest", new Abortable() { 185 boolean aborted = false; 186 187 @Override 188 public void abort(String why, Throwable e) { 189 aborted = true; 190 throw new RuntimeException("Fatal ZK error, why=" + why, e); 191 } 192 193 @Override 194 public boolean isAborted() { 195 return aborted; 196 } 197 }); 198 } 199 200 /** Returns True if we removed the test dirs */ 201 @Override 202 public boolean cleanupTestDir() { 203 boolean ret = super.cleanupTestDir(); 204 if (deleteDir(this.clusterTestDir)) { 205 this.clusterTestDir = null; 206 return ret; 207 } 208 return false; 209 } 210}