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.IOException; 021import org.apache.hadoop.conf.Configuration; 022import org.apache.hadoop.hbase.client.TestMetaWithReplicasShutdownHandling; 023import org.apache.hadoop.hbase.protobuf.ProtobufUtil; 024import org.apache.hadoop.hbase.regionserver.StorefileRefresherChore; 025import org.apache.hadoop.hbase.testclassification.IntegrationTests; 026import org.apache.hadoop.hbase.zookeeper.ZKUtil; 027import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 028import org.apache.hadoop.hbase.zookeeper.ZNodePaths; 029import org.junit.AfterClass; 030import org.junit.BeforeClass; 031import org.junit.Test; 032import org.junit.experimental.categories.Category; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036/** 037 * An integration test that starts the cluster with three replicas for the meta It then creates a 038 * table, flushes the meta, kills the server holding the primary. After that a client issues put/get 039 * requests on the created table - the other replicas of the meta would be used to get the location 040 * of the region of the created table. 041 */ 042@Category(IntegrationTests.class) 043public class IntegrationTestMetaReplicas { 044 private static final Logger LOG = LoggerFactory.getLogger(IntegrationTestMetaReplicas.class); 045 /** 046 * Util to get at the cluster. 047 */ 048 private static IntegrationTestingUtility util; 049 050 @BeforeClass 051 public static void setUp() throws Exception { 052 // Set up the integration test util 053 if (util == null) { 054 util = new IntegrationTestingUtility(); 055 } 056 util.getConfiguration().setInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD, 057 1000); 058 // Make sure there are three servers. 059 util.initializeCluster(3); 060 HBaseTestingUtility.setReplicas(util.getAdmin(), TableName.META_TABLE_NAME, 3); 061 ZKWatcher zkw = util.getZooKeeperWatcher(); 062 Configuration conf = util.getConfiguration(); 063 String baseZNode = 064 conf.get(HConstants.ZOOKEEPER_ZNODE_PARENT, HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT); 065 String primaryMetaZnode = 066 ZNodePaths.joinZNode(baseZNode, conf.get("zookeeper.znode.metaserver", "meta-region-server")); 067 // check that the data in the znode is parseable (this would also mean the znode exists) 068 byte[] data = ZKUtil.getData(zkw, primaryMetaZnode); 069 ProtobufUtil.toServerName(data); 070 waitUntilZnodeAvailable(1); 071 waitUntilZnodeAvailable(2); 072 } 073 074 @AfterClass 075 public static void teardown() throws Exception { 076 // Clean everything up. 077 util.restoreCluster(); 078 util = null; 079 } 080 081 private static void waitUntilZnodeAvailable(int replicaId) throws Exception { 082 String znode = util.getZooKeeperWatcher().getZNodePaths().getZNodeForReplica(replicaId); 083 int i = 0; 084 while (i < 1000) { 085 if (ZKUtil.checkExists(util.getZooKeeperWatcher(), znode) == -1) { 086 Thread.sleep(100); 087 i++; 088 } else break; 089 } 090 if (i == 1000) throw new IOException("znode for meta replica " + replicaId + " not available"); 091 } 092 093 @Test 094 public void testShutdownHandling() throws Exception { 095 // This test creates a table, flushes the meta (with 3 replicas), kills the 096 // server holding the primary meta replica. Then it does a put/get into/from 097 // the test table. The put/get operations would use the replicas to locate the 098 // location of the test table's region 099 TestMetaWithReplicasShutdownHandling.shutdownMetaAndDoValidations(util); 100 } 101 102 public static void main(String[] args) throws Exception { 103 setUp(); 104 new IntegrationTestMetaReplicas().testShutdownHandling(); 105 teardown(); 106 } 107}