Search in sources :

Example 56 with Callback

use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.

the class TSMeta method getFromStorage.

/**
 * Attempts to fetch the timeseries meta data from storage.
 * This method will fetch the {@code counter} and {@code meta} columns.
 * <b>Note:</b> This method will not load the UIDMeta objects.
 * @param tsdb The TSDB to use for storage access
 * @param tsuid The UID of the meta to fetch
 * @return A TSMeta object if found, null if not
 * @throws HBaseException if there was an issue fetching
 * @throws IllegalArgumentException if parsing failed
 * @throws JSONException if the data was corrupted
 */
private static Deferred<TSMeta> getFromStorage(final TSDB tsdb, final byte[] tsuid) {
    /**
     * Called after executing the GetRequest to parse the meta data.
     */
    final class GetCB implements Callback<Deferred<TSMeta>, ArrayList<KeyValue>> {

        /**
         * @return Null if the meta did not exist or a valid TSMeta object if it
         * did.
         */
        @Override
        public Deferred<TSMeta> call(final ArrayList<KeyValue> row) throws Exception {
            if (row == null || row.isEmpty()) {
                return Deferred.fromResult(null);
            }
            long dps = 0;
            long last_received = 0;
            TSMeta meta = null;
            for (KeyValue column : row) {
                if (Arrays.equals(COUNTER_QUALIFIER, column.qualifier())) {
                    dps = Bytes.getLong(column.value());
                    last_received = column.timestamp() / 1000;
                } else if (Arrays.equals(META_QUALIFIER, column.qualifier())) {
                    meta = JSON.parseToObject(column.value(), TSMeta.class);
                }
            }
            if (meta == null) {
                LOG.warn("Found a counter TSMeta column without a meta for TSUID: " + UniqueId.uidToString(row.get(0).key()));
                return Deferred.fromResult(null);
            }
            meta.total_dps = dps;
            meta.last_received = last_received;
            return Deferred.fromResult(meta);
        }
    }
    final GetRequest get = new GetRequest(tsdb.metaTable(), tsuid);
    get.family(FAMILY);
    get.qualifiers(new byte[][] { COUNTER_QUALIFIER, META_QUALIFIER });
    return tsdb.getClient().get(get).addCallbackDeferring(new GetCB());
}
Also used : KeyValue(org.hbase.async.KeyValue) Callback(com.stumbleupon.async.Callback) GetRequest(org.hbase.async.GetRequest) ArrayList(java.util.ArrayList)

Example 57 with Callback

use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.

the class TSMeta method metaExistsInStorage.

/**
 * Determines if an entry exists in storage or not.
 * This is used by the UID Manager tool to determine if we need to write a
 * new TSUID entry or not. It will not attempt to verify if the stored data is
 * valid, just checks to see if something is stored in the proper column.
 * @param tsdb  The TSDB to use for storage access
 * @param tsuid The UID of the meta to verify
 * @return True if data was found, false if not
 * @throws HBaseException if there was an issue fetching
 */
public static Deferred<Boolean> metaExistsInStorage(final TSDB tsdb, final String tsuid) {
    final GetRequest get = new GetRequest(tsdb.metaTable(), UniqueId.stringToUid(tsuid));
    get.family(FAMILY);
    get.qualifier(META_QUALIFIER);
    /**
     * Callback from the GetRequest that simply determines if the row is empty
     * or not
     */
    final class ExistsCB implements Callback<Boolean, ArrayList<KeyValue>> {

        @Override
        public Boolean call(ArrayList<KeyValue> row) throws Exception {
            if (row == null || row.isEmpty() || row.get(0).value() == null) {
                return false;
            }
            return true;
        }
    }
    return tsdb.getClient().get(get).addCallback(new ExistsCB());
}
Also used : Callback(com.stumbleupon.async.Callback) KeyValue(org.hbase.async.KeyValue) GetRequest(org.hbase.async.GetRequest) ArrayList(java.util.ArrayList)

Example 58 with Callback

use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.

the class TSMeta method storeIfNecessary.

/**
 * Attempts to fetch the meta column and if null, attempts to write a new
 * column using {@link #storeNew}.
 * @param tsdb The TSDB instance to use for access.
 * @param tsuid The TSUID of the time series.
 * @return A deferred with a true if the meta exists or was created, false
 * if the meta did not exist and writing failed.
 */
