package org.rhq.plugins.test.measurement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.concurrent.CountDownLatch;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
public class BZ834019ResourceComponent implements ResourceComponent<ResourceComponent<?>>, MeasurementFacet {
public class CollectedMetric {
public String metricName;
public long collectedTime; // the collected time as relative to initialCollectionTime
public long finishedTime; // the time when the getValues returned relative to initialCollectionTime
}
public CountDownLatch latch;
public long initialCollectionTime = 0L;
public Vector<CollectedMetric> collectedMetrics = new Vector<CollectedMetric>(); // we want synchronized Vector
@Override
public AvailabilityType getAvailability() {
return AvailabilityType.UP;
}
@Override
public void start(ResourceContext<ResourceComponent<?>> context) throws Exception {
}
@Override
public void stop() {
}
@Override
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
boolean doSleep = false;
if (initialCollectionTime == 0L) {
initialCollectionTime = System.currentTimeMillis();
doSleep = true;
latch = new CountDownLatch(1); // so the rest of our collections will wait for our sleep to finish
}
ArrayList<CollectedMetric> thisCollection = new ArrayList<CollectedMetric>();
long now = System.currentTimeMillis() - initialCollectionTime;
for (Iterator<MeasurementScheduleRequest> i = metrics.iterator(); i.hasNext();) {
MeasurementScheduleRequest metric = i.next();
log("collecting metric " + (metric.getName() + " (interval=" + metric.getInterval() + ")"));
report.addData(new MeasurementDataNumeric(metric, new Double(1.0)));
// remember what time we were called and which metric was asked to be collected
CollectedMetric collectedMetric = new CollectedMetric();
collectedMetric.collectedTime = now;
collectedMetric.metricName = metric.getName();
collectedMetrics.add(collectedMetric);
thisCollection.add(collectedMetric);
}
// delay the initial collection a long time to push back collection of future metrics - we must ignore all interrupts!
if (doSleep) {
log("before sleep");
for (int i = 0; i < 91; i++) {
try {
Thread.sleep(1000);
} catch (Exception e) {
log("ignoring interrupt at second #" + i);
}
}
log("after sleep");
latch.countDown();
} else {
// don't let interrupts abort our wait - always wait for the countdown latch to open up
boolean shouldWait = true;
while (shouldWait) {
try {
log("before latch wait");
latch.await();
log("latch opened up");
shouldWait = false;
} catch (Exception e) {
log("latch wait interruptted, go back and wait...");
}
}
}
now = System.currentTimeMillis() - initialCollectionTime;
for (CollectedMetric collection : thisCollection) {
collection.finishedTime = now;
}
return;
}
private void log(String msg) {
//System.out.println("!!!!!!!!!!! " + this.getClass().getSimpleName() + ": " + new Date() + ": " + msg);
}
}