/* * Jopr 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, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also as published by the Free * Software Foundation. * * 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser 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.serviceBinding; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.managed.api.ManagedComponent; import org.jboss.managed.api.ManagedProperty; import org.jboss.metatype.api.types.MetaType; import org.jboss.metatype.api.values.CollectionValue; import org.jboss.metatype.api.values.CollectionValueSupport; import org.jboss.metatype.api.values.CompositeValue; import org.jboss.metatype.api.values.MetaValue; import org.jboss.metatype.api.values.SimpleValue; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.ConfigurationUpdateStatus; import org.rhq.core.domain.configuration.Property; import org.rhq.core.domain.configuration.PropertyList; import org.rhq.core.domain.configuration.PropertyMap; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.measurement.AvailabilityType; 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.pluginapi.configuration.ConfigurationFacet; import org.rhq.core.pluginapi.configuration.ConfigurationUpdateReport; import org.rhq.core.pluginapi.inventory.DeleteResourceFacet; 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.jbossas5.serviceBinding.Util.PropertyDefinition; public class SetComponent implements ResourceComponent<ManagerComponent>, ConfigurationFacet, DeleteResourceFacet, OperationFacet, MeasurementFacet { private final Log log = LogFactory.getLog(this.getClass()); private static final String BINDING_PROPERTY = "binding"; private static final String RESULTING_BINDINGS_PROPERTY = "resultingBindings"; private static final String DISPLAY_BINDINGS_OPERATION_NAME = "displayBindings"; private ResourceContext<ManagerComponent> context; public Configuration loadResourceConfiguration() throws Exception { Configuration configuration = new Configuration(); CompositeValue bindingSet = getBindingSet(); if (bindingSet == null) { throw new IllegalStateException("Could not find a binding set called " + context.getResourceKey()); } for (PropertySimple prop : Util.getProperties(Arrays.asList(Util.BINDING_SET_SIMPLE_PROPERTIES), bindingSet)) { configuration.put(prop); } CollectionValue overrideBindings = (CollectionValue) bindingSet.get(Util.OVERRIDE_BINDINGS_PROPERTY); PropertyList overrideBindingsList = new PropertyList(Util.OVERRIDE_BINDINGS_PROPERTY); configuration.put(overrideBindingsList); for (MetaValue m : overrideBindings.getElements()) { CompositeValue binding = (CompositeValue) m; PropertyMap bindingMap = new PropertyMap(BINDING_PROPERTY); overrideBindingsList.add(bindingMap); for (PropertySimple prop : Util.getProperties(Arrays.asList(Util.BINDING_SET_OVERRIDE_PROPERTIES), binding)) { bindingMap.put(prop); } } return configuration; } public void updateResourceConfiguration(ConfigurationUpdateReport report) { try { ManagerComponent managerResourceComponent = context.getParentResourceComponent(); ManagedComponent bindingManager = managerResourceComponent.getBindingManager(); Configuration updatedConfiguration = report.getConfiguration(); managerResourceComponent.checkValidity(updatedConfiguration); MetaType bindingSetValueMetaType = managerResourceComponent.getBindingSetValueMetaType(bindingManager); CompositeValue currentBindingSet = Util.getBindingSetFromConfiguration(bindingSetValueMetaType, updatedConfiguration); //ok, now we can update the bindingSets property with the update set of binding sets ManagedProperty bindingSetsProperty = bindingManager.getProperty(Util.BINDING_SETS_PROPERTY); String thisBindingSetName = managerResourceComponent.getBindingSetNameFromResourceKey(context.getResourceKey()); //create new set of binding sets CollectionValue bindingSets = (CollectionValue) bindingSetsProperty.getValue(); List<MetaValue> newBindingSets = Util.replaceWithNew(bindingSets, thisBindingSetName, currentBindingSet); CollectionValueSupport newBindingSetsValue = new CollectionValueSupport(bindingSets.getMetaType()); newBindingSetsValue.setElements(newBindingSets.toArray(new MetaValue[newBindingSets.size()])); bindingSetsProperty.setValue(newBindingSetsValue); context.getParentResourceComponent().updateBindingManager(bindingManager); report.setStatus(ConfigurationUpdateStatus.SUCCESS); } catch (Exception e) { log.warn("Failed to update service binding set", e); report.setErrorMessageFromThrowable(e); report.setStatus(ConfigurationUpdateStatus.FAILURE); } } public AvailabilityType getAvailability() { return getBindingSet() != null ? AvailabilityType.UP : AvailabilityType.DOWN; } public void start(ResourceContext<ManagerComponent> context) { this.context = context; } public void stop() { } public void deleteResource() throws Exception { //check that this binding set is not the active one String thisBindingSetName = context.getParentResourceComponent().getBindingSetNameFromResourceKey( context.getResourceKey()); ManagedComponent bindingManagerComponent = context.getParentResourceComponent().getBindingManager(); String activeBindingSetName = Util.getValue((SimpleValue) bindingManagerComponent.getProperty( Util.ACTIVE_BINDING_SET_NAME_PROPERTY).getValue(), String.class); if (thisBindingSetName.equals(activeBindingSetName)) { throw new IllegalStateException("Cannot delete currently active binding set."); } ManagedProperty bindingSetsProperty = bindingManagerComponent.getProperty(Util.BINDING_SETS_PROPERTY); //create new set of binding sets CollectionValue bindingSets = (CollectionValue) bindingSetsProperty.getValue(); List<MetaValue> newBindingSets = Util.replaceWithNew(bindingSets, thisBindingSetName, null); CollectionValueSupport newBindingSetsValue = new CollectionValueSupport(bindingSets.getMetaType()); newBindingSetsValue.setElements(newBindingSets.toArray(new MetaValue[newBindingSets.size()])); bindingSetsProperty.setValue(newBindingSetsValue); context.getParentResourceComponent().updateBindingManager(bindingManagerComponent); } public OperationResult invokeOperation(String name, Configuration parameters) throws InterruptedException, Exception { if (!DISPLAY_BINDINGS_OPERATION_NAME.equals(name)) return null; OperationResult result = new OperationResult(); Configuration currentConfiguration = loadResourceConfiguration(); Configuration bindingManagerConfiguration = context.getParentResourceComponent().loadResourceConfiguration(); Configuration bindings = result.getComplexResults(); //populate the resulting binding map so that the users have summary what the //the bindings would look like if this binding set was active. PropertyList resultingBindings = new PropertyList(RESULTING_BINDINGS_PROPERTY); bindings.put(resultingBindings); int portOffset = currentConfiguration.getSimple(Util.PORT_OFFSET_PROPERTY).getIntegerValue(); String defaultHostName = currentConfiguration.getSimple(Util.DEFAULT_HOST_NAME_PROPERTY).getStringValue(); Map<String, PropertyMap> overridesMap = buildOverridesMap(currentConfiguration.getList(Util.OVERRIDE_BINDINGS_PROPERTY)); for(Property p : bindingManagerConfiguration.getList(Util.STANDARD_BINDINGS_PROPERTY).getList()) { PropertyMap standardBinding = (PropertyMap) p; PropertyMap bindingMap = new PropertyMap(BINDING_PROPERTY); resultingBindings.add(bindingMap); for (PropertyDefinition def : Util.BINDING_SET_OVERRIDE_PROPERTIES) { Property equivalent = standardBinding.get(def.propertyName); if (equivalent != null) { bindingMap.put(equivalent); } } //now update the port and host name in the result boolean fixedPort = standardBinding.getSimple(Util.FIXED_PORT_PROPERTY).getBooleanValue(); boolean fixedHostName = standardBinding.getSimple(Util.FIXED_HOST_NAME_PROPERTY).getBooleanValue(); int standardPort = standardBinding.getSimple(Util.PORT_PROPERTY).getIntegerValue(); String standardHostName = standardBinding.getSimple(Util.HOST_NAME_PROPERTY).getStringValue(); PropertySimple resultingPort = bindingMap.getSimple(Util.PORT_PROPERTY); PropertySimple resultingHostName = bindingMap.getSimple(Util.HOST_NAME_PROPERTY); int portToSet = fixedPort ? standardPort : (standardPort + portOffset); String hostNameToSet = fixedHostName ? standardHostName : defaultHostName; //try to find an override for this binding String fullyQualifiedName = standardBinding.getSimpleValue(Util.FULLY_QUALIFIED_NAME_PROPERTY, null); PropertyMap override = overridesMap.get(fullyQualifiedName); if (override != null) { //remove this binding from overrides since we want to end up only //with the new additions in it after we process the standard bindings overridesMap.remove(fullyQualifiedName); //and get the resulting port and host name from the override instead portToSet = fixedPort ? portToSet : override.getSimple(Util.PORT_PROPERTY).getIntegerValue(); String overrideHostName = override.getSimpleValue(Util.HOST_NAME_PROPERTY, null); overrideHostName = overrideHostName == null ? defaultHostName : overrideHostName; hostNameToSet = fixedHostName ? hostNameToSet : overrideHostName; String overrideDescription = override.getSimpleValue(Util.DESCRIPTION_PROPERTY, null); if (overrideDescription != null) { bindingMap.put(new PropertySimple(Util.DESCRIPTION_PROPERTY, overrideDescription)); } } resultingPort.setIntegerValue(portToSet); resultingHostName.setStringValue(hostNameToSet); } for(PropertyMap override : overridesMap.values()) { if (override.getSimpleValue(Util.HOST_NAME_PROPERTY, null) == null) { override.put(new PropertySimple(Util.HOST_NAME_PROPERTY, defaultHostName)); } resultingBindings.add(override); } return result; } public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception { Configuration config = loadResourceConfiguration(); for (MeasurementScheduleRequest request : metrics) { String requestName = request.getName(); if (requestName.equals(Util.NAME_PROPERTY) || requestName.equals(Util.DEFAULT_HOST_NAME_PROPERTY) || requestName.equals(Util.PORT_OFFSET_PROPERTY)) { String value = config.getSimpleValue(requestName, null); report.addData(new MeasurementDataTrait(request, value)); } } } private CompositeValue getBindingSet() { String bindingSetName = context.getParentResourceComponent().getBindingSetNameFromResourceKey( context.getResourceKey()); ManagedComponent bindingManagerComponent = context.getParentResourceComponent().getBindingManager(); CollectionValue bindingSets = (CollectionValue) bindingManagerComponent.getProperty(Util.BINDING_SETS_PROPERTY) .getValue(); Iterator<MetaValue> it = bindingSets.iterator(); while (it.hasNext()) { CompositeValue bindingSet = (CompositeValue) it.next(); String currentName = Util.getValue(bindingSet, "name", String.class); if (bindingSetName.equals(currentName)) { return bindingSet; } } return null; } private Map<String, PropertyMap> buildOverridesMap(PropertyList overrides) { TreeMap<String, PropertyMap> ret = new TreeMap<String, PropertyMap>(); for(Property p : overrides.getList()) { PropertyMap overrideMap = (PropertyMap) p; ret.put(overrideMap.getSimpleValue(Util.FULLY_QUALIFIED_NAME_PROPERTY, null), overrideMap); } return ret; } }