use of org.hbase.async.DeleteRequest in project opentsdb by OpenTSDB.
the class UniqueId method deleteAsync.
/**
* Attempts to remove the mappings for the given string from the UID table
* as well as the cache. If used, the caller should remove the entry from all
* TSD caches as well.
* <p>
* WARNING: This is a best attempt only method in that we'll lookup the UID
* for the given string, then issue two delete requests, one for each mapping.
* If either mapping fails then the cache can be re-populated later on with
* stale data. In that case, please run the FSCK utility.
* <p>
* WARNING 2: This method will NOT delete time series data or TSMeta data
* associated with the UIDs. It only removes them from the UID table. Deleting
* a metric is generally safe as you won't query over it in the future. But
* deleting tag keys or values can cause queries to fail if they find data
* without a corresponding name.
*
* @param name The name of the UID to delete
* @return A deferred to wait on for completion. The result will be null if
* successful, an exception otherwise.
* @throws NoSuchUniqueName if the UID string did not exist in storage
* @throws IllegalStateException if the TSDB wasn't set for this UID object
* @since 2.2
*/
public Deferred<Object> deleteAsync(final String name) {
if (tsdb == null) {
throw new IllegalStateException("The TSDB is null for this UID object.");
}
final byte[] uid = new byte[id_width];
final ArrayList<Deferred<Object>> deferreds = new ArrayList<Deferred<Object>>(2);
/** Catches errors and still cleans out the cache */
class ErrCB implements Callback<Object, Exception> {
@Override
public Object call(final Exception ex) throws Exception {
name_cache.remove(name);
id_cache.remove(fromBytes(uid));
LOG.error("Failed to delete " + fromBytes(kind) + " UID " + name + " but still cleared the cache", ex);
return ex;
}
}
/** Used to wait on the group of delete requests */
class GroupCB implements Callback<Deferred<Object>, ArrayList<Object>> {
@Override
public Deferred<Object> call(final ArrayList<Object> response) throws Exception {
name_cache.remove(name);
id_cache.remove(fromBytes(uid));
LOG.info("Successfully deleted " + fromBytes(kind) + " UID " + name);
return Deferred.fromResult(null);
}
}
/** Called after fetching the UID from storage */
class LookupCB implements Callback<Deferred<Object>, byte[]> {
@Override
public Deferred<Object> call(final byte[] stored_uid) throws Exception {
if (stored_uid == null) {
return Deferred.fromError(new NoSuchUniqueName(kind(), name));
}
System.arraycopy(stored_uid, 0, uid, 0, id_width);
final DeleteRequest forward = new DeleteRequest(table, toBytes(name), ID_FAMILY, kind);
deferreds.add(tsdb.getClient().delete(forward));
final DeleteRequest reverse = new DeleteRequest(table, uid, NAME_FAMILY, kind);
deferreds.add(tsdb.getClient().delete(reverse));
final DeleteRequest meta = new DeleteRequest(table, uid, NAME_FAMILY, toBytes((type.toString().toLowerCase() + "_meta")));
deferreds.add(tsdb.getClient().delete(meta));
return Deferred.group(deferreds).addCallbackDeferring(new GroupCB());
}
}
final byte[] cached_uid = name_cache.get(name);
if (cached_uid == null) {
return getIdFromHBase(name).addCallbackDeferring(new LookupCB()).addErrback(new ErrCB());
}
System.arraycopy(cached_uid, 0, uid, 0, id_width);
final DeleteRequest forward = new DeleteRequest(table, toBytes(name), ID_FAMILY, kind);
deferreds.add(tsdb.getClient().delete(forward));
final DeleteRequest reverse = new DeleteRequest(table, uid, NAME_FAMILY, kind);
deferreds.add(tsdb.getClient().delete(reverse));
final DeleteRequest meta = new DeleteRequest(table, uid, NAME_FAMILY, toBytes((type.toString().toLowerCase() + "_meta")));
deferreds.add(tsdb.getClient().delete(meta));
return Deferred.group(deferreds).addCallbackDeferring(new GroupCB()).addErrback(new ErrCB());
}
use of org.hbase.async.DeleteRequest in project opentsdb by OpenTSDB.
the class UniqueId method rename.
/**
* Reassigns the UID to a different name (non-atomic).
* <p>
* Whatever was the UID of {@code oldname} will be given to {@code newname}.
* {@code oldname} will no longer be assigned a UID.
* <p>
* Beware that the assignment change is <b>not atommic</b>. If two threads
* or processes attempt to rename the same UID differently, the result is
* unspecified and might even be inconsistent. This API is only here for
* administrative purposes, not for normal programmatic interactions.
* @param oldname The old name to rename.
* @param newname The new name.
* @throws NoSuchUniqueName if {@code oldname} wasn't assigned.
* @throws IllegalArgumentException if {@code newname} was already assigned.
* @throws HBaseException if there was a problem with HBase while trying to
* update the mapping.
*/
public void rename(final String oldname, final String newname) {
final byte[] row = getId(oldname);
final String row_string = fromBytes(row);
{
byte[] id = null;
try {
id = getId(newname);
} catch (NoSuchUniqueName e) {
// OK, we don't want the new name to be assigned.
}
if (id != null) {
throw new IllegalArgumentException("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": new name already" + " assigned ID=" + Arrays.toString(id));
}
}
if (renaming_id_names.contains(row_string) || renaming_id_names.contains(newname)) {
throw new IllegalArgumentException("Ongoing rename on the same ID(\"" + Arrays.toString(row) + "\") or an identical new name(\"" + newname + "\")");
}
renaming_id_names.add(row_string);
renaming_id_names.add(newname);
final byte[] newnameb = toBytes(newname);
// but the forward mapping without reverse mapping is bad.
try {
final PutRequest reverse_mapping = new PutRequest(table, row, NAME_FAMILY, kind, newnameb);
hbasePutWithRetry(reverse_mapping, MAX_ATTEMPTS_PUT, INITIAL_EXP_BACKOFF_DELAY);
} catch (HBaseException e) {
LOG.error("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to update reverse" + " mapping for ID=" + Arrays.toString(row), e);
renaming_id_names.remove(row_string);
renaming_id_names.remove(newname);
throw e;
}
// Now create the new forward mapping.
try {
final PutRequest forward_mapping = new PutRequest(table, newnameb, ID_FAMILY, kind, row);
hbasePutWithRetry(forward_mapping, MAX_ATTEMPTS_PUT, INITIAL_EXP_BACKOFF_DELAY);
} catch (HBaseException e) {
LOG.error("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to create the" + " new forward mapping with ID=" + Arrays.toString(row), e);
renaming_id_names.remove(row_string);
renaming_id_names.remove(newname);
throw e;
}
// Update cache.
// add new name -> ID
addIdToCache(newname, row);
// update ID -> new name
id_cache.put(fromBytes(row), newname);
// remove old name -> ID
name_cache.remove(oldname);
// Delete the old forward mapping.
try {
final DeleteRequest old_forward_mapping = new DeleteRequest(table, toBytes(oldname), ID_FAMILY, kind);
client.delete(old_forward_mapping).joinUninterruptibly();
} catch (HBaseException e) {
LOG.error("When trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to remove the" + " old forward mapping for ID=" + Arrays.toString(row), e);
throw e;
} catch (Exception e) {
final String msg = "Unexpected exception when trying rename(\"" + oldname + "\", \"" + newname + "\") on " + this + ": Failed to remove the" + " old forward mapping for ID=" + Arrays.toString(row);
LOG.error("WTF? " + msg, e);
throw new RuntimeException(msg, e);
} finally {
renaming_id_names.remove(row_string);
renaming_id_names.remove(newname);
}
// Success!
}
Aggregations