Search in sources :

Example 16 with PutRequest

use of org.hbase.async.PutRequest in project opentsdb by OpenTSDB.

the class UniqueIdRpc method handleTSMeta.

/**
   * Handles CRUD calls to individual TSMeta data entries
   * @param tsdb The TSDB from the RPC router
   * @param query The query for this request
   */
private void handleTSMeta(final TSDB tsdb, final HttpQuery query) {
    final HttpMethod method = query.getAPIMethod();
    // GET
    if (method == HttpMethod.GET) {
        String tsuid = null;
        if (query.hasQueryStringParam("tsuid")) {
            tsuid = query.getQueryStringParam("tsuid");
            try {
                final TSMeta meta = TSMeta.getTSMeta(tsdb, tsuid).joinUninterruptibly();
                if (meta != null) {
                    query.sendReply(query.serializer().formatTSMetaV1(meta));
                } else {
                    throw new BadRequestException(HttpResponseStatus.NOT_FOUND, "Could not find Timeseries meta data");
                }
            } catch (NoSuchUniqueName e) {
                // the timeseries meta data
                throw new BadRequestException(HttpResponseStatus.NOT_FOUND, "Unable to find one of the UIDs", e);
            } catch (BadRequestException e) {
                throw e;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            String mquery = query.getRequiredQueryStringParam("m");
            // m is of the following forms:
            // metric[{tag=value,...}]
            // where the parts in square brackets `[' .. `]' are optional.
            final HashMap<String, String> tags = new HashMap<String, String>();
            String metric = null;
            try {
                metric = Tags.parseWithMetric(mquery, tags);
            } catch (IllegalArgumentException e) {
                throw new BadRequestException(e);
            }
            final TSUIDQuery tsuid_query = new TSUIDQuery(tsdb, metric, tags);
            try {
                final List<TSMeta> tsmetas = tsuid_query.getTSMetas().joinUninterruptibly();
                query.sendReply(query.serializer().formatTSMetaListV1(tsmetas));
            } catch (NoSuchUniqueName e) {
                throw new BadRequestException(HttpResponseStatus.NOT_FOUND, "Unable to find one of the UIDs", e);
            } catch (BadRequestException e) {
                throw e;
            } catch (RuntimeException e) {
                throw new BadRequestException(e);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    // POST / PUT
    } else if (method == HttpMethod.POST || method == HttpMethod.PUT) {
        final TSMeta meta;
        if (query.hasContent()) {
            meta = query.serializer().parseTSMetaV1();
        } else {
            meta = this.parseTSMetaQS(query);
        }
        /**
       * Storage callback used to determine if the storage call was successful
       * or not. Also returns the updated object from storage.
       */
        class SyncCB implements Callback<Deferred<TSMeta>, Boolean> {

            @Override
            public Deferred<TSMeta> call(Boolean success) throws Exception {
                if (!success) {
                    throw new BadRequestException(HttpResponseStatus.INTERNAL_SERVER_ERROR, "Failed to save the TSMeta to storage", "This may be caused by another process modifying storage data");
                }
                return TSMeta.getTSMeta(tsdb, meta.getTSUID());
            }
        }
        if (meta.getTSUID() == null || meta.getTSUID().isEmpty()) {
            // we got a JSON object without TSUID. Try to find a timeseries spec of
            // the form "m": "metric{tagk=tagv,...}"
            final String metric = query.getRequiredQueryStringParam("m");
            final boolean create = query.getQueryStringParam("create") != null && query.getQueryStringParam("create").equals("true");
            final String tsuid = getTSUIDForMetric(metric, tsdb);
            class WriteCounterIfNotPresentCB implements Callback<Boolean, Boolean> {

                @Override
                public Boolean call(Boolean exists) throws Exception {
                    if (!exists && create) {
                        final PutRequest put = new PutRequest(tsdb.metaTable(), UniqueId.stringToUid(tsuid), TSMeta.FAMILY(), TSMeta.COUNTER_QUALIFIER(), Bytes.fromLong(0));
                        tsdb.getClient().put(put);
                    }
                    return exists;
                }
            }
            try {
                // Check whether we have a TSMeta stored already
                final boolean exists = TSMeta.metaExistsInStorage(tsdb, tsuid).joinUninterruptibly();
                // set TSUID
                meta.setTSUID(tsuid);
                if (!exists && create) {
                    // Write 0 to counter column if not present
                    TSMeta.counterExistsInStorage(tsdb, UniqueId.stringToUid(tsuid)).addCallback(new WriteCounterIfNotPresentCB()).joinUninterruptibly();
                    // set TSUID
                    final Deferred<TSMeta> process_meta = meta.storeNew(tsdb).addCallbackDeferring(new SyncCB());
                    final TSMeta updated_meta = process_meta.joinUninterruptibly();
                    tsdb.indexTSMeta(updated_meta);
                    tsdb.processTSMetaThroughTrees(updated_meta);
                    query.sendReply(query.serializer().formatTSMetaV1(updated_meta));
                } else if (exists) {
                    final Deferred<TSMeta> process_meta = meta.syncToStorage(tsdb, method == HttpMethod.PUT).addCallbackDeferring(new SyncCB());
                    final TSMeta updated_meta = process_meta.joinUninterruptibly();
                    tsdb.indexTSMeta(updated_meta);
                    query.sendReply(query.serializer().formatTSMetaV1(updated_meta));
                } else {
                    throw new BadRequestException("Could not find TSMeta, specify \"create=true\" to create a new one.");
                }
            } catch (IllegalStateException e) {
                query.sendStatusOnly(HttpResponseStatus.NOT_MODIFIED);
            } catch (IllegalArgumentException e) {
                throw new BadRequestException(e);
            } catch (BadRequestException e) {
                throw e;
            } catch (NoSuchUniqueName e) {
                // the timeseries meta data
                throw new BadRequestException(HttpResponseStatus.NOT_FOUND, "Unable to find one or more UIDs", e);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            try {
                final Deferred<TSMeta> process_meta = meta.syncToStorage(tsdb, method == HttpMethod.PUT).addCallbackDeferring(new SyncCB());
                final TSMeta updated_meta = process_meta.joinUninterruptibly();
                tsdb.indexTSMeta(updated_meta);
                query.sendReply(query.serializer().formatTSMetaV1(updated_meta));
            } catch (IllegalStateException e) {
                query.sendStatusOnly(HttpResponseStatus.NOT_MODIFIED);
            } catch (IllegalArgumentException e) {
                throw new BadRequestException(e);
            } catch (NoSuchUniqueName e) {
                // the timeseries meta data
                throw new BadRequestException(HttpResponseStatus.NOT_FOUND, "Unable to find one or more UIDs", e);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    // DELETE  
    } else if (method == HttpMethod.DELETE) {
        final TSMeta meta;
        if (query.hasContent()) {
            meta = query.serializer().parseTSMetaV1();
        } else {
            meta = this.parseTSMetaQS(query);
        }
        try {
            meta.delete(tsdb);
            tsdb.deleteTSMeta(meta.getTSUID());
        } catch (IllegalArgumentException e) {
            throw new BadRequestException("Unable to delete TSMeta information", e);
        }
        query.sendStatusOnly(HttpResponseStatus.NO_CONTENT);
    } else {
        throw new BadRequestException(HttpResponseStatus.METHOD_NOT_ALLOWED, "Method not allowed", "The HTTP method [" + method.getName() + "] is not permitted for this endpoint");
    }
}
Also used : HashMap(java.util.HashMap) Deferred(com.stumbleupon.async.Deferred) TSMeta(net.opentsdb.meta.TSMeta) PutRequest(org.hbase.async.PutRequest) IOException(java.io.IOException) HttpMethod(org.jboss.netty.handler.codec.http.HttpMethod) TSUIDQuery(net.opentsdb.meta.TSUIDQuery) NoSuchUniqueName(net.opentsdb.uid.NoSuchUniqueName)

Example 17 with PutRequest

use of org.hbase.async.PutRequest 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!
}
Also used : PutRequest(org.hbase.async.PutRequest) HBaseException(org.hbase.async.HBaseException) DeleteRequest(org.hbase.async.DeleteRequest) HBaseException(org.hbase.async.HBaseException)

Aggregations

PutRequest (org.hbase.async.PutRequest)17 Callback (com.stumbleupon.async.Callback)11 HashMap (java.util.HashMap)10 Map (java.util.Map)8 IOException (java.io.IOException)5 TreeMap (java.util.TreeMap)5 Deferred (com.stumbleupon.async.Deferred)4 ArrayList (java.util.ArrayList)4 HBaseException (org.hbase.async.HBaseException)4 JSONException (net.opentsdb.utils.JSONException)2 AppendRequest (org.hbase.async.AppendRequest)2 DeleteRequest (org.hbase.async.DeleteRequest)2 KeyValue (org.hbase.async.KeyValue)2 ByteArrayByteIterator (com.yahoo.ycsb.ByteArrayByteIterator)1 ByteIterator (com.yahoo.ycsb.ByteIterator)1 DBException (com.yahoo.ycsb.DBException)1 BufferedReader (java.io.BufferedReader)1 TreeSet (java.util.TreeSet)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Cell (net.opentsdb.core.Internal.Cell)1