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