/** * Attempts to retrieve the specified tree rule from storage. * * @param tsdb The TSDB to use for storage access * @param tree_id ID of the tree the rule belongs to * @param level Level where the rule resides * @param order Order where the rule resides * @return A TreeRule object if found, null if it does not exist * @throws HBaseException if there was an issue * @throws IllegalArgumentException if the one of the required parameters was missing * @throws JSONException if the object could not be serialized */ public static Deferred<TreeRule> fetchRule( final TSDB tsdb, final int tree_id, final int level, final int order) { if (tree_id < 1 || tree_id > 65535) { throw new IllegalArgumentException("Invalid Tree ID"); } if (level < 0) { throw new IllegalArgumentException("Invalid rule level"); } if (order < 0) { throw new IllegalArgumentException("Invalid rule order"); } // fetch the whole row final GetRequest get = new GetRequest(tsdb.treeTable(), Tree.idToBytes(tree_id)); get.family(Tree.TREE_FAMILY()); get.qualifier(getQualifier(level, order)); /** Called after fetching to parse the results */ final class FetchCB implements Callback<Deferred<TreeRule>, ArrayList<KeyValue>> { @Override public Deferred<TreeRule> call(final ArrayList<KeyValue> row) { if (row == null || row.isEmpty()) { return Deferred.fromResult(null); } return Deferred.fromResult(parseFromStorage(row.get(0))); } } return tsdb.getClient().get(get).addCallbackDeferring(new FetchCB()); }
/** @return True if the CAS was successful, false if not */ @Override public Deferred<Boolean> call(final TreeRule fetched_rule) { TreeRule stored_rule = fetched_rule; final byte[] original_rule = stored_rule == null ? new byte[0] : JSON.serializeToBytes(stored_rule); if (stored_rule == null) { stored_rule = local_rule; } else { if (!stored_rule.copyChanges(local_rule, overwrite)) { LOG.debug(this + " does not have changes, skipping sync to storage"); throw new IllegalStateException("No changes detected in the rule"); } } // reset the local change map so we don't keep writing on subsequent // requests initializeChangedMap(); // validate before storing stored_rule.validateRule(); final PutRequest put = new PutRequest( tsdb.treeTable(), Tree.idToBytes(tree_id), Tree.TREE_FAMILY(), getQualifier(level, order), JSON.serializeToBytes(stored_rule)); return tsdb.getClient().compareAndSet(put, original_rule); }
/** * Attempts to delete all rules belonging to the given tree. * * @param tsdb The TSDB to use for storage access * @param tree_id ID of the tree the rules belongs to * @return A deferred to wait on for completion. The value has no meaning and may be null. * @throws HBaseException if there was an issue * @throws IllegalArgumentException if the one of the required parameters was missing */ public static Deferred<Object> deleteAllRules(final TSDB tsdb, final int tree_id) { if (tree_id < 1 || tree_id > 65535) { throw new IllegalArgumentException("Invalid Tree ID"); } // fetch the whole row final GetRequest get = new GetRequest(tsdb.treeTable(), Tree.idToBytes(tree_id)); get.family(Tree.TREE_FAMILY()); /** * Called after fetching the requested row. If the row is empty, we just return, otherwise we * compile a list of qualifiers to delete and submit a single delete request to storage. */ final class GetCB implements Callback<Deferred<Object>, ArrayList<KeyValue>> { @Override public Deferred<Object> call(final ArrayList<KeyValue> row) throws Exception { if (row == null || row.isEmpty()) { return Deferred.fromResult(null); } final ArrayList<byte[]> qualifiers = new ArrayList<byte[]>(row.size()); for (KeyValue column : row) { if (column.qualifier().length > RULE_PREFIX.length && Bytes.memcmp(RULE_PREFIX, column.qualifier(), 0, RULE_PREFIX.length) == 0) { qualifiers.add(column.qualifier()); } } final DeleteRequest delete = new DeleteRequest( tsdb.treeTable(), Tree.idToBytes(tree_id), Tree.TREE_FAMILY(), qualifiers.toArray(new byte[qualifiers.size()][])); return tsdb.getClient().delete(delete); } } return tsdb.getClient().get(get).addCallbackDeferring(new GetCB()); }
/** * Attempts to delete the specified rule from storage * * @param tsdb The TSDB to use for storage access * @param tree_id ID of the tree the rule belongs to * @param level Level where the rule resides * @param order Order where the rule resides * @return A deferred without meaning. The response may be null and should only be used to track * completion. * @throws HBaseException if there was an issue * @throws IllegalArgumentException if the one of the required parameters was missing */ public static Deferred<Object> deleteRule( final TSDB tsdb, final int tree_id, final int level, final int order) { if (tree_id < 1 || tree_id > 65535) { throw new IllegalArgumentException("Invalid Tree ID"); } if (level < 0) { throw new IllegalArgumentException("Invalid rule level"); } if (order < 0) { throw new IllegalArgumentException("Invalid rule order"); } final DeleteRequest delete = new DeleteRequest( tsdb.treeTable(), Tree.idToBytes(tree_id), Tree.TREE_FAMILY(), getQualifier(level, order)); return tsdb.getClient().delete(delete); }
@Override public Deferred<Object> call(final ArrayList<KeyValue> row) throws Exception { if (row == null || row.isEmpty()) { return Deferred.fromResult(null); } final ArrayList<byte[]> qualifiers = new ArrayList<byte[]>(row.size()); for (KeyValue column : row) { if (column.qualifier().length > RULE_PREFIX.length && Bytes.memcmp(RULE_PREFIX, column.qualifier(), 0, RULE_PREFIX.length) == 0) { qualifiers.add(column.qualifier()); } } final DeleteRequest delete = new DeleteRequest( tsdb.treeTable(), Tree.idToBytes(tree_id), Tree.TREE_FAMILY(), qualifiers.toArray(new byte[qualifiers.size()][])); return tsdb.getClient().delete(delete); }