public static Deferred<Boolean> storeIfNecessary(final TSDB tsdb, final byte[] tsuid) {
    final GetRequest get = new GetRequest(tsdb.metaTable(), tsuid);
    get.family(FAMILY);
    get.qualifier(META_QUALIFIER);
    final class CreateNewCB implements Callback<Deferred<Boolean>, Object> {

        @Override
        public Deferred<Boolean> call(Object arg0) throws Exception {
            final TSMeta meta = new TSMeta(tsuid, System.currentTimeMillis() / 1000);
            final class FetchNewCB implements Callback<Deferred<Boolean>, TSMeta> {

                @Override
                public Deferred<Boolean> call(TSMeta stored_meta) throws Exception {
                    // pass to the search plugin
                    tsdb.indexTSMeta(stored_meta);
                    // pass through the trees
                    tsdb.processTSMetaThroughTrees(stored_meta);
                    return Deferred.fromResult(true);
                }
            }
            final class StoreNewCB implements Callback<Deferred<Boolean>, Boolean> {

                @Override
                public Deferred<Boolean> call(Boolean success) throws Exception {
                    if (!success) {
                        LOG.warn("Unable to save metadata: " + meta);
                        return Deferred.fromResult(false);
                    }
                    LOG.info("Successfullly created new TSUID entry for: " + meta);
                    return new LoadUIDs(tsdb, UniqueId.uidToString(tsuid)).call(meta).addCallbackDeferring(new FetchNewCB());
                }
            }
            return meta.storeNew(tsdb).addCallbackDeferring(new StoreNewCB());
        }
    }
    final class ExistsCB implements Callback<Deferred<Boolean>, ArrayList<KeyValue>> {

        @Override
        public Deferred<Boolean> call(ArrayList<KeyValue> row) throws Exception {
            if (row == null || row.isEmpty() || row.get(0).value() == null) {
                return new CreateNewCB().call(null);
            }
            return Deferred.fromResult(true);
        }
    }
    return tsdb.getClient().get(get).addCallbackDeferring(new ExistsCB());
}
Also used : Callback(com.stumbleupon.async.Callback) KeyValue(org.hbase.async.KeyValue) GetRequest(org.hbase.async.GetRequest) ArrayList(java.util.ArrayList)

Example 59 with Callback

use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.

the class TSMeta method incrementAndGetCounter.

/**
 * Increments the tsuid datapoint counter or creates a new counter. Also
 * creates a new meta data entry if the counter did not exist.
 * <b>Note:</b> This method also:
 * <ul><li>Passes the new TSMeta object to the Search plugin after loading
 * UIDMeta objects</li>
 * <li>Passes the new TSMeta through all configured trees if enabled</li></ul>
 * @param tsdb The TSDB to use for storage access
 * @param tsuid The TSUID to increment or create
 * @return 0 if the put failed, a positive LONG if the put was successful
 * @throws HBaseException if there was a storage issue
 * @throws JSONException if the data was corrupted
 * @throws NoSuchUniqueName if one of the UIDMeta objects does not exist
 */
public static Deferred<Long> incrementAndGetCounter(final TSDB tsdb, final byte[] tsuid) {
    /**
     * Callback that will create a new TSMeta if the increment result is 1 or
     * will simply return the new value.
     */
    final class TSMetaCB implements Callback<Deferred<Long>, Long> {

        /**
         * Called after incrementing the counter and will create a new TSMeta if
         * the returned value was 1 as well as pass the new meta through trees
         * and the search indexer if configured.
         * @return 0 if the put failed, a positive LONG if the put was successful
         */
        @Override
        public Deferred<Long> call(final Long incremented_value) throws Exception {
            LOG.debug("Value: " + incremented_value);
            if (incremented_value > 1) {
                // whenever the user runs the full sync CLI
                return Deferred.fromResult(incremented_value);
            }
            // create a new meta object with the current system timestamp. Ideally
            // we would want the data point's timestamp, but that's much more data
            // to keep track of and may not be accurate.
            final TSMeta meta = new TSMeta(tsuid, System.currentTimeMillis() / 1000);
            /**
             * Called after the meta has been passed through tree processing. The
             * result of the processing doesn't matter and the user may not even
             * have it enabled, so we'll just return the counter.
             */
            final class TreeCB implements Callback<Deferred<Long>, Boolean> {

                @Override
                public Deferred<Long> call(Boolean success) throws Exception {
                    return Deferred.fromResult(incremented_value);
                }
            }
            /**
             * Called after retrieving the newly stored TSMeta and loading
             * associated UIDMeta objects. This class will also pass the meta to the
             * search plugin and run it through any configured trees
             */
            final class FetchNewCB implements Callback<Deferred<Long>, TSMeta> {

                @Override
                public Deferred<Long> call(TSMeta stored_meta) throws Exception {
                    // pass to the search plugin
                    tsdb.indexTSMeta(stored_meta);
                    // pass through the trees
                    return tsdb.processTSMetaThroughTrees(stored_meta).addCallbackDeferring(new TreeCB());
                }
            }
            /**
             * Called after the CAS to store the new TSMeta object. If the CAS
             * failed then we return immediately with a 0 for the counter value.
             * Otherwise we keep processing to load the meta and pass it on.
             */
            final class StoreNewCB implements Callback<Deferred<Long>, Boolean> {

                @Override
                public Deferred<Long> call(Boolean success) throws Exception {
                    if (!success) {
                        LOG.warn("Unable to save metadata: " + meta);
                        return Deferred.fromResult(0L);
                    }
                    LOG.info("Successfullly created new TSUID entry for: " + meta);
                    return new LoadUIDs(tsdb, UniqueId.uidToString(tsuid)).call(meta).addCallbackDeferring(new FetchNewCB());
                }
            }
            // store the new TSMeta object and setup the callback chain
            return meta.storeNew(tsdb).addCallbackDeferring(new StoreNewCB());
        }
    }
    // setup the increment request and execute
    final AtomicIncrementRequest inc = new AtomicIncrementRequest(tsdb.metaTable(), tsuid, FAMILY, COUNTER_QUALIFIER);
    // then we only want to increment the data point count.
    if (!tsdb.getConfig().enable_realtime_ts()) {
        return tsdb.getClient().atomicIncrement(inc);
    }
    return tsdb.getClient().atomicIncrement(inc).addCallbackDeferring(new TSMetaCB());
}
Also used : Callback(com.stumbleupon.async.Callback) AtomicIncrementRequest(org.hbase.async.AtomicIncrementRequest)

