/*
* RHQ Management Platform
* Copyright (C) 2005-2013 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package org.rhq.plugins.jbossas5.test;
import static org.testng.Assert.fail;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import org.rhq.core.clientapi.agent.configuration.ConfigurationUpdateRequest;
import org.rhq.core.clientapi.agent.inventory.CreateResourceRequest;
import org.rhq.core.clientapi.agent.metadata.PluginMetadataManager;
import org.rhq.core.clientapi.agent.metadata.ResourceTypeNotEnabledException;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementDataTrait;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.pc.PluginContainer;
import org.rhq.core.pc.configuration.ConfigurationManager;
import org.rhq.core.pc.inventory.InventoryManager;
import org.rhq.core.pc.inventory.ResourceFactoryManager;
import org.rhq.core.pc.plugin.PluginManager;
import org.rhq.core.pc.util.ComponentUtil;
import org.rhq.core.pc.util.FacetLockType;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.measurement.MeasurementFacet;
import org.rhq.core.pluginapi.operation.OperationFacet;
import org.rhq.core.pluginapi.operation.OperationResult;
/**
* @author Ian Springer
* @author Lukas Krejci
*/
public abstract class AbstractResourceTest extends AbstractPluginTest {
private static final long MEASUREMENT_FACET_METHOD_TIMEOUT = 3000; // 3 seconds
private static final long OPERATION_FACET_METHOD_TIMEOUT = 3000; // 3 seconds
protected void testDiscovery() throws Exception {
Set<Resource> resources = getResources();
System.out.println("Found " + resources.size() + " " + getResourceType().getName() + " Resources.");
assert !resources.isEmpty();
}
@Deprecated
protected void testResourceCreation() throws Exception {
ResourceType resourceType = getResourceType();
if (!resourceType.isCreatable()) {
return;
}
if (resourceType.getCreationDataType() == ResourceCreationDataType.CONFIGURATION) {
ResourceFactoryManager resourceFactoryManager = PluginContainer.getInstance().getResourceFactoryManager();
new CreateResourceRequest(0, getServerResource().getId(), "My" + getResourceTypeName(),
getResourceTypeName(), getPluginName(), new Configuration(), getTestResourceConfiguration(), null);
//resourceFactoryManager.createResource();
} else {
// TODO
}
return;
}
protected void testMetrics() throws Exception {
if (supportsFacet(MeasurementFacet.class)) {
Set<MeasurementDefinition> metricDefinitions = getResourceType().getMetricDefinitions();
Set<Resource> resources = getResources();
for (Resource resource : resources) {
System.out.println("Validating metrics for " + resource + "...");
MeasurementFacet measurementFacet = ComponentUtil.getComponent(resource.getId(),
MeasurementFacet.class, FacetLockType.READ, MEASUREMENT_FACET_METHOD_TIMEOUT, true, true, true);
for (MeasurementDefinition metricDefinition : metricDefinitions) {
String name = metricDefinition.getName();
try {
DataType dataType = metricDefinition.getDataType();
if (dataType == DataType.MEASUREMENT || metricDefinition.getDataType() == DataType.TRAIT) {
MeasurementReport report = new MeasurementReport();
Set<MeasurementScheduleRequest> requests = new HashSet<MeasurementScheduleRequest>();
MeasurementScheduleRequest request = new MeasurementScheduleRequest(1, metricDefinition
.getName(), 0, true, metricDefinition.getDataType());
requests.add(request);
measurementFacet.getValues(report, requests);
if (dataType == DataType.MEASUREMENT) {
assert report.getNumericData().isEmpty() || report.getNumericData().size() == 1;
assert report.getTraitData().isEmpty();
assert report.getCallTimeData().isEmpty();
MeasurementDataNumeric dataNumeric = (report.getNumericData().isEmpty()) ? null
: report.getNumericData().iterator().next();
Double value = (dataNumeric != null) ? dataNumeric.getValue() : null;
System.out.println("Validating numeric metric '" + name + "' value (" + value + ")...");
validateNumericMetricValue(metricDefinition.getName(), value, resource);
} else if (metricDefinition.getDataType() == DataType.TRAIT) {
assert report.getTraitData().isEmpty() || report.getTraitData().size() == 1;
assert report.getNumericData().isEmpty();
assert report.getCallTimeData().isEmpty();
MeasurementDataTrait dataTrait = (report.getTraitData().size() == 1) ? report
.getTraitData().iterator().next() : null;
String value = (dataTrait != null) ? dataTrait.getValue() : null;
System.out.println("Validating trait '" + name + "' value (" + value + ")...");
validateTraitMetricValue(metricDefinition.getName(), value, resource);
}
}
} catch (Exception e) {
fail("Collection of metrics " + name + " for resource " + resource.getName() + " failed.", e);
}
}
}
}
return;
}
protected void testOperations() throws Exception {
Set<OperationDefinition> operationDefinitions = getResourceType().getOperationDefinitions();
Set<String> operationNames = new TreeSet<String>();
for (OperationDefinition operationDefinition : operationDefinitions) {
operationNames.add(operationDefinition.getName());
}
Set<Resource> resources = getResources();
testOperations(resources, operationNames);
}
protected void testOperations(Set<Resource> resources, Set<String> operationNames) throws Exception {
if (supportsFacet(OperationFacet.class)) {
//Set<OperationDefinition> operationDefinitions = getResourceType().getOperationDefinitions();
//Set<Resource> resources = getResources();
for (Resource resource : resources) {
System.out.println("Validating operations for " + resource + "...");
// TODO: Execute lifecycle operations in a specific order, so they don't break the other operations.
// For example, execute 'restart' first, followed by 'stop', followed by 'start'.
for (String name : operationNames) {
//we must get a new operation facet for each operation so that each operation gets
//the 3 seconds to finish. Otherwise all the operations would have to finish in 3 secs
//which can be a bit harsh limit.
OperationFacet operationFacet = ComponentUtil.getComponent(resource.getId(), OperationFacet.class,
FacetLockType.WRITE, OPERATION_FACET_METHOD_TIMEOUT, true, true, true);
//String name = operationDefinition.getName();
OperationResult result = operationFacet.invokeOperation(name, getTestOperationParameters(name));
System.out.println("Validating operation '" + name + "' result (" + result + ")...");
validateOperationResult(name, result, resource);
}
}
}
return;
}
protected void testResourceConfigLoad() throws Exception {
if (supportsFacet(ConfigurationFacet.class) && getResourceType().getResourceConfigurationDefinition() != null) {
ConfigurationManager configurationManager = PluginContainer.getInstance().getConfigurationManager();
Set<Resource> resources = getResources();
for (Resource resource : resources) {
try {
Configuration resourceConfig = configurationManager.loadResourceConfiguration(resource.getId());
// TODO: Validate the properties?
} catch (Exception e) {
throw new Exception("Failed to load Resource config for " + resource + ".", e);
}
}
}
return;
}
protected void testResourceConfigUpdate() throws Exception {
Set<Resource> resources = getResources();
testResourceConfigUpdate(resources);
}
protected void testResourceConfigUpdate(Set<Resource> resources) throws Exception {
if (supportsFacet(ConfigurationFacet.class) && getResourceType().getResourceConfigurationDefinition() != null) {
//Set<Resource> resources = getResources();
for (Resource resource : resources) {
try {
Configuration testResourceConfig = getTestResourceConfiguration();
Configuration resourceConfig = updateResourceConfiguration(resource, testResourceConfig);
assert resourceConfig.equals(testResourceConfig);
} catch (Exception e) {
throw new Exception("Failed to update Resource config for " + resource + ".", e);
}
}
}
return;
}
protected abstract String getResourceTypeName();
/**
* Used in {@link #testResourceCreation()} and {@link #testResourceConfigUpdate()}
* methods. The default implementation just throws UnsupportedOperationException.
*
* @return the configuration to be used to create or update a resource.
*/
protected Configuration getTestResourceConfiguration() {
throw new UnsupportedOperationException();
}
protected static Set<Resource> getResources(ResourceType resourceType) {
InventoryManager inventoryManager = PluginContainer.getInstance().getInventoryManager();
return inventoryManager.getResourcesWithType(resourceType);
}
protected Set<Resource> getResources() {
return getResources(getResourceType());
}
protected static ResourceType getResourceType(String resourceTypeName, String pluginName) {
PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
PluginMetadataManager pluginMetadataManager = pluginManager.getMetadataManager();
return pluginMetadataManager.getType(resourceTypeName, pluginName);
}
protected ResourceType getResourceType() {
return getResourceType(getResourceTypeName(), getPluginName());
}
@Deprecated
protected ResourceType getServerResource() {
PluginManager pluginManager = PluginContainer.getInstance().getPluginManager();
PluginMetadataManager pluginMetadataManager = pluginManager.getMetadataManager();
return pluginMetadataManager.getType("JBossAS Server", getPluginName());
}
protected Configuration getTestOperationParameters(String name) {
OperationDefinition operationDefinition = getOperationDefinition(name);
ConfigurationDefinition parametersConfigDef = operationDefinition.getParametersConfigurationDefinition();
if (parametersConfigDef == null || parametersConfigDef.getPropertyDefinitions().isEmpty()) {
return new Configuration();
} else {
// TODO: Return a Configuration auto-populated from the parameters ConfigurationDefinition.
throw new IllegalStateException();
}
}
protected void validateOperationResult(String name, OperationResult result, Resource resource) {
return;
}
protected void validateNumericMetricValue(String metricName, Double value, Resource resource) {
assert value != null;
}
protected void validateTraitMetricValue(String metricName, String value, Resource resource) {
assert value != null;
}
protected static Configuration updateResourceConfiguration(Resource resource, Configuration newConfiguration)
throws Exception {
ConfigurationManager configurationManager = PluginContainer.getInstance().getConfigurationManager();
ConfigurationUpdateRequest configurationUpdateRequest = new ConfigurationUpdateRequest(0, newConfiguration,
resource.getId());
configurationManager.updateResourceConfiguration(configurationUpdateRequest);
//give the component and the managed resource some time to properly persist the update
Thread.sleep(500);
return configurationManager.loadResourceConfiguration(resource.getId());
}
protected static Configuration loadResourceConfiguration(Resource resource) throws Exception {
ConfigurationManager configurationManager = PluginContainer.getInstance().getConfigurationManager();
return configurationManager.loadResourceConfiguration(resource.getId());
}
private OperationDefinition getOperationDefinition(String name) {
Set<OperationDefinition> operationDefinitions = getResourceType().getOperationDefinitions();
OperationDefinition matchingOperationDefinition = null;
for (OperationDefinition operationDefinition : operationDefinitions) {
if (operationDefinition.getName().equals(name)) {
matchingOperationDefinition = operationDefinition;
break;
}
}
return matchingOperationDefinition;
}
private boolean supportsFacet(Class<?> facetInterface) {
PluginMetadataManager manager = PluginContainer.getInstance().getPluginManager().getMetadataManager();
String componentClass;
try {
componentClass = manager.getComponentClass(getResourceType());
} catch (ResourceTypeNotEnabledException rtne) {
throw new RuntimeException(rtne);
}
try {
return facetInterface.isAssignableFrom(Class.forName(componentClass));
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Could not find component class " + componentClass, e);
}
}
}