Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement MetricDataApi.addData()

  • Loading branch information...
commit 73d9a27078313fecc5af667e39d097eca453c073 1 parent 9abea1c
Ryan Morgan authored
View
2  ChangeLog
@@ -1,6 +1,8 @@
Changes in HQApi 3.0
+ *) [HHQ-3216] Implement MetricDataApi.addData()
+
*) [HHQ-3216] Revamp metricData CLI command to allow metrics to be pulled
for a single resource in addition to metrics. Allow different time
windows to be specified and format output in human readable form rather
View
45 hqu/hqapi1/app/MetricdataController.groovy
@@ -1,5 +1,8 @@
import org.hyperic.hq.hqapi1.ErrorCode;
+import org.hyperic.hq.measurement.server.session.MeasurementStartupListener as MListener
+import org.hyperic.hq.measurement.server.session.DataPoint as DP
+
class MetricdataController extends ApiController {
private Closure getMetricDataXML(r) {
@@ -39,14 +42,18 @@ class MetricdataController extends ApiController {
*/
private Closure validateParameters(metricIds, start, end) {
- if (!start) {
+ if (start == null) {
return getFailureXML(ErrorCode.INVALID_PARAMETERS,
"Start time not given")
}
- if (!end) {
+ if (end == null) {
return getFailureXML(ErrorCode.INVALID_PARAMETERS,
"End time not given")
}
+ if (start < 0) {
+ return getFailureXML(ErrorCode.INVALID_PARAMETERS,
+ "Start time must be >= 0")
+ }
if (end < start) {
return getFailureXML(ErrorCode.INVALID_PARAMETERS,
"End time cannot be < start time")
@@ -212,10 +219,42 @@ class MetricdataController extends ApiController {
}
def put(params) {
+ def inserter = MListener.dataInserter
+ def failureXml = null
+
+ def dataRequest = new XmlParser().parseText(getPostData())
+ def metricId = dataRequest.'@metricId'?.toInteger()
+
+ def metric = metricHelper.findMeasurementById(metricId)
+ if (!metric) {
+ failureXml = getFailureXML(ErrorCode.OBJECT_NOT_FOUND,
+ "Unable to find metric with id = " +
+ metricId)
+ } else {
+ def points = []
+ for (dp in dataRequest["DataPoint"]) {
+ long ts = dp.'@timestamp'?.toLong()
+ double val = dp.'@value'?.toDouble()
+ points << new DP(metricId, val, ts)
+ }
+ log.info("Inserting " + points.size() + " metrics for " + metric.template.name)
+ try {
+ inserter.insertMetrics(points)
+ } catch (Exception e) {
+ failureXml = getFailureXML(ErrorCode.UNEXPECTED_ERROR,
+ "Error inserting metrics: " +
+ e.getMessage())
+ log.warn("Error inserting metrics", e)
+ }
+ }
renderXml() {
StatusResponse() {
- out << getFailureXML(ErrorCode.NOT_IMPLEMENTED);
+ if (failureXml) {
+ out << failureXml
+ } else {
+ out << getSuccessXML()
+ }
}
}
}
View
123 src/org/hyperic/hq/hqapi1/test/MetricDataAddData_test.java
@@ -2,15 +2,25 @@
import org.hyperic.hq.hqapi1.MetricApi;
import org.hyperic.hq.hqapi1.MetricDataApi;
+import org.hyperic.hq.hqapi1.ResourceApi;
import org.hyperic.hq.hqapi1.types.Resource;
import org.hyperic.hq.hqapi1.types.MetricsResponse;
import org.hyperic.hq.hqapi1.types.Metric;
import org.hyperic.hq.hqapi1.types.DataPoint;
import org.hyperic.hq.hqapi1.types.StatusResponse;
+import org.hyperic.hq.hqapi1.types.Agent;
+import org.hyperic.hq.hqapi1.types.ResourcePrototypeResponse;
+import org.hyperic.hq.hqapi1.types.ResourcePrototype;
+import org.hyperic.hq.hqapi1.types.ResourcesResponse;
+import org.hyperic.hq.hqapi1.types.ResourceResponse;
+import org.hyperic.hq.hqapi1.types.MetricResponse;
+import org.hyperic.hq.hqapi1.types.MetricDataResponse;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
+import java.util.Map;
+import java.util.HashMap;
public class MetricDataAddData_test extends MetricDataTestBase {
@@ -18,29 +28,116 @@ public MetricDataAddData_test(String name) {
super(name);
}
- public void testAddData() throws Exception {
+ public void testAddDataSinglePoint() throws Exception {
- MetricApi api = getApi().getMetricApi();
+ ResourceApi resourceApi = getApi().getResourceApi();
+ MetricApi metricApi = getApi().getMetricApi();
MetricDataApi dataApi = getApi().getMetricDataApi();
+ Agent a = getRunningAgent();
- Resource platform = getLocalPlatformResource(false, false);
- MetricsResponse metricsResponse = api.getMetrics(platform, true);
+ // Find HTTP resource type
+ ResourcePrototypeResponse protoResponse =
+ resourceApi.getResourcePrototype("HTTP");
+ hqAssertSuccess(protoResponse);
+ ResourcePrototype pt = protoResponse.getResourcePrototype();
+
+ // Find local platform
+ ResourcesResponse resourcesResponse =
+ resourceApi.getResources(a, false, false);
+ hqAssertSuccess(resourcesResponse);
+ assertTrue("Did not find a single platform for " + a.getAddress() + ":" +
+ a.getPort(), resourcesResponse.getResource().size() == 1);
+ Resource platform = resourcesResponse.getResource().get(0);
+
+ // Configure service
+ Map<String,String> params = new HashMap<String,String>();
+ params.put("hostname", "www.hyperic.com");
+ params.put("port", "80");
+ params.put("sotimeout", "10");
+ params.put("path", "/");
+ params.put("method", "GET");
+
+ Random r = new Random();
+ String name = "My HTTP Check " + r.nextInt();
+
+ ResourceResponse resp = resourceApi.createService(pt, platform,
+ name, params);
+ hqAssertSuccess(resp);
+ Resource createdResource = resp.getResource();
+ assertEquals(createdResource.getName(), name);
+
+ try {
+ // HQ does not like it when resources are modified so quickly
+ // after being created.
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+
+ MetricsResponse metricsResponse =
+ metricApi.getMetrics(createdResource, true);
hqAssertSuccess(metricsResponse);
- assertTrue("No metrics found for " + platform.getName(),
+ assertTrue("No metrics found for " + createdResource.getName(),
metricsResponse.getMetric().size() > 0);
- Metric m = metricsResponse.getMetric().get(0);
+ Metric m = null;
+ for (Metric metric : metricsResponse.getMetric()) {
+ if (!metric.getMetricTemplate().getName().equals("Availability")) {
+ m = metric;
+ break;
+ }
+ }
+
+ assertNotNull("Unable to find suitible metric for " +
+ createdResource.getName(), m);
+ // Insert slightly into the past to avoid collisions with
+ // current data.
+ long ts = System.currentTimeMillis() - (60 * 1000);
List<DataPoint> dps = new ArrayList<DataPoint>();
- Random r = new Random();
- for (int i = 1; i < 100; i++) {
- DataPoint dp = new DataPoint();
- dp.setTimestamp(i);
- dp.setValue(r.nextDouble());
- dps.add(dp);
+ DataPoint dp = new DataPoint();
+ dp.setTimestamp(ts);
+ dp.setValue(10000.0);
+ dps.add(dp);
+
+ StatusResponse insertResponse = dataApi.addData(m, dps);
+ hqAssertSuccess(insertResponse);
+
+ // BatchInserter only inserts once every 10 seconds.
+ try {
+ Thread.sleep(10000);
+ } catch (Exception e) {
+ // Ignore
}
+ // Validate we can pull the metrics back out
+ MetricDataResponse metricDataResponse = dataApi.getData(m, ts - 60000,
+ ts + 60000);
+ hqAssertSuccess(metricDataResponse);
+ assertTrue("Invalid number of data points found, expected 1 found " +
+ metricDataResponse.getMetricData().getDataPoint().size(),
+ metricDataResponse.getMetricData().getDataPoint().size() == 1);
+
+ DataPoint insertedPoint = metricDataResponse.getMetricData().getDataPoint().get(0);
+
+ assertEquals("Timestamps don't match", insertedPoint.getTimestamp(),
+ dp.getTimestamp());
+ assertEquals("Values don't match", dp.getValue(), dp.getValue());
+
+ // Clean up
+ StatusResponse deleteResponse = resourceApi.deleteResource(createdResource.getId());
+ hqAssertSuccess(deleteResponse);
+ }
+
+ public void testAddDataInvalidMetric() throws Exception {
+
+ MetricDataApi dataApi = getApi().getMetricDataApi();
+
+ List<DataPoint> dps = new ArrayList<DataPoint>();
+ Metric m = new Metric();
+ m.setId(Integer.MAX_VALUE);
+
StatusResponse response = dataApi.addData(m, dps);
- hqAssertFailureNotImplemented(response);
+ hqAssertFailureObjectNotFound(response);
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.