Search in sources :

Example 6 with IncomingDataPoint

use of net.opentsdb.core.IncomingDataPoint in project opentsdb by OpenTSDB.

the class TestTSUIDQuery method getLastPointMetricResolve.

@Test
public void getLastPointMetricResolve() throws Exception {
    Whitebox.setInternalState(config, "enable_tsuid_incrementing", false);
    Whitebox.setInternalState(config, "enable_realtime_ts", false);
    storage.flushStorage();
    tsdb.addPoint(METRIC_STRING, 1356998400L, 42, tags);
    PowerMockito.mockStatic(DateTime.class);
    PowerMockito.when(DateTime.currentTimeMillis()).thenReturn(1356998400000L);
    query = new TSUIDQuery(tsdb, METRIC_STRING, tags);
    final IncomingDataPoint dp = query.getLastPoint(true, 0).join();
    assertEquals(1356998400000L, dp.getTimestamp());
    assertEquals(METRIC_STRING, dp.getMetric());
    assertSame(tags, dp.getTags());
    assertEquals("42", dp.getValue());
    assertEquals(UniqueId.uidToString(TSUID), dp.getTSUID());
}
Also used : IncomingDataPoint(net.opentsdb.core.IncomingDataPoint) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) BaseTsdbTest(net.opentsdb.core.BaseTsdbTest) Test(org.junit.Test)

Example 7 with IncomingDataPoint

use of net.opentsdb.core.IncomingDataPoint in project opentsdb by OpenTSDB.

the class TestTSUIDQuery method getLastPointMetricZeroBackscanOnePoint.

@Test
public void getLastPointMetricZeroBackscanOnePoint() throws Exception {
    Whitebox.setInternalState(config, "enable_tsuid_incrementing", false);
    Whitebox.setInternalState(config, "enable_realtime_ts", false);
    storage.flushStorage();
    tsdb.addPoint(METRIC_STRING, 1356998400L, 42, tags);
    PowerMockito.mockStatic(DateTime.class);
    PowerMockito.when(DateTime.currentTimeMillis()).thenReturn(1356998400000L);
    query = new TSUIDQuery(tsdb, METRIC_STRING, tags);
    final IncomingDataPoint dp = query.getLastPoint(false, 0).join();
    assertEquals(1356998400000L, dp.getTimestamp());
    assertNull(dp.getMetric());
    assertNull(dp.getTags());
    assertEquals("42", dp.getValue());
    assertEquals(UniqueId.uidToString(TSUID), dp.getTSUID());
}
Also used : IncomingDataPoint(net.opentsdb.core.IncomingDataPoint) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) BaseTsdbTest(net.opentsdb.core.BaseTsdbTest) Test(org.junit.Test)

Example 8 with IncomingDataPoint

use of net.opentsdb.core.IncomingDataPoint in project opentsdb by OpenTSDB.

the class TestTSUIDQuery method getLastPointTSUIDOneBackscanInRange.

@Test
public void getLastPointTSUIDOneBackscanInRange() throws Exception {
    Whitebox.setInternalState(config, "enable_tsuid_incrementing", false);
    Whitebox.setInternalState(config, "enable_realtime_ts", false);
    storage.flushStorage();
    tsdb.addPoint(METRIC_STRING, 1356998400L, 42, tags);
    PowerMockito.mockStatic(DateTime.class);
    PowerMockito.when(DateTime.currentTimeMillis()).thenReturn(1357002000000L);
    query = new TSUIDQuery(tsdb, TSUID);
    final IncomingDataPoint dp = query.getLastPoint(false, 1).join();
    assertEquals(1356998400000L, dp.getTimestamp());
    assertNull(dp.getMetric());
    assertNull(dp.getTags());
    assertEquals("42", dp.getValue());
    assertEquals(UniqueId.uidToString(TSUID), dp.getTSUID());
}
Also used : IncomingDataPoint(net.opentsdb.core.IncomingDataPoint) PrepareForTest(org.powermock.core.classloader.annotations.PrepareForTest) BaseTsdbTest(net.opentsdb.core.BaseTsdbTest) Test(org.junit.Test)

Example 9 with IncomingDataPoint

use of net.opentsdb.core.IncomingDataPoint in project opentsdb by OpenTSDB.

the class PutDataPointRpc method execute.

