下面列出了怎么用org.apache.hadoop.hbase.client.Delete的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
protected void deleteResourceImpl(String resPath, long timestamp) throws IOException {
Table table = getConnection().getTable(TableName.valueOf(tableName));
try {
boolean hdfsResourceExist = isHdfsResourceExist(table, resPath);
long origLastModified = getResourceLastModified(table, resPath);
if (checkTimeStampBeforeDelete(origLastModified, timestamp)) {
Delete del = new Delete(Bytes.toBytes(resPath));
table.delete(del);
if (hdfsResourceExist) { // remove hdfs cell value
deletePushdown(resPath);
}
} else {
throw new IOException("Resource " + resPath + " timestamp not match, [originLastModified: "
+ origLastModified + ", timestampToDelete: " + timestamp + "]");
}
} finally {
IOUtils.closeQuietly(table);
}
}
/**
* Writes an action (Put or Delete) to the specified table.
*
* @param tableName
* the table being updated.
* @param action
* the update, either a put or a delete.
* @throws IllegalArgumentException
* if the action is not a put or a delete.
*/
@Override
public void write(ImmutableBytesWritable tableName, Mutation action) throws IOException {
BufferedMutator mutator = getBufferedMutator(tableName);
// The actions are not immutable, so we defensively copy them
if (action instanceof Put) {
Put put = new Put((Put) action);
put.setDurability(useWriteAheadLogging ? Durability.SYNC_WAL
: Durability.SKIP_WAL);
mutator.mutate(put);
} else if (action instanceof Delete) {
Delete delete = new Delete((Delete) action);
mutator.mutate(delete);
} else
throw new IllegalArgumentException(
"action must be either Delete or Put");
}
private void verifyUserDeniedForDeleteMultipleVersions(final User user, final byte[] row,
final byte[] q1, final byte[] q2) throws IOException, InterruptedException {
user.runAs(new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(conf)) {
try (Table t = connection.getTable(testTable.getTableName())) {
Delete d = new Delete(row);
d.addColumns(TEST_FAMILY1, q1);
d.addColumns(TEST_FAMILY1, q2);
t.delete(d);
fail(user.getShortName() + " should not be allowed to delete the row");
} catch (Exception e) {
}
}
return null;
}
});
}
protected void wipeOutMeta() throws IOException {
// Mess it up by blowing up meta.
Admin admin = TEST_UTIL.getAdmin();
Scan s = new Scan();
Table meta = TEST_UTIL.getConnection().getTable(TableName.META_TABLE_NAME);
ResultScanner scanner = meta.getScanner(s);
List<Delete> dels = new ArrayList<>();
for (Result r : scanner) {
RegionInfo info =
CatalogFamilyFormat.getRegionInfo(r);
if(info != null && !info.getTable().getNamespaceAsString()
.equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR)) {
Delete d = new Delete(r.getRow());
dels.add(d);
admin.unassign(r.getRow(), true);
}
}
meta.delete(dels);
scanner.close();
meta.close();
}
/**
* Transactional version of {@link Table#batch(List<? extends Row> rows)}
*
* @param transaction an instance of transaction to be used
* @param rows List of rows that must be instances of Put or Delete
* @param addShadowCell denotes whether to add the shadow cell
* @throws IOException if a remote or network exception occurs
*/
public void batch(Transaction transaction, List<? extends Row> rows, boolean addShadowCells) throws IOException {
List<Mutation> mutations = new ArrayList<>(rows.size());
for (Row row : rows) {
if (row instanceof Put) {
mutations.add(putInternal(transaction, (Put)row, addShadowCells));
} else if (row instanceof Delete) {
Put deleteP = deleteInternal(transaction, (Delete)row);
if (!deleteP.isEmpty()) {
mutations.add(deleteP);
}
} else {
throw new UnsupportedOperationException("Unsupported mutation: " + row);
}
}
addMutations(mutations);
}
@Test
public void testConvertToDelete() {
byte[] rowKey = Bytes.add(Bytes.toBytes("GOOG:"), Bytes.toBytes(1000L));
byte[] cf = Bytes.toBytes("cf1");
byte[] clordid = Bytes.toBytes("clordid");
byte[] orderqty = Bytes.toBytes("orderqty");
byte[] leavesqty = Bytes.toBytes("leavesqty");
byte[] cumqty = Bytes.toBytes("cumqty");
Row row = new RowWithSchema(fullSchema, "GOOG", 1000L, "abcd", 100, 10, 5);
Delete delete = serde.convertToDelete(row);
Map<byte[], List<Cell>> contents = delete.getFamilyCellMap();
assertArrayEquals("Row key should be GOOG:1000L", rowKey, delete.getRow());
assertTrue("Delete contains cf1", contents.containsKey(cf));
List<Cell> cells = contents.get(cf);
assertEquals("Delete should have four cells", 4, cells.size());
assertArrayEquals("Cell 0 should be cf1:clordid", clordid, CellUtil.cloneQualifier(cells.get(0)));
assertArrayEquals("Cell 1 should be cf1:cumqty", cumqty, CellUtil.cloneQualifier(cells.get(1)));
assertArrayEquals("Cell 2 should be cf1:leavesqty", leavesqty, CellUtil.cloneQualifier(cells.get(2)));
assertArrayEquals("Cell 3 should be cf1:orderqty", orderqty, CellUtil.cloneQualifier(cells.get(3)));
}
@Override
public Mutation beforeMutate(long rowkeyBase, Mutation m) throws IOException {
if (!(m instanceof Delete)) {
if (userNames != null && userNames.length > 0) {
int mod = ((int) rowkeyBase % this.userNames.length);
if (((int) rowkeyBase % specialPermCellInsertionFactor) == 0) {
// These cells cannot be read back when running as user userName[mod]
if (LOG.isTraceEnabled()) {
LOG.trace("Adding special perm " + rowkeyBase);
}
m.setACL(userNames[mod], new Permission(Permission.Action.WRITE));
} else {
m.setACL(userNames[mod], new Permission(Permission.Action.READ));
}
}
}
return m;
}
/**
* Supports Coprocessor 'bypass'.
* @param row row to check
* @param filter filter
* @param delete delete to commit if check succeeds
* @return true or false to return to client if default processing should be bypassed, or null
* otherwise
*/
public Boolean preCheckAndDelete(final byte [] row, final Filter filter, final Delete delete)
throws IOException {
boolean bypassable = true;
boolean defaultResult = false;
if (coprocEnvironments.isEmpty()) {
return null;
}
return execOperationWithResult(
new ObserverOperationWithResult<RegionObserver, Boolean>(regionObserverGetter,
defaultResult, bypassable) {
@Override
public Boolean call(RegionObserver observer) throws IOException {
return observer.preCheckAndDelete(this, row, filter, delete, getResult());
}
});
}
@Override
public void preDelete(ObserverContext<RegionCoprocessorEnvironment> e, Delete delete,
WALEdit edit, boolean writeToWAL) throws IOException {
if (this.disabled) {
super.preDelete(e, delete, edit, writeToWAL);
return;
}
try {
preDeleteWithExceptions(e, delete, edit, writeToWAL);
return;
} catch (Throwable t) {
rethrowIndexingException(t);
}
throw new RuntimeException(
"Somehow didn't return an index update but also didn't propagate the failure to the client!");
}
@Override
public int compare(Mutation o1, Mutation o2) {
long ts1 = getTimestamp(o1);
long ts2 = getTimestamp(o2);
if (ts1 < ts2) {
return -1;
}
if (ts1 > ts2) {
return 1;
}
if (o1 instanceof Put && o2 instanceof Delete) {
return -1;
}
if (o1 instanceof Delete && o2 instanceof Put) {
return 1;
}
return 0;
}
/**
* Get the index deletes from the codec {@link IndexCodec#getIndexDeletes(TableState)} and then
* add them to the update map.
* <p>
* Expects the {@link LocalTableState} to already be correctly setup (correct timestamp, updates
* applied, etc).
* @throws IOException
*/
protected void
addDeleteUpdatesToMap(IndexUpdateManager updateMap,
LocalTableState state, long ts) throws IOException {
Iterable<IndexUpdate> cleanup = codec.getIndexDeletes(state);
if (cleanup != null) {
for (IndexUpdate d : cleanup) {
if (!d.isValid()) {
continue;
}
// override the timestamps in the delete to match the current batch.
Delete remove = (Delete)d.getUpdate();
remove.setTimestamp(ts);
updateMap.addIndexUpdate(d.getTableName(), remove);
}
}
}
@Test
public void testVisibilityLabelsWithDeleteColumns() throws Throwable {
setAuths();
final TableName tableName = TableName.valueOf(testName.getMethodName());
try (Table table = createTableAndWriteDataWithLabels(SECRET + "&" + TOPSECRET, SECRET)) {
PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
@Override
public Void run() throws Exception {
try (Connection connection = ConnectionFactory.createConnection(conf);
Table table = connection.getTable(tableName)) {
Delete d = new Delete(row1);
d.setCellVisibility(new CellVisibility(TOPSECRET + "&" + SECRET));
d.addColumns(fam, qual);
table.delete(d);
} catch (Throwable t) {
throw new IOException(t);
}
return null;
}
};
SUPERUSER.runAs(actiona);
TEST_UTIL.getAdmin().flush(tableName);
Scan s = new Scan();
s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL));
ResultScanner scanner = table.getScanner(s);
Result[] next = scanner.next(3);
assertTrue(next.length == 1);
CellScanner cellScanner = next[0].cellScanner();
cellScanner.advance();
Cell current = cellScanner.current();
assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
row2, 0, row2.length));
}
}
public void mutate(Table table, Mutation m,
long keyBase, byte[] row, byte[] cf, byte[] q, byte[] v) {
long start = System.currentTimeMillis();
try {
m = dataGenerator.beforeMutate(keyBase, m);
if (m instanceof Increment) {
table.increment((Increment)m);
} else if (m instanceof Append) {
table.append((Append)m);
} else if (m instanceof Put) {
table.checkAndMutate(row, cf).qualifier(q).ifEquals(v).thenPut((Put)m);
} else if (m instanceof Delete) {
table.checkAndMutate(row, cf).qualifier(q).ifEquals(v).thenDelete((Delete)m);
} else {
throw new IllegalArgumentException(
"unsupported mutation " + m.getClass().getSimpleName());
}
totalOpTimeMs.addAndGet(System.currentTimeMillis() - start);
} catch (IOException e) {
failedKeySet.add(keyBase);
String exceptionInfo;
if (e instanceof RetriesExhaustedWithDetailsException) {
RetriesExhaustedWithDetailsException aggEx = (RetriesExhaustedWithDetailsException)e;
exceptionInfo = aggEx.getExhaustiveDescription();
} else {
StringWriter stackWriter = new StringWriter();
PrintWriter pw = new PrintWriter(stackWriter);
e.printStackTrace(pw);
pw.flush();
exceptionInfo = StringUtils.stringifyException(e);
}
LOG.error("Failed to mutate: " + keyBase + " after " + (System.currentTimeMillis() - start) +
"ms; region information: " + getRegionDebugInfoSafe(table, m.getRow()) + "; errors: "
+ exceptionInfo);
}
}
@Override
public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, CompareOperator op,
byte[] value, Delete delete) throws IOException {
if (allowNonTransactional) {
return hTable.checkAndDelete(row, family, qualifier, op, value, delete);
} else {
throw new UnsupportedOperationException("Operation is not supported transactionally");
}
}
@Override
public void preDelete(ObserverContext<RegionCoprocessorEnvironment> e, Delete delete, WALEdit edit,
Durability durability) throws IOException {
// Translate deletes into our own delete tombstones
// Since HBase deletes cannot be undone, we need to translate deletes into special puts, which allows
// us to rollback the changes (by a real delete) if the transaction fails
// Deletes that are part of a transaction rollback do not need special handling.
// They will never be rolled back, so are performed as normal HBase deletes.
if (isRollbackOperation(delete)) {
return;
}
Transaction tx = getFromOperation(delete);
ensureValidTxLifetime(e.getEnvironment(), delete, tx);
// Other deletes are client-initiated and need to be translated into our own tombstones
// TODO: this should delegate to the DeleteStrategy implementation.
Put deleteMarkers = new Put(delete.getRow(), delete.getTimeStamp());
for (byte[] family : delete.getFamilyCellMap().keySet()) {
List<Cell> familyCells = delete.getFamilyCellMap().get(family);
if (isFamilyDelete(familyCells)) {
deleteMarkers.add(family, TxConstants.FAMILY_DELETE_QUALIFIER, familyCells.get(0).getTimestamp(),
HConstants.EMPTY_BYTE_ARRAY);
} else {
for (Cell cell : familyCells) {
deleteMarkers.add(family, CellUtil.cloneQualifier(cell), cell.getTimestamp(),
HConstants.EMPTY_BYTE_ARRAY);
}
}
}
for (Map.Entry<String, byte[]> entry : delete.getAttributesMap().entrySet()) {
deleteMarkers.setAttribute(entry.getKey(), entry.getValue());
}
e.getEnvironment().getRegion().put(deleteMarkers);
// skip normal delete handling
e.bypass();
}
/**
* {@inheritDoc}
*/
@Override
public void mutateRow(RowMutations rm) throws IOException {
// currently only support Put and Delete
for (Mutation mutation : rm.getMutations()) {
if (mutation instanceof Put) {
put((Put) mutation);
} else if (mutation instanceof Delete) {
delete((Delete) mutation);
}
}
}
@Test
public void testMultiColumnFamilyRowDeleteRollback() throws Exception {
HTable hTable = createTable(Bytes.toBytes("TestMultColFam"), new byte[][] {TestBytes.family, TestBytes.family2});
try (TransactionAwareHTable txTable = new TransactionAwareHTable(hTable, TxConstants.ConflictDetection.ROW)) {
TransactionContext txContext = new TransactionContext(new InMemoryTxSystemClient(txManager), txTable);
txContext.start();
txTable.put(new Put(TestBytes.row).add(TestBytes.family, TestBytes.qualifier, TestBytes.value));
txContext.finish();
txContext.start();
//noinspection ConstantConditions
txContext.getCurrentTransaction().setVisibility(Transaction.VisibilityLevel.SNAPSHOT_ALL);
Result result = txTable.get(new Get(TestBytes.row));
Assert.assertEquals(1, result.getFamilyMap(TestBytes.family).size());
Assert.assertEquals(0, result.getFamilyMap(TestBytes.family2).size());
txContext.finish();
//Start a tx, delete the row and then abort the tx
txContext.start();
txTable.delete(new Delete(TestBytes.row));
txContext.abort();
//Start a tx and scan all the col families to make sure none of them have delete markers
txContext.start();
txContext.getCurrentTransaction().setVisibility(Transaction.VisibilityLevel.SNAPSHOT_ALL);
result = txTable.get(new Get(TestBytes.row));
Assert.assertEquals(1, result.getFamilyMap(TestBytes.family).size());
Assert.assertEquals(0, result.getFamilyMap(TestBytes.family2).size());
txContext.finish();
}
}
@Override
public void preDelete(ObserverContext<RegionCoprocessorEnvironment> e, Delete delete, WALEdit edit,
Durability durability) throws IOException {
// Translate deletes into our own delete tombstones
// Since HBase deletes cannot be undone, we need to translate deletes into special puts, which allows
// us to rollback the changes (by a real delete) if the transaction fails
// Deletes that are part of a transaction rollback do not need special handling.
// They will never be rolled back, so are performed as normal HBase deletes.
if (isRollbackOperation(delete)) {
return;
}
Transaction tx = getFromOperation(delete);
ensureValidTxLifetime(e.getEnvironment(), delete, tx);
// Other deletes are client-initiated and need to be translated into our own tombstones
// TODO: this should delegate to the DeleteStrategy implementation.
Put deleteMarkers = new Put(delete.getRow(), delete.getTimeStamp());
for (byte[] family : delete.getFamilyCellMap().keySet()) {
List<Cell> familyCells = delete.getFamilyCellMap().get(family);
if (isFamilyDelete(familyCells)) {
deleteMarkers.add(family, TxConstants.FAMILY_DELETE_QUALIFIER, familyCells.get(0).getTimestamp(),
HConstants.EMPTY_BYTE_ARRAY);
} else {
for (Cell cell : familyCells) {
deleteMarkers.add(family, CellUtil.cloneQualifier(cell), cell.getTimestamp(),
HConstants.EMPTY_BYTE_ARRAY);
}
}
}
for (Map.Entry<String, byte[]> entry : delete.getAttributesMap().entrySet()) {
deleteMarkers.setAttribute(entry.getKey(), entry.getValue());
}
e.getEnvironment().getRegion().put(deleteMarkers);
// skip normal delete handling
e.bypass();
}
/**
* Get all the deletes necessary for a group of columns - logically, the cleanup the index table
* for a given index.
* @param group index information
* @return the cleanup for the given index, or <tt>null</tt> if no cleanup is necessary
*/
private IndexUpdate getDeleteForGroup(ColumnGroup group, TableState state) {
List<CoveredColumn> refs = group.getColumns();
try {
Pair<Scanner, IndexUpdate> kvs = state.getIndexedColumnsTableState(refs);
Pair<Integer, List<ColumnEntry>> columns =
getNextEntries(refs, kvs.getFirst(), state.getCurrentRowKey());
// make sure we close the scanner reference
kvs.getFirst().close();
// no change, just return the passed update
if (columns.getFirst() == 0) {
return kvs.getSecond();
}
// have all the column entries, so just turn it into a Delete for the row
// convert the entries to the needed values
byte[] rowKey =
composeRowKey(state.getCurrentRowKey(), columns.getFirst(), columns.getSecond());
Delete d = new Delete(rowKey);
d.setTimestamp(state.getCurrentTimestamp());
IndexUpdate update = kvs.getSecond();
update.setUpdate(d);
update.setTable(Bytes.toBytes(group.getTable()));
return update;
} catch (IOException e) {
throw new RuntimeException("Unexpected exception when getting state for columns: " + refs);
}
}
@Override
public void mutateRow(RowMutations rm) throws IOException {
if (tx == null) {
throw new IOException("Transaction not started");
}
RowMutations transactionalMutations = new RowMutations();
for (Mutation mutation : rm.getMutations()) {
if (mutation instanceof Put) {
transactionalMutations.add(transactionalizeAction((Put) mutation));
} else if (mutation instanceof Delete) {
transactionalMutations.add(transactionalizeAction((Delete) mutation));
}
}
hTable.mutateRow(transactionalMutations);
}
@Test
public void testMinorCompactionWithDeleteVersion1() throws Exception {
Delete deleteVersion = new Delete(secondRowBytes);
deleteVersion.addColumns(fam2, col2, 2);
/* compactionThreshold is 3. The table has 4 versions: 0, 1, 2, and 3.
* We delete versions 0 ... 2. So, we still have one remaining.
*/
testMinorCompactionWithDelete(deleteVersion, 1);
}
/**
* Delete the passed <code>d</code> from the <code>hbase:meta</code> table.
*
* COPIED MetaTableAccessor.deleteFromMetaTable()
* @param connection connection we're using
* @param d Delete to add to hbase:meta
*/
private static void deleteFromMetaTable(final Connection connection, final Delete d)
throws IOException {
if (connection == null) {
throw new NullPointerException("No connection");
} else if (connection.isClosed()) {
throw new IOException("connection is closed");
}
try (Table t = connection.getTable(TableName.META_TABLE_NAME)) {
List<Delete> deletes = new ArrayList<>();
deletes.add(d);
LOG.debug("Add {} delete to meta table", deletes);
t.delete(deletes);
}
}
public static MutationProto toProto(Mutation mutation) throws IOException {
MutationType type;
if (mutation instanceof Put) {
type = MutationType.PUT;
} else if (mutation instanceof Delete) {
type = MutationType.DELETE;
} else {
throw new IllegalArgumentException("Only Put and Delete are supported");
}
return org.apache.hadoop.hbase.protobuf.ProtobufUtil.toMutation(type, mutation);
}
@Test
public void testMajorCompactionAfterDelete() throws Exception {
init(UTIL.getConfiguration(), 100);
byte[] dummyData = makeDummyData(200); // larger than mob threshold
Table loader = new RegionAsTable(region);
// create hfiles and mob hfiles but don't trigger compaction
int numHfiles = compactionThreshold - 1;
byte[] deleteRow = Bytes.add(STARTROW, Bytes.toBytes(0));
for (int i = 0; i < numHfiles; i++) {
Put p = createPut(i, dummyData);
loader.put(p);
region.flush(true);
}
assertEquals("Before compaction: store files", numHfiles, countStoreFiles());
assertEquals("Before compaction: mob file count", numHfiles, countMobFiles());
assertEquals("Before compaction: rows", numHfiles, UTIL.countRows(region));
assertEquals("Before compaction: mob rows", numHfiles, countMobRows());
assertEquals("Before compaction: number of mob cells", numHfiles, countMobCellsInMetadata());
// now let's delete some cells that contain mobs
Delete delete = new Delete(deleteRow);
delete.addFamily(COLUMN_FAMILY);
region.delete(delete);
region.flush(true);
assertEquals("Before compaction: store files", numHfiles + 1, countStoreFiles());
assertEquals("Before compaction: mob files", numHfiles, countMobFiles());
// region.compactStores();
region.compact(true);
assertEquals("After compaction: store files", 1, countStoreFiles());
}
/**
* Delete all rows from the given table. This method is intended only for development and testing use.
* @param tableString
* @param timestamp
* @throws IOException
*/
@Override
public void clearTable(String tableString, long timestamp) throws IOException
{
TableName tableName = TableName.valueOf(tableString);
if (!adm.tableExists(tableName)) {
log.debug("Attempted to clear table {} before it exists (noop)", tableString);
return;
}
// Unfortunately, linear scanning and deleting rows is faster in HBase when running integration tests than
// disabling and deleting/truncating tables.
final Scan scan = new Scan();
scan.setCacheBlocks(false);
scan.setCaching(2000);
scan.setTimeRange(0, Long.MAX_VALUE);
scan.readVersions(1);
try (final Table table = adm.getConnection().getTable(tableName);
final ResultScanner scanner = table.getScanner(scan)) {
final Iterator<Result> iterator = scanner.iterator();
final int batchSize = 1000;
final List<Delete> deleteList = new ArrayList<>();
while (iterator.hasNext()) {
deleteList.add(new Delete(iterator.next().getRow(), timestamp));
if (!iterator.hasNext() || deleteList.size() == batchSize) {
table.delete(deleteList);
deleteList.clear();
}
}
}
}
/**
* Invokes Table#delete to delete test data (i.e. the row)
*
* @param table Standard Table object
* @throws IOException If IO problem is encountered
*/
static void deleteRow(final Table table) throws IOException {
System.out.println("Deleting row [" + Bytes.toString(MY_ROW_ID)
+ "] from Table ["
+ table.getName().getNameAsString() + "].");
table.delete(new Delete(MY_ROW_ID));
}
private boolean doCheckAndDelete(byte[] row, byte[] family, byte[] qualifier, byte[] value,
Delete delete) throws IOException {
Put put = new Put(row, HConstants.LATEST_TIMESTAMP, delete.getFamilyCellMap());
// column to check-the-value
put.add(new KeyValue(row, family, qualifier, value));
CellSetModel model = buildModelFromPut(put);
StringBuilder sb = new StringBuilder();
sb.append('/');
sb.append(Bytes.toString(name));
sb.append('/');
sb.append(toURLEncodedBytes(row));
sb.append("?check=delete");
for (int i = 0; i < maxRetries; i++) {
Response response =
client.put(sb.toString(), Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput());
int code = response.getCode();
switch (code) {
case 200:
return true;
case 304: // NOT-MODIFIED
return false;
case 509:
try {
Thread.sleep(sleepTime);
} catch (final InterruptedException e) {
throw (InterruptedIOException) new InterruptedIOException().initCause(e);
}
break;
default:
throw new IOException("checkAndDelete request failed with " + code);
}
}
throw new IOException("checkAndDelete request timed out");
}
/**
* Batch delete
* @throws IOException
*/
public void deleteRowkeys(List<byte[]> rowkeys) throws IOException {
final List<Delete> deletes = new ArrayList<Delete>(rowkeys.size());
for (byte[] rowkey : rowkeys) {
final Delete delete = createDelete(rowkey);
deletes.add(delete);
}
tbl.delete(deletes);
}
@Test(timeOut = 10_000)
public void runTestDeleteFamily(ITestContext context) throws Exception {
TransactionManager tm = newTransactionManager(context);
TTable tt = new TTable(connection, TEST_TABLE);
Transaction t1 = tm.begin();
LOG.info("Transaction created " + t1);
int rowsWritten = 10;
FamCol famColA = new FamCol(famA, colA);
FamCol famColB = new FamCol(famB, colB);
writeRows(tt, t1, rowsWritten, famColA, famColB);
tm.commit(t1);
Transaction t2 = tm.begin();
Delete d = new Delete(modrow);
d.addFamily(famA);
tt.delete(t2, d);
Transaction tscan = tm.begin();
ResultScanner rs = tt.getScanner(tscan, new Scan());
Map<FamCol, Integer> count = countColsInRows(rs, famColA, famColB);
assertEquals((int) count.get(famColA), rowsWritten, "ColA count should be equal to rowsWritten");
assertEquals((int) count.get(famColB), rowsWritten, "ColB count should be equal to rowsWritten");
if (getClient(context).isLowLatency()) {
return;
}
tm.commit(t2);
tscan = tm.begin();
rs = tt.getScanner(tscan, new Scan());
count = countColsInRows(rs, famColA, famColB);
assertEquals((int) count.get(famColA), (rowsWritten - 1), "ColA count should be equal to rowsWritten - 1");
assertEquals((int) count.get(famColB), rowsWritten, "ColB count should be equal to rowsWritten");
}
@Override
public void deleteAgentIds(Map<String, List<String>> applicationAgentIdMap) {
if (MapUtils.isEmpty(applicationAgentIdMap)) {
return;
}
List<Delete> deletes = new ArrayList<>(applicationAgentIdMap.size());
for (Map.Entry<String, List<String>> entry : applicationAgentIdMap.entrySet()) {
String applicationName = entry.getKey();
List<String> agentIds = entry.getValue();
if (StringUtils.isEmpty(applicationName) || CollectionUtils.isEmpty(agentIds)) {
continue;
}
Delete delete = new Delete(Bytes.toBytes(applicationName));
for (String agentId : agentIds) {
if (!StringUtils.isEmpty(agentId)) {
delete.addColumns(descriptor.getColumnFamilyName(), Bytes.toBytes(agentId));
}
}
// don't delete if nothing has been specified except row
if (!delete.getFamilyCellMap().isEmpty()) {
deletes.add(delete);
}
}
TableName applicationIndexTableName = descriptor.getTableName();
hbaseOperations2.delete(applicationIndexTableName, deletes);
}