/* * RHQ Management Platform * Copyright (C) 2005-2009 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.jbossas5.util; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.Map; import java.util.HashMap; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.deployers.spi.management.KnownComponentTypes; import org.jboss.deployers.spi.management.KnownDeploymentTypes; import org.jboss.deployers.spi.management.ManagementView; import org.jboss.managed.api.ComponentType; import org.jboss.managed.api.ManagedComponent; import org.jboss.managed.api.ManagedDeployment; import org.jboss.profileservice.spi.NoSuchDeploymentException; import org.rhq.core.clientapi.descriptor.DescriptorPackages; import org.rhq.core.clientapi.descriptor.configuration.ConfigurationDescriptor; import org.rhq.core.clientapi.descriptor.configuration.SimpleProperty; import org.rhq.core.clientapi.descriptor.configuration.PropertyType; import org.rhq.core.clientapi.descriptor.configuration.ConfigurationProperty; import org.rhq.core.clientapi.descriptor.configuration.ListProperty; import org.rhq.core.clientapi.descriptor.configuration.MapProperty; import org.rhq.core.clientapi.descriptor.plugin.MetricDescriptor; import org.rhq.core.clientapi.descriptor.plugin.OperationDescriptor; import org.rhq.core.clientapi.descriptor.plugin.PluginDescriptor; import org.rhq.core.clientapi.descriptor.plugin.ResourceDescriptor; import org.rhq.core.clientapi.descriptor.plugin.ServiceDescriptor; import org.rhq.core.domain.configuration.definition.ConfigurationDefinition; import org.rhq.core.domain.configuration.definition.PropertyDefinition; import org.rhq.core.domain.configuration.definition.PropertySimpleType; import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple; import org.rhq.core.domain.configuration.definition.PropertyDefinitionList; import org.rhq.core.domain.configuration.definition.PropertyDefinitionMap; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.operation.OperationDefinition; import org.rhq.core.domain.resource.ResourceType; /** * Generates an RHQ plugin descriptor based on the ManagedComponent types represented in a Profile Service * ManagementView. * * @author Ian Springer */ public class PluginDescriptorGenerator { private static final Log LOG = LogFactory.getLog(PluginDescriptorGenerator.class); private static final QName SIMPLE_PROPERTY_QNAME = new QName(RhqNamespacePrefixMapper.CONFIGURATION_NAMESPACE, "simple-property"); private static final QName LIST_PROPERTY_QNAME = new QName(RhqNamespacePrefixMapper.CONFIGURATION_NAMESPACE, "list-property"); private static final QName MAP_PROPERTY_QNAME = new QName(RhqNamespacePrefixMapper.CONFIGURATION_NAMESPACE, "map-property"); private static Map<PropertySimpleType, PropertyType> TYPE_MAP = new HashMap(); static { TYPE_MAP.put(PropertySimpleType.BOOLEAN, PropertyType.BOOLEAN); TYPE_MAP.put(PropertySimpleType.DIRECTORY, PropertyType.DIRECTORY); TYPE_MAP.put(PropertySimpleType.DOUBLE, PropertyType.DOUBLE); TYPE_MAP.put(PropertySimpleType.FILE, PropertyType.FILE); TYPE_MAP.put(PropertySimpleType.FLOAT, PropertyType.FLOAT); TYPE_MAP.put(PropertySimpleType.INTEGER, PropertyType.INTEGER); TYPE_MAP.put(PropertySimpleType.LONG, PropertyType.LONG); TYPE_MAP.put(PropertySimpleType.LONG_STRING, PropertyType.LONG_STRING); TYPE_MAP.put(PropertySimpleType.PASSWORD, PropertyType.PASSWORD); TYPE_MAP.put(PropertySimpleType.STRING, PropertyType.STRING); } public static void generatePluginDescriptor(ManagementView managementView, File tempDir) throws Exception { PluginDescriptor pluginDescriptor = new PluginDescriptor(); addComponentsToDescriptor(managementView, pluginDescriptor); addDeploymentsToDescriptor(managementView, pluginDescriptor); File tempFile = File.createTempFile("rhq-plugin", ".xml", tempDir); writeToFile(pluginDescriptor, tempFile); } private static void addDeploymentsToDescriptor(ManagementView managementView, PluginDescriptor pluginDescriptor) throws Exception { Set<String> knownDeploymentTypeNames = getKnownDeploymentTypeNames(); for (String deploymentTypeName : knownDeploymentTypeNames) { Set<String> deploymentNames = managementView.getDeploymentNamesForType(deploymentTypeName); if (deploymentNames == null || deploymentNames.isEmpty()) { LOG.warn("No deployments of type [" + deploymentTypeName + "] found."); continue; } ManagedDeployment deployment = null; for (String deploymentName : deploymentNames) { try { // Use the first one we successfully retrieve as a representative sample of the type. deployment = managementView.getDeployment(deploymentName); break; } catch (NoSuchDeploymentException e) { LOG.warn(e); } } if (deployment == null) { LOG.warn("Unable to successfully retrieve a Deployment of type [" + deploymentTypeName + "] due to https://jira.jboss.org/jira/browse/JBAS-5640."); continue; } // First convert ManagedDeployment to ResourceType... ResourceType resourceType = MetadataConversionUtils.convertDeploymentToResourceType(deploymentTypeName, deployment); // Then convert ResourceType to JAXB ServiceDescriptor object. convertAndMergeResourceType(pluginDescriptor, resourceType); } } private static void addComponentsToDescriptor(ManagementView managementView, PluginDescriptor pluginDescriptor) throws Exception { Set<ComponentType> knownComponentTypes = getKnownComponentTypes(); for (ComponentType componentType : knownComponentTypes) { Set<ManagedComponent> components = managementView.getComponentsForType(componentType); if (components == null || components.isEmpty()) { LOG.warn("No components of type [" + componentType + "] found."); continue; } if (componentType.getSubtype().equals("*")) { for (ManagedComponent component : components) addComponentToDescriptor(pluginDescriptor, component); } else { // Use the first one as a representative sample of the type. ManagedComponent component = components.iterator().next(); addComponentToDescriptor(pluginDescriptor, component); } } } private static void addComponentToDescriptor(PluginDescriptor pluginDescriptor, ManagedComponent component) { // First convert ManagedComponent to ResourceType... ResourceType resourceType = MetadataConversionUtils.convertComponentToResourceType(component); // Then convert ResourceType to JAXB ServiceDescriptor object. convertAndMergeResourceType(pluginDescriptor, resourceType); } private static void convertAndMergeResourceType(PluginDescriptor pluginDescriptor, ResourceType resourceType) { List<ServiceDescriptor> services = pluginDescriptor.getServices(); ServiceDescriptor serviceDescriptor = new ServiceDescriptor(); serviceDescriptor.setName(resourceType.getName()); if (resourceType.isSingleton()) serviceDescriptor.setSingleton(resourceType.isSingleton()); // TODO: Handle remaining fields. convertAndMergeOperationDefinitions(resourceType, serviceDescriptor); convertAndMergeMetricDefinitions(resourceType, serviceDescriptor); convertAndMergeResourceConfiguration(resourceType, serviceDescriptor); services.add(serviceDescriptor); } private static void convertAndMergeResourceConfiguration(ResourceType resourceType, ServiceDescriptor serviceDescriptor) { ConfigurationDefinition resourceConfigDef = resourceType.getResourceConfigurationDefinition(); ConfigurationDescriptor resourceConfigDescriptor = convertConfigurationDefinitionToConfigurationDescriptor( resourceConfigDef); serviceDescriptor.setResourceConfiguration(resourceConfigDescriptor); } private static void convertAndMergeMetricDefinitions(ResourceType resourceType, ServiceDescriptor serviceDescriptor) { List<MetricDescriptor> metricDescriptors = serviceDescriptor.getMetric(); for (MeasurementDefinition metricDef : resourceType.getMetricDefinitions()) { MetricDescriptor metricDescriptor = new MetricDescriptor(); metricDescriptors.add(metricDescriptor); if (metricDef.getCategory() != null) metricDescriptor.setCategory(metricDef.getCategory().name().toLowerCase()); metricDescriptor.setDataType(metricDef.getDataType().name().toLowerCase()); metricDescriptor.setDefaultInterval((int)metricDef.getDefaultInterval()); metricDescriptor.setDefaultOn(metricDef.isDefaultOn()); metricDescriptor.setDescription(metricDef.getDescription()); metricDescriptor.setDestinationType(metricDef.getDestinationType()); metricDescriptor.setDisplayName(metricDef.getDisplayName()); if (metricDef.getDisplayType() != null) metricDescriptor.setDisplayType(metricDef.getDisplayType().name().toLowerCase()); if (metricDef.getNumericType() != null) metricDescriptor.setMeasurementType(metricDef.getNumericType().name().toLowerCase()); metricDescriptor.setProperty(metricDef.getName()); //metricDescriptor.setUnits(metricDef.getUnits()); // TODO } } private static void convertAndMergeOperationDefinitions(ResourceType resourceType, ResourceDescriptor resourceDescriptor) { List<OperationDescriptor> operationDescriptors = resourceDescriptor.getOperation(); for (OperationDefinition opDef : resourceType.getOperationDefinitions()) { OperationDescriptor operationDescriptor = new OperationDescriptor(); operationDescriptors.add(operationDescriptor); operationDescriptor.setDescription(opDef.getDescription()); operationDescriptor.setDisplayName(opDef.getDisplayName()); operationDescriptor.setName(opDef.getName()); ConfigurationDefinition paramsConfigDef = opDef.getParametersConfigurationDefinition(); ConfigurationDescriptor paramsConfigDescriptor = convertConfigurationDefinitionToConfigurationDescriptor(paramsConfigDef); operationDescriptor.setParameters(paramsConfigDescriptor); ConfigurationDefinition resultsConfigDef = opDef.getResultsConfigurationDefinition(); ConfigurationDescriptor resultsConfigDescriptor = convertConfigurationDefinitionToConfigurationDescriptor(resultsConfigDef); operationDescriptor.setResults(resultsConfigDescriptor); operationDescriptor.setTimeout(opDef.getTimeout()); } } private static ConfigurationDescriptor convertConfigurationDefinitionToConfigurationDescriptor( ConfigurationDefinition configDef) { if (configDef == null) return null; ConfigurationDescriptor configDescriptor = new ConfigurationDescriptor(); configDescriptor.setNotes(configDef.getDescription()); for (PropertyDefinition propDef : configDef.getPropertyDefinitions().values()) { ConfigurationProperty configProp = convertPropertyDefinitionToConfigurationProperty(propDef); JAXBElement propElement = getJAXBElement(configProp); configDescriptor.getConfigurationProperty().add(propElement); } return configDescriptor; } private static ConfigurationProperty convertPropertyDefinitionToConfigurationProperty(PropertyDefinition propDef) { ConfigurationProperty configProp; if (propDef instanceof PropertyDefinitionSimple) { PropertyDefinitionSimple propDefSimple = (PropertyDefinitionSimple)propDef; SimpleProperty simpleProp = new SimpleProperty(); simpleProp.setDefaultValue(propDefSimple.getDefaultValue()); simpleProp.setDefaultValueDescription(propDefSimple.getDefaultValue()); simpleProp.setInitialValue(propDefSimple.getDefaultValue()); if (propDefSimple.getType() != PropertySimpleType.STRING) simpleProp.setType(TYPE_MAP.get(propDefSimple.getType())); configProp = simpleProp; } else if (propDef instanceof PropertyDefinitionList) { PropertyDefinitionList propDefList = (PropertyDefinitionList)propDef; ListProperty listProp = new ListProperty(); //listProp.setMin(BigInteger.valueOf(propDefList.getMin())); //listProp.setMax(String.valueOf(propDefList.getMax())); ConfigurationProperty memberConfigProp = convertPropertyDefinitionToConfigurationProperty( propDefList.getMemberDefinition()); JAXBElement propElement = getJAXBElement(memberConfigProp); listProp.setConfigurationProperty(propElement); configProp = listProp; } else if (propDef instanceof PropertyDefinitionMap) { PropertyDefinitionMap propDefMap = (PropertyDefinitionMap)propDef; MapProperty mapProp = new MapProperty(); for (PropertyDefinition itemPropDef : propDefMap.getPropertyDefinitions().values()) { ConfigurationProperty itemConfigProp = convertPropertyDefinitionToConfigurationProperty(itemPropDef); JAXBElement propElement = getJAXBElement(itemConfigProp); mapProp.getConfigurationProperty().add(propElement); } configProp = mapProp; } else { throw new IllegalStateException("Invalid property definition type: " + propDef.getClass().getName()); } configProp.setDescription(propDef.getDescription()); //simpleProp.setActivationPolicy(propDefSimple.getActivationPolicy()); // TODO configProp.setName(propDef.getName()); //simpleProp.setPropertyOptions(); // TODO if (propDef.isReadOnly()) configProp.setReadOnly(propDef.isReadOnly()); if (!propDef.isRequired()) configProp.setRequired(propDef.isRequired()); if (propDef.isSummary()) configProp.setSummary(propDef.isSummary()); //simpleProp.setUnits(propDefSimple.getUnits()); // TODO return configProp; } private static JAXBElement<? extends ConfigurationProperty> getJAXBElement(ConfigurationProperty configProp) { JAXBElement<? extends ConfigurationProperty> propElement; QName qname; if (configProp instanceof SimpleProperty) qname = SIMPLE_PROPERTY_QNAME; else if (configProp instanceof ListProperty) qname = LIST_PROPERTY_QNAME; else if (configProp instanceof MapProperty) qname = MAP_PROPERTY_QNAME; else throw new IllegalStateException(); propElement = new JAXBElement(qname, configProp.getClass(), configProp); return propElement; } private static Set<String> getKnownDeploymentTypeNames() { Set<String> knownDeploymentTypeNames = new LinkedHashSet(); for (KnownDeploymentTypes type : KnownDeploymentTypes.values()) { knownDeploymentTypeNames.add(type.getType()); } return knownDeploymentTypeNames; } private static Set<ComponentType> getKnownComponentTypes() { Set<ComponentType> knownComponentTypes = new LinkedHashSet<ComponentType>(); for (KnownComponentTypes.DataSourceTypes componentType : KnownComponentTypes.DataSourceTypes.values()) { knownComponentTypes.add(componentType.getType()); } for (KnownComponentTypes.ConnectionFactoryTypes componentType : KnownComponentTypes.ConnectionFactoryTypes.values()) { knownComponentTypes.add(componentType.getType()); } // TODO: Remove the below line once we upgrade to profileservice-spi 5.1.0.CR2. knownComponentTypes.add(new ComponentType("ConnectionFactory", "Tx")); for (KnownComponentTypes.JMSDestination componentType : KnownComponentTypes.JMSDestination.values()) { knownComponentTypes.add(componentType.getType()); } for (KnownComponentTypes.EJB componentType : KnownComponentTypes.EJB.values()) { knownComponentTypes.add(componentType.getType()); } for (KnownComponentTypes.MBean componentType : KnownComponentTypes.MBean.values()) { knownComponentTypes.add(componentType.getType()); } knownComponentTypes.add(new ComponentType("MBean", "Platform")); knownComponentTypes.add(new ComponentType("MBean", "Web")); for (KnownComponentTypes.MCBean componentType : KnownComponentTypes.MCBean.values()) { knownComponentTypes.add(componentType.getType()); } knownComponentTypes.add(new ComponentType("MCBean", "JTA")); knownComponentTypes.add(new ComponentType("MCBean", "MCServer")); knownComponentTypes.add(new ComponentType("MCBean", "Security")); knownComponentTypes.add(new ComponentType("MCBean", "ServerConfig")); knownComponentTypes.add(new ComponentType("MCBean", "ServerInfo")); knownComponentTypes.add(new ComponentType("MCBean", "ServicebindingManager")); knownComponentTypes.add(new ComponentType("MCBean", "ServiceBindingSet")); knownComponentTypes.add(new ComponentType("MCBean", "ServicebindingStore")); return knownComponentTypes; } private static void writeToFile(PluginDescriptor pluginDescriptor, File file) throws Exception { LOG.info("Writing plugin descriptor to [" + file + "]..."); OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file)); JAXBContext jaxbContext = JAXBContext.newInstance(DescriptorPackages.PC_PLUGIN); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new RhqNamespacePrefixMapper()); marshaller.marshal(pluginDescriptor, outputStream); outputStream.close(); } }