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.TableName.META_TABLE_NAME; 021import static org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory.TRACKER_IMPL; 022import static org.hamcrest.CoreMatchers.instanceOf; 023import static org.hamcrest.MatcherAssert.assertThat; 024import static org.junit.Assert.assertEquals; 025import static org.junit.Assert.assertFalse; 026import static org.junit.Assert.assertTrue; 027import static org.junit.Assert.fail; 028 029import java.util.ArrayList; 030import java.util.Collections; 031import java.util.List; 032import java.util.concurrent.ExecutionException; 033import java.util.regex.Pattern; 034import org.apache.hadoop.hbase.ClientMetaTableAccessor; 035import org.apache.hadoop.hbase.DoNotRetryIOException; 036import org.apache.hadoop.hbase.HBaseClassTestRule; 037import org.apache.hadoop.hbase.HRegionLocation; 038import org.apache.hadoop.hbase.TableName; 039import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory; 040import org.apache.hadoop.hbase.testclassification.ClientTests; 041import org.apache.hadoop.hbase.testclassification.LargeTests; 042import org.apache.hadoop.hbase.util.Bytes; 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 table admin operations. 051 * @see TestAsyncTableAdminApi2 This test and it used to be joined it was taking longer than our ten 052 * minute timeout so they were split. 053 */ 054@RunWith(Parameterized.class) 055@Category({ LargeTests.class, ClientTests.class }) 056public class TestAsyncTableAdminApi3 extends TestAsyncAdminBase { 057 @ClassRule 058 public static final HBaseClassTestRule CLASS_RULE = 059 HBaseClassTestRule.forClass(TestAsyncTableAdminApi3.class); 060 061 @Test 062 public void testTableExist() throws Exception { 063 boolean exist; 064 exist = admin.tableExists(tableName).get(); 065 assertFalse(exist); 066 TEST_UTIL.createTable(tableName, FAMILY); 067 exist = admin.tableExists(tableName).get(); 068 assertTrue(exist); 069 exist = admin.tableExists(TableName.META_TABLE_NAME).get(); 070 assertTrue(exist); 071 // meta table already exists 072 exist = admin.tableExists(TableName.META_TABLE_NAME).get(); 073 assertTrue(exist); 074 } 075 076 @Test 077 public void testListTables() throws Exception { 078 int numTables = admin.listTableDescriptors().get().size(); 079 final TableName tableName1 = TableName.valueOf(tableName.getNameAsString() + "1"); 080 final TableName tableName2 = TableName.valueOf(tableName.getNameAsString() + "2"); 081 final TableName tableName3 = TableName.valueOf(tableName.getNameAsString() + "3"); 082 TableName[] tables = new TableName[] { tableName1, tableName2, tableName3 }; 083 for (int i = 0; i < tables.length; i++) { 084 createTableWithDefaultConf(tables[i]); 085 } 086 087 List<TableDescriptor> tableDescs = admin.listTableDescriptors().get(); 088 int size = tableDescs.size(); 089 assertTrue(size >= tables.length); 090 for (int i = 0; i < tables.length && i < size; i++) { 091 boolean found = false; 092 for (int j = 0; j < size; j++) { 093 if (tableDescs.get(j).getTableName().equals(tables[i])) { 094 found = true; 095 break; 096 } 097 } 098 assertTrue("Not found: " + tables[i], found); 099 } 100 101 List<TableName> tableNames = admin.listTableNames().get(); 102 size = tableNames.size(); 103 assertTrue(size == (numTables + tables.length)); 104 for (int i = 0; i < tables.length && i < size; i++) { 105 boolean found = false; 106 for (int j = 0; j < size; j++) { 107 if (tableNames.get(j).equals(tables[i])) { 108 found = true; 109 break; 110 } 111 } 112 assertTrue("Not found: " + tables[i], found); 113 } 114 115 tableNames = new ArrayList<TableName>(tables.length + 1); 116 tableDescs = admin.listTableDescriptors(tableNames).get(); 117 size = tableDescs.size(); 118 assertEquals(0, size); 119 120 Collections.addAll(tableNames, tables); 121 tableNames.add(TableName.META_TABLE_NAME); 122 tableDescs = admin.listTableDescriptors(tableNames).get(); 123 size = tableDescs.size(); 124 assertEquals(tables.length + 1, size); 125 for (int i = 0, j = 0; i < tables.length && j < size; i++, j++) { 126 assertTrue("tableName should be equal in order", 127 tableDescs.get(j).getTableName().equals(tables[i])); 128 } 129 assertTrue(tableDescs.get(size - 1).getTableName().equals(TableName.META_TABLE_NAME)); 130 131 for (int i = 0; i < tables.length; i++) { 132 admin.disableTable(tables[i]).join(); 133 admin.deleteTable(tables[i]).join(); 134 } 135 136 tableDescs = admin.listTableDescriptors(true).get(); 137 assertTrue("Not found system tables", tableDescs.size() > 0); 138 tableNames = admin.listTableNames(true).get(); 139 assertTrue("Not found system tables", tableNames.size() > 0); 140 } 141 142 @Test 143 public void testGetTableDescriptor() throws Exception { 144 byte[][] families = { FAMILY, FAMILY_0, FAMILY_1 }; 145 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName); 146 for (byte[] family : families) { 147 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family)); 148 } 149 TableDescriptor desc = builder.build(); 150 admin.createTable(desc).join(); 151 TableDescriptor confirmedHtd = admin.getDescriptor(tableName).get(); 152 // HBASE-26246 introduced persist of store file tracker into table descriptor 153 desc = TableDescriptorBuilder.newBuilder(desc).setValue(TRACKER_IMPL, 154 StoreFileTrackerFactory.getStoreFileTrackerName(TEST_UTIL.getConfiguration())).build(); 155 assertEquals(0, TableDescriptor.COMPARATOR.compare(desc, confirmedHtd)); 156 } 157 158 @Test 159 public void testDisableAndEnableTable() throws Exception { 160 createTableWithDefaultConf(tableName); 161 AsyncTable<?> table = ASYNC_CONN.getTable(tableName); 162 final byte[] row = Bytes.toBytes("row"); 163 final byte[] qualifier = Bytes.toBytes("qualifier"); 164 final byte[] value = Bytes.toBytes("value"); 165 Put put = new Put(row); 166 put.addColumn(FAMILY, qualifier, value); 167 table.put(put).join(); 168 Get get = new Get(row); 169 get.addColumn(FAMILY, qualifier); 170 table.get(get).get(); 171 172 this.admin.disableTable(tableName).join(); 173 assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster().getMaster() 174 .getTableStateManager().isTableState(tableName, TableState.State.DISABLED)); 175 assertEquals(TableState.State.DISABLED, TestAsyncTableAdminApi.getStateFromMeta(tableName)); 176 177 // Test that table is disabled 178 get = new Get(row); 179 get.addColumn(FAMILY, qualifier); 180 boolean ok = false; 181 try { 182 table.get(get).get(); 183 } catch (ExecutionException e) { 184 ok = true; 185 } 186 ok = false; 187 // verify that scan encounters correct exception 188 try { 189 table.scanAll(new Scan()).get(); 190 } catch (ExecutionException e) { 191 ok = true; 192 } 193 assertTrue(ok); 194 this.admin.enableTable(tableName).join(); 195 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster().getMaster() 196 .getTableStateManager().isTableState(tableName, TableState.State.ENABLED)); 197 assertEquals(TableState.State.ENABLED, TestAsyncTableAdminApi.getStateFromMeta(tableName)); 198 199 // Test that table is enabled 200 try { 201 table.get(get).get(); 202 } catch (Exception e) { 203 ok = false; 204 } 205 assertTrue(ok); 206 // meta table can not be disabled. 207 try { 208 admin.disableTable(TableName.META_TABLE_NAME).get(); 209 fail("meta table can not be disabled"); 210 } catch (ExecutionException e) { 211 Throwable cause = e.getCause(); 212 assertThat(cause, instanceOf(DoNotRetryIOException.class)); 213 } 214 } 215 216 @Test 217 public void testDisableAndEnableTables() throws Exception { 218 final TableName tableName1 = TableName.valueOf(tableName.getNameAsString() + "1"); 219 final TableName tableName2 = TableName.valueOf(tableName.getNameAsString() + "2"); 220 createTableWithDefaultConf(tableName1); 221 createTableWithDefaultConf(tableName2); 222 AsyncTable<?> table1 = ASYNC_CONN.getTable(tableName1); 223 AsyncTable<?> table2 = ASYNC_CONN.getTable(tableName1); 224 225 final byte[] row = Bytes.toBytes("row"); 226 final byte[] qualifier = Bytes.toBytes("qualifier"); 227 final byte[] value = Bytes.toBytes("value"); 228 Put put = new Put(row); 229 put.addColumn(FAMILY, qualifier, value); 230 table1.put(put).join(); 231 table2.put(put).join(); 232 Get get = new Get(row); 233 get.addColumn(FAMILY, qualifier); 234 table1.get(get).get(); 235 table2.get(get).get(); 236 237 admin.listTableNames(Pattern.compile(tableName.getNameAsString() + ".*"), false).get() 238 .forEach(t -> admin.disableTable(t).join()); 239 240 // Test that tables are disabled 241 get = new Get(row); 242 get.addColumn(FAMILY, qualifier); 243 boolean ok = false; 244 try { 245 table1.get(get).get(); 246 } catch (ExecutionException e) { 247 ok = true; 248 } 249 assertTrue(ok); 250 251 ok = false; 252 try { 253 table2.get(get).get(); 254 } catch (ExecutionException e) { 255 ok = true; 256 } 257 assertTrue(ok); 258 assertEquals(TableState.State.DISABLED, TestAsyncTableAdminApi.getStateFromMeta(tableName1)); 259 assertEquals(TableState.State.DISABLED, TestAsyncTableAdminApi.getStateFromMeta(tableName2)); 260 261 admin.listTableNames(Pattern.compile(tableName.getNameAsString() + ".*"), false).get() 262 .forEach(t -> admin.enableTable(t).join()); 263 264 // Test that tables are enabled 265 try { 266 table1.get(get).get(); 267 } catch (Exception e) { 268 ok = false; 269 } 270 try { 271 table2.get(get).get(); 272 } catch (Exception e) { 273 ok = false; 274 } 275 assertTrue(ok); 276 assertEquals(TableState.State.ENABLED, TestAsyncTableAdminApi.getStateFromMeta(tableName1)); 277 assertEquals(TableState.State.ENABLED, TestAsyncTableAdminApi.getStateFromMeta(tableName2)); 278 } 279 280 @Test 281 public void testEnableTableRetainAssignment() throws Exception { 282 byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 }, 283 new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 }, 284 new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 }, new byte[] { 9, 9, 9 } }; 285 int expectedRegions = splitKeys.length + 1; 286 createTableWithDefaultConf(tableName, splitKeys); 287 288 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME); 289 List<HRegionLocation> regions = 290 ClientMetaTableAccessor.getTableHRegionLocations(metaTable, tableName).get(); 291 assertEquals( 292 "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(), 293 expectedRegions, regions.size()); 294 295 // Disable table. 296 admin.disableTable(tableName).join(); 297 // Enable table, use retain assignment to assign regions. 298 admin.enableTable(tableName).join(); 299 300 List<HRegionLocation> regions2 = 301 ClientMetaTableAccessor.getTableHRegionLocations(metaTable, tableName).get(); 302 // Check the assignment. 303 assertEquals(regions.size(), regions2.size()); 304 assertTrue(regions2.containsAll(regions)); 305 } 306 307 @Test 308 public void testIsTableEnabledAndDisabled() throws Exception { 309 createTableWithDefaultConf(tableName); 310 assertTrue(admin.isTableEnabled(tableName).get()); 311 assertFalse(admin.isTableDisabled(tableName).get()); 312 admin.disableTable(tableName).join(); 313 assertFalse(admin.isTableEnabled(tableName).get()); 314 assertTrue(admin.isTableDisabled(tableName).get()); 315 316 // meta table is always enabled 317 assertTrue(admin.isTableEnabled(TableName.META_TABLE_NAME).get()); 318 assertFalse(admin.isTableDisabled(TableName.META_TABLE_NAME).get()); 319 } 320 321 @Test 322 public void testIsTableAvailable() throws Exception { 323 createTableWithDefaultConf(tableName); 324 TEST_UTIL.waitTableAvailable(tableName); 325 assertTrue(admin.isTableAvailable(tableName).get()); 326 assertTrue(admin.isTableAvailable(TableName.META_TABLE_NAME).get()); 327 } 328}