/*
* RHQ Management Platform
* Copyright (C) 2005-2008 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.plugins.perftest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.content.transfer.DeployPackagesResponse;
import org.rhq.core.domain.content.transfer.RemovePackagesResponse;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.ConfigurationUpdateStatus;
import org.rhq.core.domain.content.InstalledPackage;
import org.rhq.core.domain.content.PackageType;
import org.rhq.core.domain.content.transfer.DeployPackageStep;
import org.rhq.core.domain.content.transfer.ResourcePackageDetails;
import org.rhq.core.domain.event.Event;
import org.rhq.core.domain.event.EventSeverity;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.domain.measurement.calltime.CallTimeData;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.content.ContentFacet;
import org.rhq.core.pluginapi.content.ContentServices;
import org.rhq.core.pluginapi.event.EventContext;
import org.rhq.core.pluginapi.event.EventPoller;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
import org.rhq.core.pluginapi.inventory.ResourceComponent;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
import org.rhq.plugins.perftest.calltime.CalltimeFactory;
import org.rhq.plugins.perftest.configuration.SimpleConfigurationFactory;
import org.rhq.plugins.perftest.event.PerfTestEventPoller;
import org.rhq.plugins.perftest.measurement.MeasurementFactory;
import org.rhq.plugins.perftest.trait.TraitFactory;
import java.io.InputStream;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.Arrays;
/**
* RHQ resource component for handling resources defined in a performance test scenario.
*
* @author Jason Dobies
*/
public class PerfTestComponent implements ResourceComponent, MeasurementFacet, ContentFacet, ConfigurationFacet,
OperationFacet {
// Attributes --------------------------------------------
private Log log = LogFactory.getLog(PerfTestComponent.class);
private static final Random RANDOM = new Random();
private ResourceContext resourceContext;
private EventPoller eventPoller;
private Configuration resourceConfiguration;
private long getValuesDelay = 0L;
// ResourceComponent Implementation --------------------------------------------
public void start(ResourceContext context) throws InvalidPluginConfigurationException, Exception {
this.resourceContext = context;
startEventPollers();
ScenarioManager scenarioManager = ScenarioManager.getInstance();
if (!scenarioManager.isEnabled())
log.warn("[" + this.resourceContext.getResourceType().getName()
+ "] perftest Resources exist in inventory, but no Perf test scenario is enabled.");
String tmp = System.getProperty("rhq.perftest.getvaluesdelayms","0");
getValuesDelay = Long.parseLong(tmp);
}
public void stop() {
stopEventPollers();
}
public AvailabilityType getAvailability() {
return AvailabilityType.UP;
// TODO: Return DOWN once in a while?
}
// MeasurementFacet Implementation --------------------------------------------
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
ScenarioManager scenarioManager = ScenarioManager.getInstance();
if (!scenarioManager.isEnabled())
return;
String resourceTypeName = resourceContext.getResourceType().getName();
/* Currently this will use the same value generator for each metric defined for the resource type.
* In other words, you either get values for every metric defined for the resource type or for none. There may
* be an eventual need for finer grained control.
*
* jdobies, Jun 25, 2007
*/
MeasurementFactory measurementFactory = scenarioManager.getMeasurementFactory(resourceTypeName);
CalltimeFactory calltimeFactory = scenarioManager.getCalltimeFactory(resourceTypeName);
TraitFactory traitFactory = scenarioManager.getTraitFactory(resourceTypeName);
for (MeasurementScheduleRequest metric : metrics) {
switch (metric.getDataType()) {
case CALLTIME:
CallTimeData callTimeData = calltimeFactory.nextValue(metric);
if (callTimeData!=null) {
report.addData(callTimeData);
}
break;
case MEASUREMENT:
MeasurementDataNumeric measurementData = (MeasurementDataNumeric) measurementFactory.nextValue(metric);
if (measurementData != null) {
report.addData(measurementData);
}
break;
case TRAIT:
MeasurementDataTrait measurementDataTrait = traitFactory.nextValue(metric);
if (measurementDataTrait != null) {
report.addData(measurementDataTrait);
}
break;
case COMPLEX:
log.error("DataType " + metric.getDataType() + " not yet supported");
}
if (getValuesDelay>0) {
try {
Thread.sleep(getValuesDelay);
} catch (Exception e ) {
; // ignored
}
}
}
}
// ArtifactFacet Implementation --------------------------------------------
/*
* public Set<InstalledPackageDetails> getInstalledPackages(PackageType type) { ScenarioManager scenarioManager =
* ScenarioManager.getInstance(); ContentFactory factory =
* scenarioManager.getContentFactory(resourceContext.getResourceType().getName(), type.getName());
*
* Set<InstalledPackageDetails> contentDetails; if (factory != null) { contentDetails =
* factory.discoverContent(type); } else { contentDetails = new HashSet<InstalledPackageDetails>(); }
*
* return contentDetails; }
*/
public void installPackages(Set<InstalledPackage> packages, ContentServices contentServices) {
return;
}
public InputStream retrievePackageBits(InstalledPackage pkg) {
return null;
}
public List<DeployPackageStep> generateInstallationSteps(ResourcePackageDetails packageDetails) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public DeployPackagesResponse deployPackages(Set<ResourcePackageDetails> packages, ContentServices contentServices) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public RemovePackagesResponse removePackages(Set<ResourcePackageDetails> packages) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public Set<ResourcePackageDetails> discoverDeployedPackages(PackageType type) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public InputStream retrievePackageBits(ResourcePackageDetails packageDetails) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public OperationResult invokeOperation(String name, Configuration parameters)
throws InterruptedException, Exception {
if (name.equals("createEvents")) {
return createEvents(parameters);
} else {
// Sleep for a bit to simulate actually doing something.
Thread.sleep(500);
// Make roughly 1 out of 10 invocations fail.
if ((RANDOM.nextInt(10) % 9) == 0) {
throw new Exception("Operation failed!");
} else {
// Assume the operation returns an empty result config.
return new OperationResult();
}
}
}
private OperationResult createEvents(Configuration params) {
OperationResult result;
int count = params.getSimple("count").getIntegerValue();
String source = params.getSimple("source").getStringValue();
String details = params.getSimple("details").getStringValue();
String eventType = resourceContext.getResourceType().getName() + "-event";
String severityArg = params.getSimple("severity").getStringValue();
EventSeverity severity;
try {
severity = EventSeverity.valueOf(severityArg);
} catch (IllegalArgumentException e) {
result = new OperationResult("passed");
result.setErrorMessage(severityArg + " - illegal value for severity. Supported values are " +
Arrays.toString(EventSeverity.values()));
return result;
}
EventContext eventContext = resourceContext.getEventContext();
for (int i = 0; i < count; ++i) {
Event event = new Event(eventType, source, System.currentTimeMillis(), severity, details);
eventContext.publishEvent(event);
}
result = new OperationResult("failed");
return result;
}
private void startEventPollers() {
if (this.resourceContext.getEventContext() != null) {
String pollingIntervalString = System.getProperty(PerfTestEventPoller.SYSPROP_EVENTS_POLLING_INTERVAL);
if (pollingIntervalString != null) {
int pollingInterval;
try {
pollingInterval = Integer.parseInt(pollingIntervalString);
} catch (Exception e) {
pollingInterval = EventContext.MINIMUM_POLLING_INTERVAL;
}
eventPoller = new PerfTestEventPoller(resourceContext);
this.resourceContext.getEventContext().registerEventPoller(eventPoller, pollingInterval);
}
}
}
private void stopEventPollers() {
if (this.resourceContext.getEventContext() != null) {
if (eventPoller != null) {
this.resourceContext.getEventContext().unregisterEventPoller(eventPoller.getEventType());
}
}
}
public Configuration loadResourceConfiguration() throws Exception {
if (this.resourceConfiguration == null) {
SimpleConfigurationFactory configurationFactory = new SimpleConfigurationFactory();
this.resourceConfiguration = configurationFactory.generateConfiguration(
this.resourceContext.getResourceType().getResourceConfigurationDefinition());
}
return this.resourceConfiguration;
}
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
try
{
// Sleep for a bit to simulate the time it would take to parse and update an XML config file.
Thread.sleep(1000);
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
this.resourceConfiguration = report.getConfiguration();
report.setStatus(ConfigurationUpdateStatus.SUCCESS);
// TODO: Perhaps return FAILURE and INPROGRESS once in a while.
}
}