2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.client
;
20 import static org
.junit
.Assert
.assertEquals
;
21 import static org
.junit
.Assert
.assertFalse
;
22 import static org
.junit
.Assert
.assertTrue
;
23 import static org
.junit
.Assert
.fail
;
25 import java
.io
.IOException
;
26 import java
.util
.List
;
27 import java
.util
.regex
.Pattern
;
28 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
29 import org
.apache
.hadoop
.hbase
.HConstants
;
30 import org
.apache
.hadoop
.hbase
.HRegionLocation
;
31 import org
.apache
.hadoop
.hbase
.InvalidFamilyOperationException
;
32 import org
.apache
.hadoop
.hbase
.MetaTableAccessor
;
33 import org
.apache
.hadoop
.hbase
.TableName
;
34 import org
.apache
.hadoop
.hbase
.TableNotDisabledException
;
35 import org
.apache
.hadoop
.hbase
.TableNotEnabledException
;
36 import org
.apache
.hadoop
.hbase
.TableNotFoundException
;
37 import org
.apache
.hadoop
.hbase
.testclassification
.ClientTests
;
38 import org
.apache
.hadoop
.hbase
.testclassification
.LargeTests
;
39 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
40 import org
.junit
.ClassRule
;
41 import org
.junit
.Test
;
42 import org
.junit
.experimental
.categories
.Category
;
43 import org
.slf4j
.Logger
;
44 import org
.slf4j
.LoggerFactory
;
46 @Category({ LargeTests
.class, ClientTests
.class })
47 public class TestAdmin3
extends TestAdminBase
{
50 public static final HBaseClassTestRule CLASS_RULE
= HBaseClassTestRule
.forClass(TestAdmin3
.class);
52 private static final Logger LOG
= LoggerFactory
.getLogger(TestAdmin3
.class);
55 public void testDisableAndEnableTable() throws IOException
{
56 final byte[] row
= Bytes
.toBytes("row");
57 final byte[] qualifier
= Bytes
.toBytes("qualifier");
58 final byte[] value
= Bytes
.toBytes("value");
59 final TableName table
= TableName
.valueOf(name
.getMethodName());
60 Table ht
= TEST_UTIL
.createTable(table
, HConstants
.CATALOG_FAMILY
);
61 Put put
= new Put(row
);
62 put
.addColumn(HConstants
.CATALOG_FAMILY
, qualifier
, value
);
64 Get get
= new Get(row
);
65 get
.addColumn(HConstants
.CATALOG_FAMILY
, qualifier
);
68 ADMIN
.disableTable(ht
.getName());
69 assertTrue("Table must be disabled.", TEST_UTIL
.getHBaseCluster().getMaster()
70 .getTableStateManager().isTableState(ht
.getName(), TableState
.State
.DISABLED
));
71 assertEquals(TableState
.State
.DISABLED
, getStateFromMeta(table
));
73 // Test that table is disabled
75 get
.addColumn(HConstants
.CATALOG_FAMILY
, qualifier
);
79 } catch (TableNotEnabledException e
) {
83 // verify that scan encounters correct exception
84 Scan scan
= new Scan();
86 ResultScanner scanner
= ht
.getScanner(scan
);
90 } while (res
!= null);
91 } catch (TableNotEnabledException e
) {
95 ADMIN
.enableTable(table
);
96 assertTrue("Table must be enabled.", TEST_UTIL
.getHBaseCluster().getMaster()
97 .getTableStateManager().isTableState(ht
.getName(), TableState
.State
.ENABLED
));
98 assertEquals(TableState
.State
.ENABLED
, getStateFromMeta(table
));
100 // Test that table is enabled
103 } catch (RetriesExhaustedException e
) {
111 public void testDisableAndEnableTables() throws IOException
{
112 final byte[] row
= Bytes
.toBytes("row");
113 final byte[] qualifier
= Bytes
.toBytes("qualifier");
114 final byte[] value
= Bytes
.toBytes("value");
115 final TableName table1
= TableName
.valueOf(name
.getMethodName() + "1");
116 final TableName table2
= TableName
.valueOf(name
.getMethodName() + "2");
117 Table ht1
= TEST_UTIL
.createTable(table1
, HConstants
.CATALOG_FAMILY
);
118 Table ht2
= TEST_UTIL
.createTable(table2
, HConstants
.CATALOG_FAMILY
);
119 Put put
= new Put(row
);
120 put
.addColumn(HConstants
.CATALOG_FAMILY
, qualifier
, value
);
123 Get get
= new Get(row
);
124 get
.addColumn(HConstants
.CATALOG_FAMILY
, qualifier
);
128 TableName
[] tableNames
= ADMIN
.listTableNames(Pattern
.compile("testDisableAndEnableTable.*"));
129 for (TableName tableName
: tableNames
) {
130 ADMIN
.disableTable(tableName
);
133 // Test that tables are disabled
135 get
.addColumn(HConstants
.CATALOG_FAMILY
, qualifier
);
140 } catch (org
.apache
.hadoop
.hbase
.DoNotRetryIOException e
) {
144 assertEquals(TableState
.State
.DISABLED
, getStateFromMeta(table1
));
145 assertEquals(TableState
.State
.DISABLED
, getStateFromMeta(table2
));
148 for (TableName tableName
: tableNames
) {
149 ADMIN
.enableTable(tableName
);
152 // Test that tables are enabled
155 } catch (IOException e
) {
160 } catch (IOException e
) {
168 assertEquals(TableState
.State
.ENABLED
, getStateFromMeta(table1
));
169 assertEquals(TableState
.State
.ENABLED
, getStateFromMeta(table2
));
173 * Test retain assignment on enableTable.
176 public void testEnableTableRetainAssignment() throws IOException
{
177 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
178 byte[][] splitKeys
= { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 },
179 new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 },
180 new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 }, new byte[] { 9, 9, 9 } };
181 int expectedRegions
= splitKeys
.length
+ 1;
182 TableDescriptor desc
= TableDescriptorBuilder
.newBuilder(tableName
)
183 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of(HConstants
.CATALOG_FAMILY
)).build();
184 ADMIN
.createTable(desc
, splitKeys
);
186 try (RegionLocator l
= TEST_UTIL
.getConnection().getRegionLocator(tableName
)) {
187 List
<HRegionLocation
> regions
= l
.getAllRegionLocations();
190 "Tried to create " + expectedRegions
+ " regions " + "but only found " + regions
.size(),
191 expectedRegions
, regions
.size());
193 ADMIN
.disableTable(tableName
);
194 // Enable table, use retain assignment to assign regions.
195 ADMIN
.enableTable(tableName
);
196 List
<HRegionLocation
> regions2
= l
.getAllRegionLocations();
198 // Check the assignment.
199 assertEquals(regions
.size(), regions2
.size());
200 assertTrue(regions2
.containsAll(regions
));
205 public void testEnableDisableAddColumnDeleteColumn() throws Exception
{
206 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
207 TEST_UTIL
.createTable(tableName
, HConstants
.CATALOG_FAMILY
).close();
208 while (!ADMIN
.isTableEnabled(TableName
.valueOf(name
.getMethodName()))) {
211 ADMIN
.disableTable(tableName
);
213 TEST_UTIL
.getConnection().getTable(tableName
);
214 } catch (org
.apache
.hadoop
.hbase
.DoNotRetryIOException e
) {
218 ADMIN
.addColumnFamily(tableName
, ColumnFamilyDescriptorBuilder
.of("col2"));
219 ADMIN
.enableTable(tableName
);
221 ADMIN
.deleteColumnFamily(tableName
, Bytes
.toBytes("col2"));
222 } catch (TableNotDisabledException e
) {
223 LOG
.info(e
.toString(), e
);
225 ADMIN
.disableTable(tableName
);
226 ADMIN
.deleteTable(tableName
);
230 public void testGetTableDescriptor() throws IOException
{
231 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(TableName
.valueOf(name
.getMethodName()))
232 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("fam1"))
233 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("fam2"))
234 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("fam3")).build();
235 ADMIN
.createTable(htd
);
236 Table table
= TEST_UTIL
.getConnection().getTable(htd
.getTableName());
237 TableDescriptor confirmedHtd
= table
.getDescriptor();
238 assertEquals(0, TableDescriptor
.COMPARATOR
.compare(htd
, confirmedHtd
));
239 MetaTableAccessor
.fullScanMetaAndPrint(TEST_UTIL
.getConnection());
244 * Verify schema change for read only table
247 public void testReadOnlyTableModify() throws IOException
, InterruptedException
{
248 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
249 TEST_UTIL
.createTable(tableName
, HConstants
.CATALOG_FAMILY
).close();
251 // Make table read only
252 TableDescriptor htd
=
253 TableDescriptorBuilder
.newBuilder(ADMIN
.getDescriptor(tableName
)).setReadOnly(true).build();
254 ADMIN
.modifyTable(htd
);
256 // try to modify the read only table now
257 htd
= TableDescriptorBuilder
.newBuilder(ADMIN
.getDescriptor(tableName
))
258 .setCompactionEnabled(false).build();
259 ADMIN
.modifyTable(htd
);
261 ADMIN
.disableTable(tableName
);
262 ADMIN
.deleteTable(tableName
);
263 assertFalse(ADMIN
.tableExists(tableName
));
266 @Test(expected
= TableNotDisabledException
.class)
267 public void testModifyRegionReplicasEnabledTable() throws Exception
{
268 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
269 TEST_UTIL
.createTable(tableName
, HConstants
.CATALOG_FAMILY
).close();
271 // Modify region replication count
272 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(ADMIN
.getDescriptor(tableName
))
273 .setRegionReplication(3).build();
275 // try to modify the region replication count without disabling the table
276 ADMIN
.modifyTable(htd
);
277 fail("Expected an exception");
280 ADMIN
.disableTable(tableName
);
281 ADMIN
.deleteTable(tableName
);
282 assertFalse(ADMIN
.tableExists(tableName
));
287 public void testDeleteLastColumnFamily() throws Exception
{
288 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
289 TEST_UTIL
.createTable(tableName
, HConstants
.CATALOG_FAMILY
).close();
290 while (!ADMIN
.isTableEnabled(TableName
.valueOf(name
.getMethodName()))) {
294 // test for enabled table
296 ADMIN
.deleteColumnFamily(tableName
, HConstants
.CATALOG_FAMILY
);
297 fail("Should have failed to delete the only column family of a table");
298 } catch (InvalidFamilyOperationException ex
) {
302 // test for disabled table
303 ADMIN
.disableTable(tableName
);
306 ADMIN
.deleteColumnFamily(tableName
, HConstants
.CATALOG_FAMILY
);
307 fail("Should have failed to delete the only column family of a table");
308 } catch (InvalidFamilyOperationException ex
) {
312 ADMIN
.deleteTable(tableName
);
316 public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException
{
317 // Test we get exception if we try to
318 final TableName nonexistentTable
= TableName
.valueOf("nonexistent");
319 final byte[] nonexistentColumn
= Bytes
.toBytes("nonexistent");
320 ColumnFamilyDescriptor nonexistentHcd
= ColumnFamilyDescriptorBuilder
.of(nonexistentColumn
);
321 Exception exception
= null;
323 ADMIN
.addColumnFamily(nonexistentTable
, nonexistentHcd
);
324 } catch (IOException e
) {
327 assertTrue(exception
instanceof TableNotFoundException
);
331 ADMIN
.deleteTable(nonexistentTable
);
332 } catch (IOException e
) {
335 assertTrue(exception
instanceof TableNotFoundException
);
339 ADMIN
.deleteColumnFamily(nonexistentTable
, nonexistentColumn
);
340 } catch (IOException e
) {
343 assertTrue(exception
instanceof TableNotFoundException
);
347 ADMIN
.disableTable(nonexistentTable
);
348 } catch (IOException e
) {
351 assertTrue(exception
instanceof TableNotFoundException
);
355 ADMIN
.enableTable(nonexistentTable
);
356 } catch (IOException e
) {
359 assertTrue(exception
instanceof TableNotFoundException
);
363 ADMIN
.modifyColumnFamily(nonexistentTable
, nonexistentHcd
);
364 } catch (IOException e
) {
367 assertTrue(exception
instanceof TableNotFoundException
);
371 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(nonexistentTable
)
372 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of(HConstants
.CATALOG_FAMILY
)).build();
373 ADMIN
.modifyTable(htd
);
374 } catch (IOException e
) {
377 assertTrue(exception
instanceof TableNotFoundException
);
379 // Now make it so at least the table exists and then do tests against a
380 // nonexistent column family -- see if we get right exceptions.
381 final TableName tableName
=
382 TableName
.valueOf(name
.getMethodName() + System
.currentTimeMillis());
383 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(tableName
)
384 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("cf")).build();
385 ADMIN
.createTable(htd
);
389 ADMIN
.deleteColumnFamily(htd
.getTableName(), nonexistentHcd
.getName());
390 } catch (IOException e
) {
393 assertTrue("found=" + exception
.getClass().getName(),
394 exception
instanceof InvalidFamilyOperationException
);
398 ADMIN
.modifyColumnFamily(htd
.getTableName(), nonexistentHcd
);
399 } catch (IOException e
) {
402 assertTrue("found=" + exception
.getClass().getName(),
403 exception
instanceof InvalidFamilyOperationException
);
405 ADMIN
.disableTable(tableName
);
406 ADMIN
.deleteTable(tableName
);