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