/**
   * Handles HTTP RPC put requests
   * @param tsdb The TSDB to which we belong
   * @param query The HTTP query from the user
   * @throws IOException if there is an error parsing the query or formatting 
   * the output
   * @throws BadRequestException if the user supplied bad data
   * @since 2.0
   */
public void execute(final TSDB tsdb, final HttpQuery query) throws IOException {
    requests.incrementAndGet();
    // only accept POST
    if (query.method() != HttpMethod.POST) {
        throw new BadRequestException(HttpResponseStatus.METHOD_NOT_ALLOWED, "Method not allowed", "The HTTP method [" + query.method().getName() + "] is not permitted for this endpoint");
    }
    final List<IncomingDataPoint> dps = query.serializer().parsePutV1();
    if (dps.size() < 1) {
        throw new BadRequestException("No datapoints found in content");
    }
    final boolean show_details = query.hasQueryStringParam("details");
    final boolean show_summary = query.hasQueryStringParam("summary");
    final boolean synchronous = query.hasQueryStringParam("sync");
    final int sync_timeout = query.hasQueryStringParam("sync_timeout") ? Integer.parseInt(query.getQueryStringParam("sync_timeout")) : 0;
    // this is used to coordinate timeouts
    final AtomicBoolean sending_response = new AtomicBoolean();
    sending_response.set(false);
    final ArrayList<HashMap<String, Object>> details = show_details ? new ArrayList<HashMap<String, Object>>() : null;
    int queued = 0;
    final List<Deferred<Boolean>> deferreds = synchronous ? new ArrayList<Deferred<Boolean>>(dps.size()) : null;
    for (final IncomingDataPoint dp : dps) {
        /** Handles passing a data point to the storage exception handler if 
       * we were unable to store it for any reason */
        final class PutErrback implements Callback<Boolean, Exception> {

            public Boolean call(final Exception arg) {
                handleStorageException(tsdb, dp, arg);
                hbase_errors.incrementAndGet();
                if (show_details) {
                    details.add(getHttpDetails("Storage exception: " + arg.getMessage(), dp));
                }
                return false;
            }

            public String toString() {
                return "HTTP Put Exception CB";
            }
        }
        /** Simply marks the put as successful */
        final class SuccessCB implements Callback<Boolean, Object> {

            @Override
            public Boolean call(final Object obj) {
                return true;
            }

            public String toString() {
                return "HTTP Put success CB";
            }
        }
        try {
            if (dp.getMetric() == null || dp.getMetric().isEmpty()) {
                if (show_details) {
                    details.add(this.getHttpDetails("Metric name was empty", dp));
                }
                LOG.warn("Metric name was empty: " + dp);
                illegal_arguments.incrementAndGet();
                continue;
            }
            if (dp.getTimestamp() <= 0) {
                if (show_details) {
                    details.add(this.getHttpDetails("Invalid timestamp", dp));
                }
                LOG.warn("Invalid timestamp: " + dp);
                illegal_arguments.incrementAndGet();
                continue;
            }
            if (dp.getValue() == null || dp.getValue().isEmpty()) {
                if (show_details) {
                    details.add(this.getHttpDetails("Empty value", dp));
                }
                LOG.warn("Empty value: " + dp);
                invalid_values.incrementAndGet();
                continue;
            }
            if (dp.getTags() == null || dp.getTags().size() < 1) {
                if (show_details) {
                    details.add(this.getHttpDetails("Missing tags", dp));
                }
                LOG.warn("Missing tags: " + dp);
                illegal_arguments.incrementAndGet();
                continue;
            }
            final Deferred<Object> deferred;
            if (Tags.looksLikeInteger(dp.getValue())) {
                deferred = tsdb.addPoint(dp.getMetric(), dp.getTimestamp(), Tags.parseLong(dp.getValue()), dp.getTags());
            } else {
                deferred = tsdb.addPoint(dp.getMetric(), dp.getTimestamp(), Float.parseFloat(dp.getValue()), dp.getTags());
            }
            if (synchronous) {
                deferreds.add(deferred.addCallback(new SuccessCB()));
            }
            deferred.addErrback(new PutErrback());
            ++queued;
        } catch (NumberFormatException x) {
            if (show_details) {
                details.add(this.getHttpDetails("Unable to parse value to a number", dp));
            }
            LOG.warn("Unable to parse value to a number: " + dp);
            invalid_values.incrementAndGet();
        } catch (IllegalArgumentException iae) {
            if (show_details) {
                details.add(this.getHttpDetails(iae.getMessage(), dp));
            }
            LOG.warn(iae.getMessage() + ": " + dp);
            illegal_arguments.incrementAndGet();
        } catch (NoSuchUniqueName nsu) {
            if (show_details) {
                details.add(this.getHttpDetails("Unknown metric", dp));
            }
            LOG.warn("Unknown metric: " + dp);
            unknown_metrics.incrementAndGet();
        }
    }
    /** A timer task that will respond to the user with the number of timeouts
     * for synchronous writes. */
    class PutTimeout implements TimerTask {

        final int queued;

        public PutTimeout(final int queued) {
            this.queued = queued;
        }

        @Override
        public void run(final Timeout timeout) throws Exception {
            if (sending_response.get()) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Put data point call " + query + " already responded successfully");
                }
                return;
            } else {
                sending_response.set(true);
            }
            // figure out how many writes are outstanding
            int good_writes = 0;
            int failed_writes = 0;
            int timeouts = 0;
            for (int i = 0; i < deferreds.size(); i++) {
                try {
                    if (deferreds.get(i).join(1)) {
                        ++good_writes;
                    } else {
                        ++failed_writes;
                    }
                } catch (TimeoutException te) {
                    if (show_details) {
                        details.add(getHttpDetails("Write timedout", dps.get(i)));
                    }
                    ++timeouts;
                }
            }
            writes_timedout.addAndGet(timeouts);
            final int failures = dps.size() - queued;
            if (!show_summary && !show_details) {
                throw new BadRequestException(HttpResponseStatus.BAD_REQUEST, "The put call has timedout with " + good_writes + " successful writes, " + failed_writes + " failed writes and " + timeouts + " timed out writes.", "Please see the TSD logs or append \"details\" to the put request");
            } else {
                final HashMap<String, Object> summary = new HashMap<String, Object>();
                summary.put("success", good_writes);
                summary.put("failed", failures + failed_writes);
                summary.put("timeouts", timeouts);
                if (show_details) {
                    summary.put("errors", details);
                }
                query.sendReply(HttpResponseStatus.BAD_REQUEST, query.serializer().formatPutV1(summary));
            }
        }
    }
    // now after everything has been sent we can schedule a timeout if so
    // the caller asked for a synchronous write.
    final Timeout timeout = sync_timeout > 0 ? tsdb.getTimer().newTimeout(new PutTimeout(queued), sync_timeout, TimeUnit.MILLISECONDS) : null;
    /** Serializes the response to the client */
    class GroupCB implements Callback<Object, ArrayList<Boolean>> {

        final int queued;

        public GroupCB(final int queued) {
            this.queued = queued;
        }

        @Override
        public Object call(final ArrayList<Boolean> results) {
            if (sending_response.get()) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Put data point call " + query + " was marked as timedout");
                }
                return null;
            } else {
                sending_response.set(true);
                if (timeout != null) {
                    timeout.cancel();
                }
            }
            int good_writes = 0;
            int failed_writes = 0;
            for (final boolean result : results) {
                if (result) {
                    ++good_writes;
                } else {
                    ++failed_writes;
                }
            }
            final int failures = dps.size() - queued;
            if (!show_summary && !show_details) {
                if (failures + failed_writes > 0) {
                    query.sendReply(HttpResponseStatus.BAD_REQUEST, query.serializer().formatErrorV1(new BadRequestException(HttpResponseStatus.BAD_REQUEST, "One or more data points had errors", "Please see the TSD logs or append \"details\" to the put request")));
                } else {
                    query.sendReply(HttpResponseStatus.NO_CONTENT, "".getBytes());
                }
            } else {
                final HashMap<String, Object> summary = new HashMap<String, Object>();
                if (sync_timeout > 0) {
                    summary.put("timeouts", 0);
                }
                summary.put("success", results.isEmpty() ? queued : good_writes);
                summary.put("failed", failures + failed_writes);
                if (show_details) {
                    summary.put("errors", details);
                }
                if (failures > 0) {
                    query.sendReply(HttpResponseStatus.BAD_REQUEST, query.serializer().formatPutV1(summary));
                } else {
                    query.sendReply(query.serializer().formatPutV1(summary));
                }
            }
            return null;
        }

        @Override
        public String toString() {
            return "put data point serialization callback";
        }
    }
    /** Catches any unexpected exceptions thrown in the callback chain */
    class ErrCB implements Callback<Object, Exception> {

        @Override
        public Object call(final Exception e) throws Exception {
            if (sending_response.get()) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Put data point call " + query + " was marked as timedout");
                }
                return null;
            } else {
                sending_response.set(true);
                if (timeout != null) {
                    timeout.cancel();
                }
            }
            LOG.error("Unexpected exception", e);
            throw new RuntimeException("Unexpected exception", e);
        }

        @Override
        public String toString() {
            return "put data point error callback";
        }
    }
    if (synchronous) {
        Deferred.groupInOrder(deferreds).addCallback(new GroupCB(queued)).addErrback(new ErrCB());
    } else {
        new GroupCB(queued).call(EMPTY_DEFERREDS);
    }
}
Also used : HashMap(java.util.HashMap) Deferred(com.stumbleupon.async.Deferred) ArrayList(java.util.ArrayList) TimerTask(org.jboss.netty.util.TimerTask) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TimeoutException(com.stumbleupon.async.TimeoutException) Timeout(org.jboss.netty.util.Timeout) IncomingDataPoint(net.opentsdb.core.IncomingDataPoint) IncomingDataPoint(net.opentsdb.core.IncomingDataPoint) IOException(java.io.IOException) TimeoutException(com.stumbleupon.async.TimeoutException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Callback(com.stumbleupon.async.Callback) NoSuchUniqueName(net.opentsdb.uid.NoSuchUniqueName)

Example 10 with IncomingDataPoint

use of net.opentsdb.core.IncomingDataPoint in project opentsdb by OpenTSDB.

the class HttpJsonSerializer method parsePutV1.

/**
 * Parses one or more data points for storage
 * @return an array of data points to process for storage
 * @throws JSONException if parsing failed
 * @throws BadRequestException if the content was missing or parsing failed
 */
@Override
public List<IncomingDataPoint> parsePutV1() {
    if (!query.hasContent()) {
        throw new BadRequestException("Missing request content");
    }
    // convert to a string so we can handle character encoding properly
    final String content = query.getContent().trim();
    final int firstbyte = content.charAt(0);
    try {
        if (firstbyte == '{') {
            final IncomingDataPoint dp = JSON.parseToObject(content, IncomingDataPoint.class);
            final ArrayList<IncomingDataPoint> dps = new ArrayList<IncomingDataPoint>(1);
            dps.add(dp);
            return dps;
        } else {
            return JSON.parseToObject(content, TR_INCOMING);
        }
    } catch (IllegalArgumentException iae) {
        throw new BadRequestException("Unable to parse the given JSON", iae);
    }
}
Also used : ArrayList(java.util.ArrayList) IncomingDataPoint(net.opentsdb.core.IncomingDataPoint) DataPoint(net.opentsdb.core.DataPoint) RollUpDataPoint(net.opentsdb.rollup.RollUpDataPoint) IncomingDataPoint(net.opentsdb.core.IncomingDataPoint)

Aggregations

IncomingDataPoint (net.opentsdb.core.IncomingDataPoint)22 BaseTsdbTest (net.opentsdb.core.BaseTsdbTest)12 Test (org.junit.Test)12 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)12 HashMap (java.util.HashMap)7 ArrayList (java.util.ArrayList)5 RollUpDataPoint (net.opentsdb.rollup.RollUpDataPoint)5 Callback (com.stumbleupon.async.Callback)4 Deferred (com.stumbleupon.async.Deferred)3 IOException (java.io.IOException)3 TimeoutException (com.stumbleupon.async.TimeoutException)2 Map (java.util.Map)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 DataPoint (net.opentsdb.core.DataPoint)2 HistogramPojo (net.opentsdb.core.HistogramPojo)2 NoSuchUniqueName (net.opentsdb.uid.NoSuchUniqueName)2 HBaseException (org.hbase.async.HBaseException)2 Timeout (org.jboss.netty.util.Timeout)2 TimerTask (org.jboss.netty.util.TimerTask)2 DeferredGroupException (com.stumbleupon.async.DeferredGroupException)1