From ae1ccfdd01112311a9e9d0870928a0052578be8f Mon Sep 17 00:00:00 2001 From: Keith Wall Date: Sat, 26 Apr 2014 22:22:10 +0000 Subject: QPID-5715: [Java Broker]: Refactor VHN implementations to avoid duplicated code git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1590316 13f79535-47bb-0310-9956-ffa450edef68 --- .../berkeleydb/BDBHAVirtualHostNodeImpl.java | 218 ++-------------- .../VirtualHostStoreUpgraderAndRecoverer.java | 3 +- .../server/virtualhost/AbstractVirtualHost.java | 7 +- .../AbstractStandardVirtualHostNode.java | 263 ++----------------- .../virtualhostnode/AbstractVirtualHostNode.java | 289 +++++++++++++++++++++ 5 files changed, 347 insertions(+), 433 deletions(-) create mode 100644 qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java (limited to 'qpid/java') diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java index fff5c63337..55f90ebbcb 100644 --- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java +++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java @@ -21,29 +21,20 @@ package org.apache.qpid.server.virtualhostnode.berkeleydb; import java.security.PrivilegedAction; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; import javax.security.auth.Subject; import org.apache.log4j.Logger; import org.apache.qpid.server.configuration.updater.TaskExecutor; -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.BrokerModel; import org.apache.qpid.server.model.ConfiguredObject; -import org.apache.qpid.server.model.ConfiguredObjectFactory; -import org.apache.qpid.server.model.LifetimePolicy; import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.ManagedObject; import org.apache.qpid.server.model.State; -import org.apache.qpid.server.model.SystemContext; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.security.SecurityManager; @@ -55,12 +46,13 @@ import org.apache.qpid.server.store.berkeleydb.BDBMessageStore; import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade; import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacadeFactory; import org.apache.qpid.server.virtualhost.VirtualHostState; +import org.apache.qpid.server.virtualhostnode.AbstractVirtualHostNode; import com.sleepycat.je.rep.StateChangeEvent; import com.sleepycat.je.rep.StateChangeListener; @ManagedObject( category = false, type = "BDB_HA" ) -public class BDBHAVirtualHostNodeImpl extends AbstractConfiguredObject implements BDBHAVirtualHostNode +public class BDBHAVirtualHostNodeImpl extends AbstractVirtualHostNode implements BDBHAVirtualHostNode { private static final Logger LOGGER = Logger.getLogger(BDBHAVirtualHostNodeImpl.class); @@ -97,27 +89,9 @@ public class BDBHAVirtualHostNodeImpl extends AbstractConfiguredObject _replicatedEnvironmentConfiguration; - //TODO: remove this field - @ManagedAttributeField - private boolean _messageStoreProvider; - - private final AtomicReference _state = new AtomicReference(State.INITIALISING); - private final Broker _broker; - private final ConfiguredObjectFactory _objectFactory; - private final EventLogger _eventLogger; - - private MessageStoreLogSubject _configurationStoreLogSubject; - private BDBMessageStore _durableConfigurationStore; - - @SuppressWarnings("rawtypes") - protected BDBHAVirtualHostNodeImpl(Broker broker, Map attributes, TaskExecutor taskExecutor) + public BDBHAVirtualHostNodeImpl(Broker broker, Map attributes, TaskExecutor taskExecutor) { - super(Collections.,ConfiguredObject>singletonMap(Broker.class, broker), attributes, taskExecutor); - _broker = broker; - _objectFactory = _broker.getParent(SystemContext.class).getObjectFactory(); - SystemContext systemContext = _broker.getParent(SystemContext.class); - _eventLogger = systemContext.getEventLogger(); - + super(broker, attributes, taskExecutor); } @Override @@ -138,44 +112,6 @@ public class BDBHAVirtualHostNodeImpl extends AbstractConfiguredObject getVirtualHost() - { - @SuppressWarnings("rawtypes") - Collection children = getChildren(VirtualHost.class); - if (children.size() == 0) - { - return null; - } - else if (children.size() == 1) - { - return children.iterator().next(); - } - else - { - throw new IllegalStateException(this + " has an unexpected number of virtualhost children, size " + children.size()); - } - } - - - @Override - public DurableConfigurationStore getConfigurationStore() - { - return _durableConfigurationStore; - } - - @Override - public State getState() - { - return _state.get(); - } - - @Override - public LifetimePolicy getLifetimePolicy() - { - return LifetimePolicy.PERMANENT; - } - @Override public String getGroupName() { @@ -230,77 +166,11 @@ public class BDBHAVirtualHostNodeImpl extends AbstractConfiguredObject attributes = buildAttributesForStore(); - - _durableConfigurationStore.openConfigurationStore(this, attributes); - - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CREATED()); - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.STORE_LOCATION(getStorePath())); - - - ReplicatedEnvironmentFacade environmentFacade = (ReplicatedEnvironmentFacade) _durableConfigurationStore.getEnvironmentFacade(); - environmentFacade.setStateChangeListener(new BDBHAMessageStoreStateChangeListener()); + return (BDBMessageStore) super.getConfigurationStore(); } - private void stop() + protected DurableConfigurationStore createConfigurationStore() { - destroyVirtualHostIfExist(); - _durableConfigurationStore.closeConfigurationStore(); - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CLOSE()); + return new BDBMessageStore(new ReplicatedEnvironmentFacadeFactory()); } - private void delete() + @Override + protected void activate() { - VirtualHost virtualHost = getVirtualHost(); - if (virtualHost != null) + if (LOGGER.isDebugEnabled()) { - virtualHost.setDesiredState(virtualHost.getState(), State.DELETED); + LOGGER.debug("Activating virtualhost node " + this); } - //TODO: this needs to be called from parent - deleted(); + Map attributes = buildAttributesForStore(); - _durableConfigurationStore.onDelete(); + getConfigurationStore().openConfigurationStore(this, attributes); - } + getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.CREATED()); + getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.STORE_LOCATION(getStorePath())); - private Map buildAttributesForStore() - { - final Map attributes = new HashMap(); - Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() - { - @Override - public Object run() - { - for (String attributeName : getAttributeNames()) - { - Object value = getAttribute(attributeName); - attributes.put(attributeName, value); - } - return null; - } - }); - attributes.put(IS_MESSAGE_STORE_PROVIDER, true); - return attributes; + ReplicatedEnvironmentFacade environmentFacade = (ReplicatedEnvironmentFacade) getConfigurationStore().getEnvironmentFacade(); + environmentFacade.setStateChangeListener(new BDBHAMessageStoreStateChangeListener()); } private void onMaster() @@ -395,12 +231,12 @@ public class BDBHAVirtualHostNodeImpl extends AbstractConfiguredObject host = getVirtualHost(); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java index e1cffeb942..e1772c037a 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/store/VirtualHostStoreUpgraderAndRecoverer.java @@ -30,7 +30,6 @@ import java.util.UUID; import org.apache.qpid.server.filter.FilterSupport; import org.apache.qpid.server.model.Binding; -import org.apache.qpid.server.model.ConfiguredObjectFactory; import org.apache.qpid.server.model.Exchange; import org.apache.qpid.server.model.Queue; import org.apache.qpid.server.model.UUIDGenerator; @@ -54,7 +53,7 @@ public class VirtualHostStoreUpgraderAndRecoverer private final Map _defaultExchangeIds; - public VirtualHostStoreUpgraderAndRecoverer(VirtualHostNode virtualHostNode, ConfiguredObjectFactory objectFactory) + public VirtualHostStoreUpgraderAndRecoverer(VirtualHostNode virtualHostNode) { _virtualHostNode = virtualHostNode; register(new Upgrader_0_0_to_0_1()); diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java index abe3e2ce45..d9104bfbe0 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java @@ -72,6 +72,7 @@ import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.store.ConfiguredObjectRecord; +import org.apache.qpid.server.store.ConfiguredObjectRecordImpl; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.Event; import org.apache.qpid.server.store.EventListener; @@ -1401,10 +1402,11 @@ public abstract class AbstractVirtualHost> exte } catch (Exception e) { - _logger.warn("Exception occurred on store deletion", e); + _logger.warn("Exception occurred on message store deletion", e); } } setAttribute(VirtualHost.STATE, getState(), State.DELETED); + getDurableConfigurationStore().remove(asObjectRecord()); deleted(); } @@ -1561,7 +1563,8 @@ public abstract class AbstractVirtualHost> exte protected void onCreate() { super.onCreate(); - getDurableConfigurationStore().create(asObjectRecord()); + ConfiguredObjectRecord record = asObjectRecord(); + getDurableConfigurationStore().create(new ConfiguredObjectRecordImpl(record.getId(), record.getType(), record.getAttributes())); } protected void activate() diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java index 168b03945a..87470fb3cf 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java @@ -21,62 +21,36 @@ package org.apache.qpid.server.virtualhostnode; import java.io.File; -import java.security.AccessControlException; import java.security.PrivilegedAction; -import java.util.Collection; import java.util.HashMap; import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; import javax.security.auth.Subject; import org.apache.log4j.Logger; - import org.apache.qpid.server.configuration.updater.TaskExecutor; -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.BrokerModel; import org.apache.qpid.server.model.ConfiguredObject; -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.SystemContext; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.model.VirtualHostNode; import org.apache.qpid.server.plugin.DurableConfigurationStoreFactory; import org.apache.qpid.server.security.SecurityManager; -import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.store.DurableConfigurationStore; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.VirtualHostStoreUpgraderAndRecoverer; import org.apache.qpid.server.virtualhost.StandardVirtualHost; -public abstract class AbstractStandardVirtualHostNode> extends AbstractConfiguredObject +public abstract class AbstractStandardVirtualHostNode> extends AbstractVirtualHostNode implements VirtualHostNode { private static final Logger LOGGER = Logger.getLogger(AbstractStandardVirtualHostNode.class); - private final Broker _broker; - private final AtomicReference _state = new AtomicReference(State.INITIALISING); - private final EventLogger _eventLogger; - - @ManagedAttributeField - private boolean _messageStoreProvider; - - private MessageStoreLogSubject _configurationStoreLogSubject; - private DurableConfigurationStore _durableConfigurationStore; - - @SuppressWarnings("rawtypes") public AbstractStandardVirtualHostNode(Broker parent, Map attributes, TaskExecutor taskExecutor) { - super(parentsMap(parent), attributes, taskExecutor); - _broker = parent; - SystemContext systemContext = _broker.getParent(SystemContext.class); - _eventLogger = systemContext.getEventLogger(); + super(parent, attributes, taskExecutor); } @Override @@ -89,27 +63,6 @@ public abstract class AbstractStandardVirtualHostNode getDefaultMessageStoreSettings() - { - // TODO perhaps look for the MS with the default annotation and associated default. - Map settings = new HashMap(); - settings.put(MessageStore.STORE_TYPE, "DERBY"); - settings.put(MessageStore.STORE_PATH, "${qpid.work_dir}" + File.separator + "derbystore" + File.separator + getName()); - return settings; - } - @SuppressWarnings({ "rawtypes", "unchecked" }) @Override protected C addChild(Class childClass, Map attributes, @@ -122,130 +75,18 @@ public abstract class AbstractStandardVirtualHostNode T getParent(Class clazz) - { - if (clazz == Broker.class) - { - return (T) _broker; - } - return super.getParent(clazz); - } - - - @Override - public State getState() - { - return _state.get(); - } - - @Override - public LifetimePolicy getLifetimePolicy() - { - return LifetimePolicy.PERMANENT; - } - @Override - protected boolean setState(State currentState, State desiredState) + protected DurableConfigurationStore createConfigurationStore() { - State state = _state.get(); - if (desiredState == State.DELETED) - { - if (state == State.ACTIVE || state == State.INITIALISING) - { - state = setDesiredState(currentState, State.STOPPED); - } - - if (state == State.STOPPED || state == State.ERRORED) - { - if( _state.compareAndSet(state, State.DELETED)) - { - delete(); - return true; - } - } - else - { - throw new IllegalStateException("Cannot delete virtual host node in " + state + " state"); - } - } - else if (desiredState == State.ACTIVE) - { - if ((state == State.INITIALISING || state == State.STOPPED) && _state.compareAndSet(state, State.ACTIVE)) - { - try - { - activate(); - } - catch(RuntimeException e) - { - _state.compareAndSet(State.ACTIVE, State.ERRORED); - if (_broker.isManagementMode()) - { - LOGGER.warn("Failed to make " + this + " active.", e); - } - else - { - throw e; - } - } - return true; - } - else - { - throw new IllegalStateException("Cannot activate virtual host node in " + state + " state"); - } - } - else if (desiredState == State.STOPPED) - { - if (_state.compareAndSet(state, State.STOPPED)) - { - stop(); - return true; - } - else - { - throw new IllegalStateException("Cannot stop virtual host node in " + state + " state"); - } - } - return false; - } - - - @Override - public boolean isMessageStoreProvider() - { - return _messageStoreProvider; + DurableConfigurationStoreFactory durableConfigurationStoreFactory = getDurableConfigurationStoreFactory(); + DurableConfigurationStore store = durableConfigurationStoreFactory.createDurableConfigurationStore(); + return store; } - @Override - public VirtualHost getVirtualHost() - { - Collection children = getChildren(VirtualHost.class); - if (children.size() == 0) - { - return null; - } - else if (children.size() == 1) - { - return children.iterator().next(); - } - else - { - throw new IllegalStateException(this + " has an unexpected number of virtualhost children, size " + children.size()); - } - } + protected abstract DurableConfigurationStoreFactory getDurableConfigurationStoreFactory(); @Override - public DurableConfigurationStore getConfigurationStore() - { - return _durableConfigurationStore; - } - - private void activate() + protected void activate() { if (LOGGER.isDebugEnabled()) { @@ -254,23 +95,23 @@ public abstract class AbstractStandardVirtualHostNode attributes = buildAttributesForStore(); - _durableConfigurationStore.openConfigurationStore(this, attributes); + getConfigurationStore().openConfigurationStore(this, attributes); - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CREATED()); + getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.CREATED()); if (this instanceof FileBasedVirtualHostNode) { @SuppressWarnings("rawtypes") FileBasedVirtualHostNode fileBasedVirtualHostNode = (FileBasedVirtualHostNode) this; - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.STORE_LOCATION(fileBasedVirtualHostNode.getStorePath())); + getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.STORE_LOCATION(fileBasedVirtualHostNode.getStorePath())); } - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_START()); + getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.RECOVERY_START()); - VirtualHostStoreUpgraderAndRecoverer upgrader = new VirtualHostStoreUpgraderAndRecoverer(this, getObjectFactory()); - upgrader.perform(_durableConfigurationStore); + VirtualHostStoreUpgraderAndRecoverer upgrader = new VirtualHostStoreUpgraderAndRecoverer(this); + upgrader.perform(getConfigurationStore()); - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.RECOVERY_COMPLETE()); + getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.RECOVERY_COMPLETE()); VirtualHost host = getVirtualHost(); @@ -307,75 +148,21 @@ public abstract class AbstractStandardVirtualHostNode buildAttributesForStore() - { - final Map attributes = new HashMap(); - Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() - { - @Override - public Object run() - { - for (String attributeName : getAttributeNames()) - { - Object value = getAttribute(attributeName); - attributes.put(attributeName, value); - } - return null; - } - }); - - return attributes; - } - - private void delete() - { - VirtualHost virtualHost = getVirtualHost(); - if (virtualHost != null) - { - virtualHost.setDesiredState(virtualHost.getState(), State.DELETED); - } - //TODO: this needs to be called from parent - deleted(); - - // TODO Split onDelete into deleteMessageStore/deleteConfigStore - if (_durableConfigurationStore instanceof MessageStore) - { - ((MessageStore)_durableConfigurationStore).onDelete(); - } - - } - - private void stop() - { - VirtualHost virtualHost = getVirtualHost(); - if (virtualHost != null) - { - virtualHost.setDesiredState(virtualHost.getState(), State.STOPPED); - } - _durableConfigurationStore.closeConfigurationStore(); - - _eventLogger.message(_configurationStoreLogSubject, ConfigStoreMessages.CLOSE()); - } - @Override - protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException + public String toString() { - if(desiredState == State.DELETED) - { - if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), VirtualHostNode.class, Operation.DELETE)) - { - throw new AccessControlException("Deletion of virtual host node is denied"); - } - } + return this.getClass().getSimpleName() + "[id=" + getId() + ", name=" + getName() + ", state=" + getState() + "]"; } - @Override - protected void authoriseSetAttributes(ConfiguredObject modified, Set attributes) throws AccessControlException + // protected for unit testing purposes + protected Map getDefaultMessageStoreSettings() { - if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), VirtualHostNode.class, Operation.UPDATE)) - { - throw new AccessControlException("Setting of virtual host node attributes is denied"); - } + // TODO perhaps look for the MS with the default annotation and associated default. + Map settings = new HashMap(); + settings.put(MessageStore.STORE_TYPE, "DERBY"); + settings.put(MessageStore.STORE_PATH, "${qpid.work_dir}" + File.separator + "derbystore" + File.separator + getName()); + return settings; } + } 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 new file mode 100644 index 0000000000..1db15003ed --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java @@ -0,0 +1,289 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.virtualhostnode; + +import java.security.AccessControlException; +import java.security.PrivilegedAction; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import javax.security.auth.Subject; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.configuration.updater.TaskExecutor; +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.LifetimePolicy; +import org.apache.qpid.server.model.ManagedAttributeField; +import org.apache.qpid.server.model.State; +import org.apache.qpid.server.model.SystemContext; +import org.apache.qpid.server.model.VirtualHost; +import org.apache.qpid.server.model.VirtualHostNode; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.store.MessageStore; + +public abstract class AbstractVirtualHostNode> extends AbstractConfiguredObject implements VirtualHostNode +{ + + private static final Logger LOGGER = Logger.getLogger(AbstractVirtualHostNode.class); + + private final Broker _broker; + private final AtomicReference _state = new AtomicReference(State.INITIALISING); + private final EventLogger _eventLogger; + + private DurableConfigurationStore _durableConfigurationStore; + + private MessageStoreLogSubject _configurationStoreLogSubject; + + @ManagedAttributeField + private boolean _messageStoreProvider; + + public AbstractVirtualHostNode(Broker parent, Map attributes, TaskExecutor taskExecutor) + { + super(Collections.,ConfiguredObject>singletonMap(Broker.class, parent), + attributes, taskExecutor); + _broker = parent; + SystemContext systemContext = _broker.getParent(SystemContext.class); + _eventLogger = systemContext.getEventLogger(); + } + + + @Override + public void onOpen() + { + super.onOpen(); + _durableConfigurationStore = createConfigurationStore(); + _configurationStoreLogSubject = new MessageStoreLogSubject(getName(), _durableConfigurationStore.getClass().getSimpleName()); + + } + + @Override + public State getState() + { + return _state.get(); + } + + @Override + public LifetimePolicy getLifetimePolicy() + { + return LifetimePolicy.PERMANENT; + } + + @Override + protected boolean setState(State currentState, State desiredState) + { + State state = _state.get(); + if (desiredState == State.DELETED) + { + if (state == State.ACTIVE || state == State.INITIALISING) + { + state = setDesiredState(currentState, State.STOPPED); + } + + if (state == State.STOPPED || state == State.ERRORED) + { + if( _state.compareAndSet(state, State.DELETED)) + { + delete(); + return true; + } + } + else + { + throw new IllegalStateException("Cannot delete virtual host node in " + state + " state"); + } + } + else if (desiredState == State.ACTIVE) + { + if ((state == State.INITIALISING || state == State.STOPPED) && _state.compareAndSet(state, State.ACTIVE)) + { + try + { + activate(); + } + catch(RuntimeException e) + { + _state.compareAndSet(State.ACTIVE, State.ERRORED); + if (_broker.isManagementMode()) + { + LOGGER.warn("Failed to make " + this + " active.", e); + } + else + { + throw e; + } + } + return true; + } + else + { + throw new IllegalStateException("Cannot activate virtual host node in " + state + " state"); + } + } + else if (desiredState == State.STOPPED) + { + if (_state.compareAndSet(state, State.STOPPED)) + { + stop(); + return true; + } + else + { + throw new IllegalStateException("Cannot stop virtual host node in " + state + " state"); + } + } + return false; + } + + @Override + public boolean isMessageStoreProvider() + { + return _messageStoreProvider; + } + + @Override + public VirtualHost getVirtualHost() + { + Collection children = getChildren(VirtualHost.class); + if (children.size() == 0) + { + return null; + } + else if (children.size() == 1) + { + return children.iterator().next(); + } + else + { + throw new IllegalStateException(this + " has an unexpected number of virtualhost children, size " + children.size()); + } + } + + @Override + public DurableConfigurationStore getConfigurationStore() + { + return _durableConfigurationStore; + } + + protected Broker getBroker() + { + return _broker; + } + + protected EventLogger getEventLogger() + { + return _eventLogger; + } + + protected DurableConfigurationStore getDurableConfigurationStore() + { + return _durableConfigurationStore; + } + + protected MessageStoreLogSubject getConfigurationStoreLogSubject() + { + return _configurationStoreLogSubject; + } + + protected Map buildAttributesForStore() + { + final Map attributes = new HashMap(); + Subject.doAs(SecurityManager.getSubjectWithAddedSystemRights(), new PrivilegedAction() + { + @Override + public Object run() + { + for (String attributeName : getAttributeNames()) + { + Object value = getAttribute(attributeName); + attributes.put(attributeName, value); + } + return null; + } + }); + + return attributes; + } + + protected void delete() + { + VirtualHost virtualHost = getVirtualHost(); + if (virtualHost != null) + { + virtualHost.setDesiredState(virtualHost.getState(), State.DELETED); + } + + deleted(); + + if (getConfigurationStore() instanceof MessageStore) + { + ((MessageStore)getConfigurationStore()).onDelete(); + } + } + + protected void stop() + { + VirtualHost virtualHost = getVirtualHost(); + if (virtualHost != null) + { + virtualHost.setDesiredState(virtualHost.getState(), State.STOPPED); + } + getConfigurationStore().closeConfigurationStore(); + + getEventLogger().message(getConfigurationStoreLogSubject(), ConfigStoreMessages.CLOSE()); + } + + @Override + protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException + { + if(desiredState == State.DELETED) + { + if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), VirtualHostNode.class, Operation.DELETE)) + { + throw new AccessControlException("Deletion of virtual host node is denied"); + } + } + } + + @Override + protected void authoriseSetAttributes(ConfiguredObject modified, Set attributes) throws AccessControlException + { + if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), VirtualHostNode.class, Operation.UPDATE)) + { + throw new AccessControlException("Setting of virtual host node attributes is denied"); + } + } + + protected abstract DurableConfigurationStore createConfigurationStore(); + + protected abstract void activate(); + +} \ No newline at end of file -- cgit v1.2.1