diff options
Diffstat (limited to 'qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java')
-rw-r--r-- | qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java | 190 |
1 files changed, 181 insertions, 9 deletions
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java index ad9df793c8..e866effc54 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java @@ -20,36 +20,61 @@ */ package org.apache.qpid.server.virtualhostnode; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.AccessControlException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; + import org.apache.log4j.Logger; + +import org.apache.qpid.exchange.ExchangeDefaults; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.messages.ConfigStoreMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; import org.apache.qpid.server.model.AbstractConfiguredObject; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Exchange; import org.apache.qpid.server.model.LifetimePolicy; +import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.StateTransition; import org.apache.qpid.server.model.SystemConfig; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; +import org.apache.qpid.server.store.ConfiguredObjectRecord; +import org.apache.qpid.server.store.ConfiguredObjectRecordConverter; +import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; import org.apache.qpid.server.store.DurableConfigurationStore; - -import java.security.AccessControlException; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; +import org.apache.qpid.server.util.urlstreamhandler.data.Handler; public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<X>> extends AbstractConfiguredObject<X> implements VirtualHostNode<X> { - public static final String VIRTUALHOST_BLUEPRINT_CONTEXT_VAR = "virtualhostBlueprint"; - public static final String VIRTUALHOST_BLUEPRINT_UTILISED_CONTEXT_VAR = "virtualhostBlueprintUtilised"; private static final Logger LOGGER = Logger.getLogger(AbstractVirtualHostNode.class); + + static + { + Handler.register(); + } + private final Broker<?> _broker; private final AtomicReference<State> _state = new AtomicReference<State>(State.UNINITIALIZED); private final EventLogger _eventLogger; @@ -58,6 +83,9 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode< private MessageStoreLogSubject _configurationStoreLogSubject; + @ManagedAttributeField + private String _virtualHostInitialConfiguration; + public AbstractVirtualHostNode(Broker<?> parent, Map<String, Object> attributes) { super(Collections.<Class<? extends ConfiguredObject>,ConfiguredObject<?>>singletonMap(Broker.class, parent), @@ -241,8 +269,152 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode< } } + @Override + public String getVirtualHostInitialConfiguration() + { + return _virtualHostInitialConfiguration; + } + protected abstract DurableConfigurationStore createConfigurationStore(); protected abstract void activate(); + + + protected abstract ConfiguredObjectRecord enrichInitialVirtualHostRootRecord(final ConfiguredObjectRecord vhostRecord); + + protected final ConfiguredObjectRecord[] getInitialRecords() throws IOException + { + ConfiguredObjectRecordConverter converter = new ConfiguredObjectRecordConverter(getModel()); + + Collection<ConfiguredObjectRecord> records = + new ArrayList<>(converter.readFromJson(VirtualHost.class,this,getInitialConfigReader())); + + if(!records.isEmpty()) + { + ConfiguredObjectRecord vhostRecord = null; + for(ConfiguredObjectRecord record : records) + { + if(record.getType().equals(VirtualHost.class.getSimpleName())) + { + vhostRecord = record; + break; + } + } + if(vhostRecord != null) + { + records.remove(vhostRecord); + vhostRecord = enrichInitialVirtualHostRootRecord(vhostRecord); + records.add(vhostRecord); + } + else + { + // this should be impossible as the converter should always generate a parent record + throw new IllegalConfigurationException("Somehow the initial configuration has records but " + + "not a VirtualHost. This must be a coding error in Qpid"); + } + addStandardExchangesIfNecessary(records, vhostRecord); + enrichWithAuditInformation(records); + } + + + return records.toArray(new ConfiguredObjectRecord[records.size()]); + } + + private void enrichWithAuditInformation(final Collection<ConfiguredObjectRecord> records) + { + List<ConfiguredObjectRecord> replacements = new ArrayList<>(records.size()); + + for(ConfiguredObjectRecord record : records) + { + replacements.add(new ConfiguredObjectRecordImpl(record.getId(), record.getType(), + enrichAttributesWithAuditInformation(record.getAttributes()), + record.getParents())); + } + records.clear(); + records.addAll(replacements); + } + + private Map<String, Object> enrichAttributesWithAuditInformation(final Map<String, Object> attributes) + { + LinkedHashMap<String,Object> enriched = new LinkedHashMap<>(attributes); + final AuthenticatedPrincipal currentUser = org.apache.qpid.server.security.SecurityManager.getCurrentUser(); + + if(currentUser != null) + { + enriched.put(ConfiguredObject.LAST_UPDATED_BY, currentUser.getName()); + enriched.put(ConfiguredObject.CREATED_BY, currentUser.getName()); + } + long currentTime = System.currentTimeMillis(); + enriched.put(ConfiguredObject.LAST_UPDATED_TIME, currentTime); + enriched.put(ConfiguredObject.CREATED_TIME, currentTime); + + return enriched; + } + + private void addStandardExchangesIfNecessary(final Collection<ConfiguredObjectRecord> records, + final ConfiguredObjectRecord vhostRecord) + { + addExchangeIfNecessary(ExchangeDefaults.FANOUT_EXCHANGE_CLASS, ExchangeDefaults.FANOUT_EXCHANGE_NAME, records, vhostRecord); + addExchangeIfNecessary(ExchangeDefaults.HEADERS_EXCHANGE_CLASS, ExchangeDefaults.HEADERS_EXCHANGE_NAME, records, vhostRecord); + addExchangeIfNecessary(ExchangeDefaults.TOPIC_EXCHANGE_CLASS, ExchangeDefaults.TOPIC_EXCHANGE_NAME, records, vhostRecord); + addExchangeIfNecessary(ExchangeDefaults.DIRECT_EXCHANGE_CLASS, ExchangeDefaults.DIRECT_EXCHANGE_NAME, records, vhostRecord); + } + + private void addExchangeIfNecessary(final String exchangeClass, + final String exchangeName, + final Collection<ConfiguredObjectRecord> records, + final ConfiguredObjectRecord vhostRecord) + { + boolean found = false; + + for(ConfiguredObjectRecord record : records) + { + if(Exchange.class.getSimpleName().equals(record.getType()) + && exchangeName.equals(record.getAttributes().get(ConfiguredObject.NAME))) + { + found = true; + break; + } + } + + if(!found) + { + final Map<String, Object> exchangeAttributes = new HashMap<>(); + exchangeAttributes.put(ConfiguredObject.NAME, exchangeName); + exchangeAttributes.put(ConfiguredObject.TYPE, exchangeClass); + + records.add(new ConfiguredObjectRecordImpl(UUID.randomUUID(), Exchange.class.getSimpleName(), + exchangeAttributes, Collections.singletonMap(VirtualHost.class.getSimpleName(), vhostRecord.getId()))); + } + } + + protected final Reader getInitialConfigReader() throws IOException + { + Reader initialConfigReader; + if(getVirtualHostInitialConfiguration() != null) + { + String initialContextString = getVirtualHostInitialConfiguration(); + + + try + { + URL url = new URL(initialContextString); + + initialConfigReader =new InputStreamReader(url.openStream()); + } + catch (MalformedURLException e) + { + initialConfigReader = new StringReader(initialContextString); + } + + } + else + { + LOGGER.warn("No initial configuration found for the virtual host"); + initialConfigReader = new StringReader("{}"); + } + return initialConfigReader; + } + } |