Example 60 with Callback

use of com.stumbleupon.async.Callback in project opentsdb by OpenTSDB.

the class TSUIDQuery method getLastPoint.

/**
 * Attempts to fetch the last data point for the given metric or TSUID.
 * If back_scan == 0 and meta is enabled via
 * "tsd.core.meta.enable_tsuid_tracking" or
 * "tsd.core.meta.enable_tsuid_incrementing" then we will look up the metric
 * or TSUID in the meta table first and use the counter there to get the
 * last write time.
 * <p>
 * However if backscan is set, then we'll start with the current time and
 * iterate back "back_scan" number of hours until we find a value.
 * <p>
 * @param resolve_names Whether or not to resolve the UIDs back to their
 * names when we find a value.
 * @param back_scan The number of hours back in time to scan
 * @return A data point if found, null if not. Or an exception if something
 * went pear shaped.
 */
public Deferred<IncomingDataPoint> getLastPoint(final boolean resolve_names, final int back_scan) {
    if (back_scan < 0) {
        throw new IllegalArgumentException("Backscan must be zero or a positive number");
    }
    this.resolve_names = resolve_names;
    this.back_scan = back_scan;
    final boolean meta_enabled = tsdb.getConfig().enable_tsuid_tracking() || tsdb.getConfig().enable_tsuid_incrementing();
    class TSUIDCB implements Callback<Deferred<IncomingDataPoint>, byte[]> {

        @Override
        public Deferred<IncomingDataPoint> call(final byte[] incoming_tsuid) throws Exception {
            if (tsuid == null && incoming_tsuid == null) {
                return Deferred.fromError(new RuntimeException("Both incoming and " + "supplied TSUIDs were null for " + TSUIDQuery.this));
            } else if (incoming_tsuid != null) {
                setTSUID(incoming_tsuid);
            }
            if (back_scan < 1 && meta_enabled) {
                final GetRequest get = new GetRequest(tsdb.metaTable(), tsuid);
                get.family(TSMeta.FAMILY());
                get.qualifier(TSMeta.COUNTER_QUALIFIER());
                return tsdb.getClient().get(get).addCallbackDeferring(new MetaCB());
            }
            if (last_timestamp > 0) {
                last_timestamp = Internal.baseTime(last_timestamp);
            } else {
                last_timestamp = Internal.baseTime(DateTime.currentTimeMillis());
            }
            final byte[] key = RowKey.rowKeyFromTSUID(tsdb, tsuid, last_timestamp);
            final GetRequest get = new GetRequest(tsdb.dataTable(), key);
            get.family(TSDB.FAMILY());
            return tsdb.getClient().get(get).addCallbackDeferring(new LastPointCB());
        }

        @Override
        public String toString() {
            return "TSUID callback";
        }
    }
    if (tsuid == null) {
        return tsuidFromMetric(tsdb, metric, tags).addCallbackDeferring(new TSUIDCB());
    }
    try {
        // damn typed exceptions....
        return new TSUIDCB().call(null);
    } catch (Exception e) {
        return Deferred.fromError(e);
    }
}
Also used : Callback(com.stumbleupon.async.Callback) GetRequest(org.hbase.async.GetRequest) IncomingDataPoint(net.opentsdb.core.IncomingDataPoint)

Aggregations

Callback (com.stumbleupon.async.Callback)62 ArrayList (java.util.ArrayList)48 Deferred (com.stumbleupon.async.Deferred)30 KeyValue (org.hbase.async.KeyValue)29 GetRequest (org.hbase.async.GetRequest)17 HashMap (java.util.HashMap)16 IOException (java.io.IOException)15 Map (java.util.Map)15 PutRequest (org.hbase.async.PutRequest)13 HBaseException (org.hbase.async.HBaseException)11 Scanner (org.hbase.async.Scanner)11 DeferredGroupException (com.stumbleupon.async.DeferredGroupException)10 List (java.util.List)10 TreeMap (java.util.TreeMap)7 IncomingDataPoint (net.opentsdb.core.IncomingDataPoint)7 DeleteRequest (org.hbase.async.DeleteRequest)6 DataPoints (net.opentsdb.core.DataPoints)5 TSSubQuery (net.opentsdb.core.TSSubQuery)5 TSQuery (net.opentsdb.core.TSQuery)4 Annotation (net.opentsdb.meta.Annotation)4