Skip to content

Commit

Permalink
Implement MetricDataApi.addData()
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan Morgan committed Jul 30, 2009
1 parent 9abea1c commit 73d9a27
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 16 deletions.
2 changes: 2 additions & 0 deletions 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
Expand Down
45 changes: 42 additions & 3 deletions 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) {
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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()
}
}
}
}
Expand Down
123 changes: 110 additions & 13 deletions src/org/hyperic/hq/hqapi1/test/MetricDataAddData_test.java
Expand Up @@ -2,45 +2,142 @@

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 {

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);
}
}

0 comments on commit 73d9a27

Please sign in to comment.