/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.services.binding.managed; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.jboss.managed.api.annotation.ManagementComponent; import org.jboss.managed.api.annotation.ManagementObject; import org.jboss.managed.api.annotation.ManagementProperties; import org.jboss.managed.api.annotation.ManagementProperty; import org.jboss.managed.api.annotation.ViewUse; import org.jboss.metatype.api.annotations.MetaMapping; import org.jboss.services.binding.DuplicateServiceException; import org.jboss.services.binding.ServiceBinding; import org.jboss.services.binding.ServiceBindingManager; import org.jboss.services.binding.ServiceBindingMetadata; import org.jboss.services.binding.ServiceBindingStore; import org.jboss.services.binding.ServiceBindingValueSource; import org.jboss.services.binding.impl.PojoServiceBindingStore; import org.jboss.services.binding.impl.ServiceBindingSet; /** * Provide a management interface to the overall {@link ServiceBindingManager} system. * * @author Brian Stansberry * * @version $Revision: $ */ @ManagementObject(name="ServiceBindingManager", componentType=@ManagementComponent(type="MCBean", subtype="ServiceBindingManager"), properties=ManagementProperties.EXPLICIT, description="The ServiceBindingManager enables the centralized management of ports, by service.") public class ServiceBindingManagementObject { private final ServiceBindingManager bindingManager; private final PojoServiceBindingStore bindingStore; /** * Create a new ServiceBindingManager. * * @param serverName * @param bindingSets * @param standardBindings */ public ServiceBindingManagementObject(String serverName, Set<ServiceBindingSet> bindingSets, Set<ServiceBindingMetadata> standardBindings) { bindingStore = new PojoServiceBindingStore(bindingSets, standardBindings); bindingManager = new ServiceBindingManager(serverName, bindingStore); } public ServiceBindingManager getServiceBindingManager() { return bindingManager; } /** * Gets the value of the <code>serverName</code> param the <code>ServiceBindingManager</code> * should pass to <code>ServiceBindingStore</code> when * {@link ServiceBindingStore#getServiceBinding(String, String, String) requesting bindings}. * * @return name of the set of bindings this server uses */ @ManagementProperty(description="the name of the binding set the " + "ServiceBindingManager should use when resolving bindings", use={ViewUse.CONFIGURATION}, readOnly=false) public String getActiveBindingSetName() { return bindingManager.getServerName(); } /** * Sets the value of the <code>serverName</code> param the <code>ServiceBindingManager</code> * should pass to <code>ServiceBindingStore</code> when * {@link ServiceBindingStore#getServiceBinding(String, String, String) requesting bindings}. * * param name name of the set of bindings this server uses */ public void setActiveBindingSetName(String name) { bindingManager.setServerName(name); } @ManagementProperty(description="the set of service binding configurations associated with this instance", use={ViewUse.STATISTIC}, readOnly=true) @MetaMapping(value=ServiceBindingMapper.class) public Map<String, Set<ServiceBinding>> getServiceBindings() { Map<String, Set<ServiceBinding>> result = new HashMap<String, Set<ServiceBinding>>(); for (ServiceBindingSet set : getBindingSets()) { String name = set.getName(); result.put(name, bindingStore.getServiceBindings(name)); } return result; } /** * Gets the available {@link ServiceBindingSet}s. * * @return the binding sets. Will not return <code>null</code> */ @ManagementProperty(description="the named binding sets") @MetaMapping(ServiceBindingSetMapper.class) public Set<ServiceBindingSet> getBindingSets() { return bindingStore.getServiceBindingSets(); } /** * Sets the available {@link ServiceBindingSet}s. * * @param bindingSets the binding sets * @throws DuplicateServiceException * @throws UnknownHostException */ public void setBindingSets(Set<ServiceBindingSet> bindingSets) throws UnknownHostException, DuplicateServiceException { // The managed objects don't handle any configure value sources, so we need // to restore any existing ones restoreOverrideBindingValueSources(bindingSets); bindingStore.setServiceBindingSets(bindingSets); } /** * Gets the base set of bindings that should be associated with each binding set, * but with that binding set's {@link ServiceBindingSet#getPortOffset() port offset} * applied to the port value. * * @return the set of base bindings */ @ManagementProperty(description="the base set of bindings that should be associated " + "with each binding set") @MetaMapping(ServiceBindingMetadataMapper.class) public Set<ServiceBindingMetadata> getStandardBindings() { return bindingStore.getStandardBindings(); } /** * Sets the base set of bindings that should be associated with each binding set, * but with that binding set's {@link ServiceBindingSet#getPortOffset() port offset} * applied to the port value. * * @param bindings the set of base bindings * @throws DuplicateServiceException * @throws UnknownHostException */ public void setStandardBindings(Set<ServiceBindingMetadata> bindings) throws UnknownHostException, DuplicateServiceException { // The managed objects don't handle any configure value sources, so we need // to restore any existing ones restoreStandardBindingValueSources(bindings); bindingStore.setStandardBindings(bindings); } private void restoreStandardBindingValueSources(Set<ServiceBindingMetadata> bindings) { if (bindings != null) { Set<ServiceBindingMetadata> existing = bindingStore.getStandardBindings(); restoreServiceBindingValueSources(bindings, existing); } } private void restoreOverrideBindingValueSources(Set<ServiceBindingSet> bindingSets) { if (bindingSets != null) { Set<ServiceBindingSet> existingSets = bindingStore.getServiceBindingSets(); Map<String, Set<ServiceBindingMetadata>> byName = new HashMap<String, Set<ServiceBindingMetadata>>(); for (ServiceBindingSet set : existingSets) { byName.put(set.getName(), set.getOverrideBindings()); } for (ServiceBindingSet set : bindingSets) { restoreServiceBindingValueSources(set.getOverrideBindings(), byName.get(set.getName())); } } } private void restoreServiceBindingValueSources(Set<ServiceBindingMetadata> bindings, Set<ServiceBindingMetadata> existing) { if (bindings != null && existing != null) { Map<String, ServiceBindingMetadata> byFQN = new HashMap<String, ServiceBindingMetadata>(); for (ServiceBindingMetadata md : existing) { byFQN.put(md.getFullyQualifiedName(), md); } for (ServiceBindingMetadata newMD : bindings) { ServiceBindingMetadata old = byFQN.get(newMD.getFullyQualifiedName()); if (old != null) { ServiceBindingValueSource source = old.getServiceBindingValueSource(); if (source != null) { newMD.setServiceBindingValueSource(source); } else { String sourceClass = old.getServiceBindingValueSourceClassName(); if (sourceClass != null) { newMD.setServiceBindingValueSourceClassName(sourceClass); } } newMD.setServiceBindingValueSourceConfig(old.getServiceBindingValueSourceConfig()); } } } } // /** // * Add a ServiceBinding to all binding sets in the store. For each binding // * set, a new ServiceBinding is added whose serviceName and bindingName // * properties match the passed binding. If <the given <code>binding</code>'s // * <code>fixeHostName</code> property is <code>false</code>, the new binding's // * hostName matches the target set's {@link #getDefaultHostName(String) default host name}. // * If <code>binding</code>'s <code>fixedPort</code> property is <code>false</code>, // * the new binding's port is derived by taking the port from the passed binding // * and incrementing it by the target set's // * {@link #getDefaultPortOffset(String) default port offset}. // * // * @param serviceName the name of the service. Cannot be <code>null</code> // * @param bindingName name qualifier for the binding within the service. // * May be <code>null</code> // * @param description helpful description of the binding; may be <code>null</code> // * @param hostName hostname or IP address to which the binding should be // * bound. Often <code>null</code> since the host name typically // * comes from the default host name for each binding set // * @param port port the binding should use // * @param fixedHostName <code>true</code> if the binding's <code>hostName</code> // * should remain fixed when added to each binding set; // * <code>false</code> if it should be changed to the binding set's // * default host name // * @param fixedPort <code>true</code> if the binding's port should remain fixed // * when added to each binding set; <code>false</code> if it // * should be offset by the binding set's port offset // * // * @throws DuplicateServiceException thrown if a configuration for the // * <serverName, serviceName> pair already exists. // */ // @ManagementOperation(description="adds a service binding to all binding sets in the store", impact=Impact.WriteOnly, // params={@ManagementParameter(name="serviceName", // description="the name of the service; cannot be null"), // @ManagementParameter(name="bindingName", // description="name qualifier for the binding within the service; may be null"), // @ManagementParameter(name="description", // description="helpful description of the binding; may be null"), // @ManagementParameter(name="hostName", // description="hostname or IP address designating " + // "the interface to which the binding " + // "should be bound; Often null since the host name " + // "typically comes from the default host name for each binding set"), // @ManagementParameter(name="port", // description="port the binding should use"), // @ManagementParameter(name="fixedHostName", // description="true if the value of the hostName " + // "param must be respected; false if it " + // "can be altered to the default value " + // "for each binding set"), // @ManagementParameter(name="fixedPort", // description="true if the the binding's port " + // "should remain fixed when added to each " + // "binding set; false if it should be " + // "offset by the binding set's port offset")}) // public void addStandardBinding(String serviceName, String bindingName, String description, String hostName, int port, boolean fixedHostName, boolean fixedPort) // throws DuplicateServiceException, UnknownHostException // { // bindingStore.addServiceBinding(serviceName, bindingName, description, hostName, port, fixedHostName, fixedPort); // } // // /** // * Remove a service configuration from all binding sets in the store. // * // * @param serviceName the name of the service. Cannot be <code>null</code> // * @param bindingName name qualifier for the binding within the service. // * May be <code>null</code> // */ // @ManagementOperation(description="removes a service binding", impact=Impact.WriteOnly, // params={@ManagementParameter(name="serviceName"), // @ManagementParameter(name="bindingName")}) // public void removeStandardBinding(String serviceName, String bindingName) // { // bindingStore.removeServiceBinding(serviceName, bindingName); // } public void start() throws Exception { bindingStore.start(); } public void stop() throws Exception { bindingStore.stop(); } }