/* * 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. } }