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.client; 019 020import static org.apache.hadoop.hbase.client.AsyncProcess.START_LOG_ERRORS_AFTER_COUNT_KEY; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertNull; 024import static org.junit.Assert.assertTrue; 025import static org.junit.Assert.fail; 026 027import java.util.concurrent.Callable; 028import org.apache.hadoop.hbase.HBaseClassTestRule; 029import org.apache.hadoop.hbase.HColumnDescriptor; 030import org.apache.hadoop.hbase.HConstants; 031import org.apache.hadoop.hbase.HTableDescriptor; 032import org.apache.hadoop.hbase.MiniHBaseCluster; 033import org.apache.hadoop.hbase.NamespaceDescriptor; 034import org.apache.hadoop.hbase.NamespaceExistException; 035import org.apache.hadoop.hbase.NamespaceNotFoundException; 036import org.apache.hadoop.hbase.TableName; 037import org.apache.hadoop.hbase.Waiter; 038import org.apache.hadoop.hbase.ZKNamespaceManager; 039import org.apache.hadoop.hbase.master.HMaster; 040import org.apache.hadoop.hbase.testclassification.ClientTests; 041import org.apache.hadoop.hbase.testclassification.LargeTests; 042import org.junit.BeforeClass; 043import org.junit.ClassRule; 044import org.junit.Test; 045import org.junit.experimental.categories.Category; 046import org.junit.runner.RunWith; 047import org.junit.runners.Parameterized; 048 049/** 050 * Class to test asynchronous namespace admin operations. 051 */ 052@RunWith(Parameterized.class) 053@Category({ LargeTests.class, ClientTests.class }) 054public class TestAsyncNamespaceAdminApi extends TestAsyncAdminBase { 055 056 @ClassRule 057 public static final HBaseClassTestRule CLASS_RULE = 058 HBaseClassTestRule.forClass(TestAsyncNamespaceAdminApi.class); 059 060 private String prefix = "TestNamespace"; 061 private static HMaster master; 062 private static ZKNamespaceManager zkNamespaceManager; 063 064 @BeforeClass 065 public static void setUpBeforeClass() throws Exception { 066 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 60000); 067 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, 120000); 068 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2); 069 TEST_UTIL.getConfiguration().setInt(START_LOG_ERRORS_AFTER_COUNT_KEY, 0); 070 TEST_UTIL.startMiniCluster(1); 071 ASYNC_CONN = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get(); 072 master = TEST_UTIL.getHBaseCluster().getMaster(); 073 zkNamespaceManager = new ZKNamespaceManager(master.getZooKeeper()); 074 zkNamespaceManager.start(); 075 LOG.info("Done initializing cluster"); 076 } 077 078 @Test 079 public void testCreateAndDelete() throws Exception { 080 String testName = "testCreateAndDelete"; 081 String nsName = prefix + "_" + testName; 082 083 // create namespace and verify 084 admin.createNamespace(NamespaceDescriptor.create(nsName).build()).join(); 085 assertEquals(3, admin.listNamespaceDescriptors().get().size()); 086 TEST_UTIL.waitFor(60000, new Waiter.Predicate<Exception>() { 087 @Override 088 public boolean evaluate() throws Exception { 089 return zkNamespaceManager.list().size() == 3; 090 } 091 }); 092 assertNotNull(zkNamespaceManager.get(nsName)); 093 // delete namespace and verify 094 admin.deleteNamespace(nsName).join(); 095 assertEquals(2, admin.listNamespaceDescriptors().get().size()); 096 assertEquals(2, zkNamespaceManager.list().size()); 097 assertNull(zkNamespaceManager.get(nsName)); 098 } 099 100 @Test 101 public void testDeleteReservedNS() throws Exception { 102 boolean exceptionCaught = false; 103 try { 104 admin.deleteNamespace(NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR).join(); 105 } catch (Exception exp) { 106 LOG.warn(exp.toString(), exp); 107 exceptionCaught = true; 108 } finally { 109 assertTrue(exceptionCaught); 110 } 111 112 try { 113 admin.deleteNamespace(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR).join(); 114 } catch (Exception exp) { 115 LOG.warn(exp.toString(), exp); 116 exceptionCaught = true; 117 } finally { 118 assertTrue(exceptionCaught); 119 } 120 } 121 122 @Test 123 public void testNamespaceOperations() throws Exception { 124 admin.createNamespace(NamespaceDescriptor.create(prefix + "ns1").build()).join(); 125 admin.createNamespace(NamespaceDescriptor.create(prefix + "ns2").build()).join(); 126 127 // create namespace that already exists 128 runWithExpectedException(new Callable<Void>() { 129 @Override 130 public Void call() throws Exception { 131 admin.createNamespace(NamespaceDescriptor.create(prefix + "ns1").build()).join(); 132 return null; 133 } 134 }, NamespaceExistException.class); 135 136 // create a table in non-existing namespace 137 runWithExpectedException(new Callable<Void>() { 138 @Override 139 public Void call() throws Exception { 140 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("non_existing_namespace", 141 "table1")); 142 htd.addFamily(new HColumnDescriptor("family1")); 143 admin.createTable(htd).join(); 144 return null; 145 } 146 }, NamespaceNotFoundException.class); 147 148 // get descriptor for existing namespace 149 NamespaceDescriptor ns1 = admin.getNamespaceDescriptor(prefix + "ns1").get(); 150 assertEquals(prefix + "ns1", ns1.getName()); 151 152 // get descriptor for non-existing namespace 153 runWithExpectedException(new Callable<NamespaceDescriptor>() { 154 @Override 155 public NamespaceDescriptor call() throws Exception { 156 return admin.getNamespaceDescriptor("non_existing_namespace").get(); 157 } 158 }, NamespaceNotFoundException.class); 159 160 // delete descriptor for existing namespace 161 admin.deleteNamespace(prefix + "ns2").join(); 162 163 // delete descriptor for non-existing namespace 164 runWithExpectedException(new Callable<Void>() { 165 @Override 166 public Void call() throws Exception { 167 admin.deleteNamespace("non_existing_namespace").join(); 168 return null; 169 } 170 }, NamespaceNotFoundException.class); 171 172 // modify namespace descriptor for existing namespace 173 ns1 = admin.getNamespaceDescriptor(prefix + "ns1").get(); 174 ns1.setConfiguration("foo", "bar"); 175 admin.modifyNamespace(ns1).join(); 176 ns1 = admin.getNamespaceDescriptor(prefix + "ns1").get(); 177 assertEquals("bar", ns1.getConfigurationValue("foo")); 178 179 // modify namespace descriptor for non-existing namespace 180 runWithExpectedException(new Callable<Void>() { 181 @Override 182 public Void call() throws Exception { 183 admin.modifyNamespace(NamespaceDescriptor.create("non_existing_namespace").build()).join(); 184 return null; 185 } 186 }, NamespaceNotFoundException.class); 187 188 admin.deleteNamespace(prefix + "ns1").join(); 189 } 190 191 private static <V, E> void runWithExpectedException(Callable<V> callable, Class<E> exceptionClass) { 192 try { 193 callable.call(); 194 } catch (Exception ex) { 195 LOG.info("Get exception is " + ex); 196 assertEquals(exceptionClass, ex.getCause().getClass()); 197 return; 198 } 199 fail("Should have thrown exception " + exceptionClass); 200 } 201}