private void createColumnFamily(HColumnDescriptor family, TableName table) throws IOException { try { admin.addColumn(table, family); } catch (InvalidFamilyOperationException e) { if (!hasFamily(family, table)) { //Schroedinger's cat: InvalidFamilyOperationException (cf exists) but does not exist at the same time throw new IllegalStateException("Column family should exist but does not", e); } //columnFamily was created in the meantime return; } waitForColumnFamilyCreation(family, table); log.info("Created column family '{}' in HBase table '{}'", family.getNameAsString(), table.getNameAsString()); }
/** * Modify Column of a table * @param tableName * @param hcd HColumnDesciptor * @return Modified HTableDescriptor with the column modified. * @throws IOException */ public HTableDescriptor modifyColumn(TableName tableName, HColumnDescriptor hcd) throws IOException { LOG.info("AddModifyColumn. Table = " + tableName + " HCD = " + hcd.toString()); HTableDescriptor htd = this.services.getTableDescriptors().get(tableName); byte [] familyName = hcd.getName(); if(!htd.hasFamily(familyName)) { throw new InvalidFamilyOperationException("Family '" + Bytes.toString(familyName) + "' doesn't exists so cannot be modified"); } htd.modifyFamily(hcd); this.services.getTableDescriptors().add(htd); return htd; }
/** * Action before any real action of deleting column family. * @param env MasterProcedureEnv * @throws IOException */ private void prepareDelete(final MasterProcedureEnv env) throws IOException { // Checks whether the table is allowed to be modified. MasterDDLOperationHelper.checkTableModifiable(env, tableName); // In order to update the descriptor, we need to retrieve the old descriptor for comparison. unmodifiedHTableDescriptor = env.getMasterServices().getTableDescriptors().get(tableName); if (unmodifiedHTableDescriptor == null) { throw new IOException("HTableDescriptor missing for " + tableName); } if (!unmodifiedHTableDescriptor.hasFamily(familyName)) { throw new InvalidFamilyOperationException("Family '" + getColumnFamilyName() + "' does not exist, so it cannot be deleted"); } if (unmodifiedHTableDescriptor.getColumnFamilies().length == 1) { throw new InvalidFamilyOperationException("Family '" + getColumnFamilyName() + "' is the only column family in the table, so it cannot be deleted"); } }
@Test(timeout=60000) public void testDeleteNonExistingColumnFamily() throws Exception { final TableName tableName = TableName.valueOf("testDeleteNonExistingColumnFamily"); final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor(); final String cf3 = "cf3"; MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1", "f2"); // delete the column family that does not exist long procId1 = procExec.submitProcedure( new DeleteColumnFamilyProcedure(procExec.getEnvironment(), tableName, cf3.getBytes()), nonceGroup, nonce); // Wait the completion ProcedureTestingUtility.waitProcedure(procExec, procId1); ProcedureInfo result = procExec.getResult(procId1); assertTrue(result.isFailed()); LOG.debug("Delete failed with exception: " + result.getExceptionFullMessage()); assertTrue( ProcedureTestingUtility.getExceptionCause(result) instanceof InvalidFamilyOperationException); }
/** * Modify Column of a table * @param tableName * @param hcd HColumnDesciptor * @return Modified HTableDescriptor with the column modified. * @throws IOException */ public HTableDescriptor modifyColumn(byte[] tableName, HColumnDescriptor hcd) throws IOException { LOG.info("AddModifyColumn. Table = " + Bytes.toString(tableName) + " HCD = " + hcd.toString()); HTableDescriptor htd = this.services.getTableDescriptors().get(tableName); byte [] familyName = hcd.getName(); if(!htd.hasFamily(familyName)) { throw new InvalidFamilyOperationException("Family '" + Bytes.toString(familyName) + "' doesn't exists so cannot be modified"); } htd.addFamily(hcd); this.services.getTableDescriptors().add(htd); return htd; }
/** * Modify Column of a table * @param tableName * @param hcd HColumnDesciptor * @return Modified HTableDescriptor with the column modified. * @throws IOException */ public HTableDescriptor modifyColumn(TableName tableName, HColumnDescriptor hcd) throws IOException { LOG.info("AddModifyColumn. Table = " + tableName + " HCD = " + hcd.toString()); HTableDescriptor htd = this.services.getTableDescriptors().get(tableName); byte [] familyName = hcd.getName(); if(!htd.hasFamily(familyName)) { throw new InvalidFamilyOperationException("Family '" + Bytes.toString(familyName) + "' doesn't exists so cannot be modified"); } htd.addFamily(hcd); this.services.getTableDescriptors().add(htd); return htd; }
@Override public long addColumn( final TableName tableName, final ColumnFamilyDescriptor column, final long nonceGroup, final long nonce) throws IOException { checkInitialized(); checkTableExists(tableName); TableDescriptor old = getTableDescriptors().get(tableName); if (old.hasColumnFamily(column.getName())) { throw new InvalidFamilyOperationException("Column family '" + column.getNameAsString() + "' in table '" + tableName + "' already exists so cannot be added"); } TableDescriptor newDesc = TableDescriptorBuilder .newBuilder(old).addColumnFamily(column).build(); return modifyTable(tableName, newDesc, nonceGroup, nonce); }
@Override public long modifyColumn( final TableName tableName, final ColumnFamilyDescriptor descriptor, final long nonceGroup, final long nonce) throws IOException { checkInitialized(); checkTableExists(tableName); TableDescriptor old = getTableDescriptors().get(tableName); if (! old.hasColumnFamily(descriptor.getName())) { throw new InvalidFamilyOperationException("Family '" + descriptor.getNameAsString() + "' does not exist, so it cannot be modified"); } TableDescriptor td = TableDescriptorBuilder .newBuilder(old) .modifyColumnFamily(descriptor) .build(); return modifyTable(tableName, td, nonceGroup, nonce); }
@Override public long deleteColumn( final TableName tableName, final byte[] columnName, final long nonceGroup, final long nonce) throws IOException { checkInitialized(); checkTableExists(tableName); TableDescriptor old = getTableDescriptors().get(tableName); if (! old.hasColumnFamily(columnName)) { throw new InvalidFamilyOperationException("Family '" + Bytes.toString(columnName) + "' does not exist, so it cannot be deleted"); } if (old.getColumnFamilyCount() == 1) { throw new InvalidFamilyOperationException("Family '" + Bytes.toString(columnName) + "' is the only column family in the table, so it cannot be deleted"); } TableDescriptor td = TableDescriptorBuilder .newBuilder(old).removeColumnFamily(columnName).build(); return modifyTable(tableName, td, nonceGroup, nonce); }
/** * Add column to a table * @param tableName * @param hcd * @return Modified HTableDescriptor with new column added. * @throws IOException */ public HTableDescriptor addColumn(TableName tableName, HColumnDescriptor hcd) throws IOException { LOG.info("AddColumn. Table = " + tableName + " HCD = " + hcd.toString()); HTableDescriptor htd = this.services.getTableDescriptors().get(tableName); if (htd == null) { throw new InvalidFamilyOperationException("Family '" + hcd.getNameAsString() + "' cannot be modified as HTD is null"); } htd.addFamily(hcd); this.services.getTableDescriptors().add(htd); return htd; }
byte [] hasColumnFamily(final HTableDescriptor htd, final byte [] cf) throws InvalidFamilyOperationException { if (!htd.hasFamily(cf)) { throw new InvalidFamilyOperationException("Column family '" + Bytes.toString(cf) + "' does not exist"); } return cf; }
/** * Action before any real action of modifying column family. * @param env MasterProcedureEnv * @throws IOException */ private void prepareModify(final MasterProcedureEnv env) throws IOException { // Checks whether the table is allowed to be modified. MasterDDLOperationHelper.checkTableModifiable(env, tableName); unmodifiedHTableDescriptor = env.getMasterServices().getTableDescriptors().get(tableName); if (unmodifiedHTableDescriptor == null) { throw new IOException("HTableDescriptor missing for " + tableName); } if (!unmodifiedHTableDescriptor.hasFamily(cfDescriptor.getName())) { throw new InvalidFamilyOperationException("Family '" + getColumnFamilyName() + "' does not exist, so it cannot be modified"); } }
/** * Action before any real action of adding column family. * @param env MasterProcedureEnv * @throws IOException */ private void prepareAdd(final MasterProcedureEnv env) throws IOException { // Checks whether the table is allowed to be modified. MasterDDLOperationHelper.checkTableModifiable(env, tableName); // In order to update the descriptor, we need to retrieve the old descriptor for comparison. unmodifiedHTableDescriptor = env.getMasterServices().getTableDescriptors().get(tableName); if (unmodifiedHTableDescriptor == null) { throw new IOException("HTableDescriptor missing for " + tableName); } if (unmodifiedHTableDescriptor.hasFamily(cfDescriptor.getName())) { throw new InvalidFamilyOperationException("Column family '" + getColumnFamilyName() + "' in table '" + tableName + "' already exists so cannot be added"); } }
@Test public void testAddSameColumnFamilyTwice() throws IOException { Admin admin = TEST_UTIL.getHBaseAdmin(); // Create a table with one families HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); admin.createTable(baseHtd); admin.disableTable(TABLE_NAME); try { // Verify the table descriptor verifyTableDescriptor(TABLE_NAME, FAMILY_0); // Modify the table removing one family and verify the descriptor admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); try { // Add same column family again - expect failure admin.addColumn(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); Assert.fail("Delete a non-exist column family should fail"); } catch (InvalidFamilyOperationException e) { // Expected. } } finally { admin.deleteTable(TABLE_NAME); } }
@Test public void testModifyNonExistingColumnFamily() throws IOException { Admin admin = TEST_UTIL.getHBaseAdmin(); HColumnDescriptor cfDescriptor = new HColumnDescriptor(FAMILY_1); int blockSize = cfDescriptor.getBlocksize(); // Create a table with one families HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); admin.createTable(baseHtd); admin.disableTable(TABLE_NAME); try { // Verify the table descriptor verifyTableDescriptor(TABLE_NAME, FAMILY_0); int newBlockSize = 2 * blockSize; cfDescriptor.setBlocksize(newBlockSize); // Modify a column family that is not in the table. try { admin.modifyColumn(TABLE_NAME, cfDescriptor); Assert.fail("Modify a non-exist column family should fail"); } catch (InvalidFamilyOperationException e) { // Expected. } } finally { admin.deleteTable(TABLE_NAME); } }
@Test(timeout=60000) public void testModifyNonExistingColumnFamily() throws Exception { final TableName tableName = TableName.valueOf("testModifyExistingColumnFamily"); final String cf2 = "cf2"; final HColumnDescriptor columnDescriptor = new HColumnDescriptor(cf2); int oldBlockSize = columnDescriptor.getBlocksize(); int newBlockSize = 2 * oldBlockSize; final ProcedureExecutor<MasterProcedureEnv> procExec = getMasterProcedureExecutor(); MasterProcedureTestingUtility.createTable(procExec, tableName, null, "f1"); // Modify the column family that does not exist columnDescriptor.setBlocksize(newBlockSize); long procId1 = procExec.submitProcedure( new ModifyColumnFamilyProcedure(procExec.getEnvironment(), tableName, columnDescriptor), nonceGroup, nonce); // Wait the completion ProcedureTestingUtility.waitProcedure(procExec, procId1); ProcedureInfo result = procExec.getResult(procId1); assertTrue(result.isFailed()); LOG.debug("Modify failed with exception: " + result.getExceptionFullMessage()); assertTrue( ProcedureTestingUtility.getExceptionCause(result) instanceof InvalidFamilyOperationException); }
/** * Add column to a table * @param tableName * @param hcd * @return Modified HTableDescriptor with new column added. * @throws IOException */ public HTableDescriptor addColumn(byte[] tableName, HColumnDescriptor hcd) throws IOException { LOG.info("AddColumn. Table = " + Bytes.toString(tableName) + " HCD = " + hcd.toString()); HTableDescriptor htd = this.services.getTableDescriptors().get(tableName); if (htd == null) { throw new InvalidFamilyOperationException("Family '" + hcd.getNameAsString() + "' cannot be modified as HTD is null"); } htd.addFamily(hcd); this.services.getTableDescriptors().add(htd); return htd; }
public TableAddFamilyHandler(byte[] tableName, HColumnDescriptor familyDesc, Server server, final MasterServices masterServices) throws IOException { super(EventType.C_M_ADD_FAMILY, tableName, server, masterServices); HTableDescriptor htd = getTableDescriptor(); if (htd.hasFamily(familyDesc.getName())) { throw new InvalidFamilyOperationException("Family '" + familyDesc.getNameAsString() + "' already exists so cannot be added"); } this.familyDesc = familyDesc; }
@Override protected void prepareWithTableLock() throws IOException { super.prepareWithTableLock(); HTableDescriptor htd = getTableDescriptor(); if (htd.hasFamily(familyDesc.getName())) { throw new InvalidFamilyOperationException("Family '" + familyDesc.getNameAsString() + "' already exists so cannot be added"); } }
@Test public void testAddSameColumnFamilyTwice() throws IOException { Admin admin = TEST_UTIL.getAdmin(); // Create a table with one families HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); admin.createTable(baseHtd); admin.disableTable(TABLE_NAME); try { // Verify the table descriptor verifyTableDescriptor(TABLE_NAME, FAMILY_0); // Modify the table removing one family and verify the descriptor admin.addColumnFamily(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); verifyTableDescriptor(TABLE_NAME, FAMILY_0, FAMILY_1); try { // Add same column family again - expect failure admin.addColumnFamily(TABLE_NAME, new HColumnDescriptor(FAMILY_1)); Assert.fail("Delete a non-exist column family should fail"); } catch (InvalidFamilyOperationException e) { // Expected. } } finally { admin.deleteTable(TABLE_NAME); } }
@Test public void testModifyNonExistingColumnFamily() throws IOException { Admin admin = TEST_UTIL.getAdmin(); HColumnDescriptor cfDescriptor = new HColumnDescriptor(FAMILY_1); int blockSize = cfDescriptor.getBlocksize(); // Create a table with one families HTableDescriptor baseHtd = new HTableDescriptor(TABLE_NAME); baseHtd.addFamily(new HColumnDescriptor(FAMILY_0)); admin.createTable(baseHtd); admin.disableTable(TABLE_NAME); try { // Verify the table descriptor verifyTableDescriptor(TABLE_NAME, FAMILY_0); int newBlockSize = 2 * blockSize; cfDescriptor.setBlocksize(newBlockSize); // Modify a column family that is not in the table. try { admin.modifyColumnFamily(TABLE_NAME, cfDescriptor); Assert.fail("Modify a non-exist column family should fail"); } catch (InvalidFamilyOperationException e) { // Expected. } } finally { admin.deleteTable(TABLE_NAME); } }