package org.rhq.plugins.jbossas5;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import org.mc4j.ems.connection.EmsConnection;
import org.jboss.deployers.spi.management.ManagementView;
import org.jboss.managed.api.ManagedComponent;
import org.jboss.managed.api.ManagedDeployment;
import org.jboss.managed.api.ManagedObject;
import org.jboss.managed.api.ManagedOperation;
import org.jboss.managed.api.ManagedProperty;
import org.jboss.metatype.api.types.MetaType;
import org.jboss.metatype.api.values.MetaValue;
import org.jboss.profileservice.spi.NoSuchDeploymentException;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.measurement.AvailabilityType;
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.ResourceType;
import org.rhq.core.pluginapi.configuration.ConfigurationFacet;
import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport;
import org.rhq.core.pluginapi.inventory.CreateResourceReport;
import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException;
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.jbossas5.adapter.api.MeasurementAdapter;
import org.rhq.plugins.jbossas5.adapter.impl.measurement.SimpleMetaValueMeasurementAdapter;
import org.rhq.plugins.jbossas5.connection.ProfileServiceConnection;
import org.rhq.plugins.jbossas5.util.ConversionUtils;
import org.rhq.plugins.jbossas5.util.ResourceTypeUtils;
public class PlatformComponent implements ProfileServiceComponent<ProfileServiceComponent<?>>, MeasurementFacet,
OperationFacet, ConfigurationFacet {
private final Log log = LogFactory.getLog(this.getClass());
private ResourceContext<ProfileServiceComponent<?>> context;
private String deployName;
private String componentName;
public PlatformComponent() {
}
public void start(ResourceContext<ProfileServiceComponent<?>> context) throws InvalidPluginConfigurationException,
Exception {
this.context = context;
}
public void stop() {
return;
}
@NotNull
public ResourceContext<ProfileServiceComponent<?>> getResourceContext() {
return this.context;
}
public ProfileServiceConnection getConnection() {
ApplicationServerComponent component = (ApplicationServerComponent) context.getParentResourceComponent();
return component.getConnection();
}
public EmsConnection getEmsConnection() {
return context.getParentResourceComponent().getEmsConnection();
}
public CreateResourceReport createResource(CreateResourceReport report) {
// TODO Auto-generated method stub
return null;
}
// ------------ MeasurementFacet Implementation ------------
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests) {
try {
ManagedComponent component = loadComponent();
String[] propertyName;
for (MeasurementScheduleRequest request : requests) {
String metricName = request.getName();
propertyName = parsePropertyName(metricName);
if (propertyName.length == 0)
continue;
ManagedProperty prop = component.getProperties().get(propertyName[0]);
if (prop != null) {
MetaType type = prop.getMetaType();
MetaValue value = prop.getValue();
if (value != null) {
MeasurementDefinition measurementDefinition = ResourceTypeUtils.getMeasurementDefinition(
context.getResourceType(), metricName);
if (type.isSimple()) {
MeasurementAdapter measurementAdapter = new SimpleMetaValueMeasurementAdapter();
if (measurementDefinition != null & measurementAdapter != null)
measurementAdapter.setMeasurementData(report, value, request, measurementDefinition);
}
if (type.isComposite()) {
ManagedObject obj = prop.getManagedObject();
Object attachment = obj.getAttachment();
for (int i = 0; i < propertyName.length; i++) {
attachment = getObjectProperty(attachment, propertyName[i]);
}
setMeasurementData(report, attachment, request, measurementDefinition);
}
}
}
}
} catch (NoSuchDeploymentException e) {
log.error("Loaded component does not exist: " + e);
} catch (SecurityException e) {
log.error("Security Exception: " + e);
}
}
public Configuration loadResourceConfiguration() throws Exception {
// TODO Auto-generated method stub
return null;
}
public void updateResourceConfiguration(ConfigurationUpdateReport report) {
// TODO Auto-generated method stub
}
private ManagedComponent loadComponent() throws NoSuchDeploymentException {
deployName = context.getPluginConfiguration().getSimple(PlatformDiscoveryComponent.PLATFORM_DEPLOYMENT_NAME)
.getStringValue();
componentName = context.getPluginConfiguration().getSimple(PlatformDiscoveryComponent.PLATFORM_COMPONENT_NAME)
.getStringValue();
ProfileServiceConnection connection = context.getParentResourceComponent().getConnection();
ManagementView managementView = connection.getManagementView();
ManagedDeployment deploy = managementView.getDeployment(deployName);
if (deploy != null) {
Map<String, ManagedComponent> components = deploy.getComponents();
return components.get(componentName);
}
return null;
}
public AvailabilityType getAvailability() {
// TODO Auto-generated method stub
return null;
}
public String[] parsePropertyName(String name) {
String[] ps;
if (name.indexOf('{') == -1) {
ps = new String[1];
ps[0] = name;
return ps;
}
name = name.substring(name.indexOf('{') + 1, name.indexOf('}'));
ps = name.split("\\.");
return ps;
}
protected Object getObjectProperty(Object value, String property) {
try {
PropertyDescriptor[] pds = Introspector.getBeanInfo(value.getClass()).getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
if (pd.getName().equals(property)) {
pd.getReadMethod().setAccessible(true);
value = pd.getReadMethod().invoke(value);
}
}
} catch (Exception e) {
log.error("Object " + value.toString() + " does not contain property " + property, e);
}
return value;
}
public void setMeasurementData(MeasurementReport report, Object value, MeasurementScheduleRequest request,
MeasurementDefinition measurementDefinition) {
DataType dataType = measurementDefinition.getDataType();
switch (dataType) {
case MEASUREMENT:
try {
MeasurementDataNumeric dataNumeric = new MeasurementDataNumeric(request, new Double(value.toString()));
report.addData(dataNumeric);
} catch (NumberFormatException e) {
log.warn("Measurement request: " + request.getName()
+ " did not return a numeric value from the Profile Service", e);
}
break;
case TRAIT:
MeasurementDataTrait dataTrait = new MeasurementDataTrait(request, String.valueOf(value));
report.addData(dataTrait);
break;
default:
throw new IllegalStateException("Unsupported measurement data type: " + dataType);
}
}
public OperationResult invokeOperation(String name, Configuration parameters) throws InterruptedException,
Exception {
ResourceType resourceType = context.getResourceType();
OperationDefinition operationDefinition = ResourceTypeUtils.getOperationDefinition(resourceType, name);
ManagedComponent component = loadComponent();
Set<ManagedOperation> operations = component.getOperations();
for (ManagedOperation operation : operations) {
if (operation.getName().equals(name)) {
MetaValue[] params = ConversionUtils.convertOperationsParametersToMetaValues(operation, parameters,
operationDefinition);
MetaValue operationResult = operation.invoke(params);
OperationResult result = new OperationResult();
ConversionUtils.convertManagedOperationResults(operation, operationResult, result.getComplexResults(),
operationDefinition);
return result;
}
}
return null;
}
}