Author: rgodfrey Date: Fri Oct 10 09:59:55 2014 New Revision: 1630749 URL: http://svn.apache.org/r1630749 Log: Merge from trunk
Added: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/ - copied from r1630746, qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java - copied unchanged from r1630746, qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/binding/ - copied from r1630746, qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/binding/ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/model/port/ - copied from r1630746, qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/port/ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/TestLdapDirectoryContext.java - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/TestLdapDirectoryContext.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ChannelMethodProcessor.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ServerMethodProcessor.java (with props) qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/editQueue.html - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/editQueue.html qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editQueue.js - copied unchanged from r1630746, qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/editQueue.js Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/ (props changed) qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCConfigurationStore.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/model/VirtualHostTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/ServerMethodDispatcherImpl.java (contents, props changed) qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/addQueue.html qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/css/common.css qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/ContextVariablesEditor.js qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/Queue.js qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addQueue.js qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addVirtualHostNodeAndVirtualHost.js qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-http/src/main/java/resources/showQueue.html qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1001-MessageSize-Transient-ByteSec.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1002-MessageSize-Persistent-ByteSec.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1003-MessageSize-Transient-MsgSec.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1004-MessageSize-Persistent-MsgSec.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1011-VaryingNumberOfProducers-AutoAck.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1012-VaryingNumberOfConsumers-AutoAck.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1015-VaryingNumberOfProducers-SessionTrans.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1016-VaryingNumberOfConsumers-SessionTrans.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1021-AcknowledgementModes-Persistent.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1022-AcknowledgementModes-Transient.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1030-BatchSize-Equal.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1031-BatchSize-Unequal.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1040-QueueTypes.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1050-VaryingNumberOfProducerSessionsSingleConnection.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1300-QueueConsumersWithNonOverlappingSelectors-Transient.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1301-QueueConsumersWithNonOverlappingSelectors-Persistent.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1302-QueueConsumersWithOverlappingSelectors-Transient.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1303-QueueConsumersWithOverlappingSelectors-Persistent.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1500-Topic-NumberOfConsumers.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1501-Topic-NumberOfTopics.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1502-Topic-Persistence.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/1503-Topic-AckModes.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/2001-Latency-MessageSize-Transient.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/2002-Latency-MessageSize-Persistent.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/chartdefs/2031-Latency-VaryingNumberOfParticipants.chartdef qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/testdefs/Latency-MessageSize.json qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/testdefs/Latency-VaryingNumberOfParticipants.json qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/testdefs/MessageSize.json qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/testdefs/QueueConsumersWithNonOverlappingSelectors.js qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/etc/testdefs/QueueConsumersWithOverlappingSelectors.js qpid/branches/QPID-6125-ProtocolRefactoring/java/perftests/pom.xml qpid/branches/QPID-6125-ProtocolRefactoring/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java qpid/branches/QPID-6125-ProtocolRefactoring/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java qpid/branches/QPID-6125-ProtocolRefactoring/java/systests/src/test/java/org/apache/qpid/systest/rest/PortRestTest.java Propchange: qpid/branches/QPID-6125-ProtocolRefactoring/java/ ------------------------------------------------------------------------------ Merged /qpid/trunk/qpid/java:r1628068-1630746 Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/jmx/src/main/java/org/apache/qpid/server/store/berkeleydb/jmx/BDBHAMessageStoreManagerMBeanProvider.java Fri Oct 10 09:59:55 2014 @@ -27,6 +27,7 @@ import org.apache.qpid.server.jmx.MBeanP import org.apache.qpid.server.jmx.ManagedObject; import org.apache.qpid.server.jmx.ManagedObjectRegistry; import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.State; import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHAVirtualHostNode; @@ -46,7 +47,7 @@ public class BDBHAMessageStoreManagerMBe @Override public boolean isChildManageableByMBean(ConfiguredObject child) { - return child instanceof BDBHAVirtualHostNode; + return child instanceof BDBHAVirtualHostNode && ((BDBHAVirtualHostNode)child).getState() != State.ERRORED; } @Override Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java Fri Oct 10 09:59:55 2014 @@ -26,6 +26,7 @@ import org.apache.qpid.server.logging.Ev import org.apache.qpid.server.logging.LogRecorder; import org.apache.qpid.server.model.AbstractSystemConfig; import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.BrokerShutdownProvider; import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.ManagedObject; import org.apache.qpid.server.model.SystemConfigFactoryConstructor; @@ -48,9 +49,10 @@ public class BDBSystemConfigImpl extends public BDBSystemConfigImpl(final TaskExecutor taskExecutor, final EventLogger eventLogger, final LogRecorder logRecorder, - final BrokerOptions brokerOptions) + final BrokerOptions brokerOptions, + final BrokerShutdownProvider brokerShutdownProvider) { - super(taskExecutor, eventLogger, logRecorder, brokerOptions); + super(taskExecutor, eventLogger, logRecorder, brokerOptions, brokerShutdownProvider); } @Override Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/replication/ReplicatedEnvironmentFacade.java Fri Oct 10 09:59:55 2014 @@ -1253,7 +1253,7 @@ public class ReplicatedEnvironmentFacade { if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Setting permitted nodes to " + permittedNodes); + LOGGER.debug(_prettyGroupNodeName + " permitted nodes set to " + permittedNodes); } _permittedNodes.clear(); @@ -1263,12 +1263,18 @@ public class ReplicatedEnvironmentFacade registerAppStateMonitorIfPermittedNodesSpecified(); ReplicationGroupListener listener = _replicationGroupListener.get(); + int count = 0; for(ReplicationNode node: _remoteReplicationNodes.values()) { if (!isNodePermitted(node)) { onIntruder(listener, node); } + count++; + } + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug(_prettyGroupNodeName + " checked " + count + " node(s)"); } } } @@ -1329,7 +1335,7 @@ public class ReplicatedEnvironmentFacade } catch (IOException e) { - throw new IllegalConfigurationException(String.format("Cannot connect to '%s'", helperHostPort), e); + throw new IllegalConfigurationException(String.format("Cannot connect to existing node '%s' at '%s'", helperNodeName, helperHostPort), e); } catch (ServiceConnectFailedException e) { @@ -1337,8 +1343,8 @@ public class ReplicatedEnvironmentFacade } catch (Exception e) { - throw new RuntimeException(String.format("Unexpected exception on attempt to retrieve state from '%s' at '%s'", - helperNodeName, helperHostPort), e); + throw new RuntimeException(String.format("Cannot retrieve state for node '%s' (%s) from group '%s'", + helperNodeName, helperHostPort, groupName), e); } if (LOGGER.isDebugEnabled()) Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java Fri Oct 10 09:59:55 2014 @@ -20,7 +20,11 @@ */ package org.apache.qpid.server.virtualhostnode.berkeleydb; +import java.io.File; import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.file.Files; import java.security.PrivilegedAction; import java.text.MessageFormat; import java.util.ArrayList; @@ -74,6 +78,7 @@ import org.apache.qpid.server.store.berk import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacade; import org.apache.qpid.server.store.berkeleydb.replication.ReplicatedEnvironmentFacadeFactory; import org.apache.qpid.server.store.berkeleydb.replication.ReplicationGroupListener; +import org.apache.qpid.server.util.PortUtil; import org.apache.qpid.server.util.ServerScopedRuntimeException; import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHostImpl; import org.apache.qpid.server.virtualhostnode.AbstractVirtualHostNode; @@ -255,7 +260,7 @@ public class BDBHAVirtualHostNodeImpl ex public String toString() { return "BDBHAVirtualHostNodeImpl [id=" + getId() + ", name=" + getName() + ", storePath=" + _storePath + ", groupName=" + _groupName + ", address=" + _address - + ", state=" + getState() + ", priority=" + _priority + ", designatedPrimary=" + _designatedPrimary + ", quorumOverride=" + _quorumOverride + "]"; + + ", state=" + getState() + ", priority=" + _priority + ", designatedPrimary=" + _designatedPrimary + ", quorumOverride=" + _quorumOverride + ", role=" + getRole() + "]"; } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -282,22 +287,18 @@ public class BDBHAVirtualHostNodeImpl ex super.onCreate(); if (!isFirstNodeInAGroup()) { - try - { - int dbPingSocketTimeout = getContextKeys(false).contains("qpid.bdb.ha.db_ping_socket_timeout") ? getContextValue(Integer.class, "qpid.bdb.ha.db_ping_socket_timeout") : 10000 /* JE's own default */; - Collection<String> permittedNodes = ReplicatedEnvironmentFacade.connectToHelperNodeAndCheckPermittedHosts(getName(), getAddress(), getGroupName(), getHelperNodeName(), getHelperAddress(), dbPingSocketTimeout); - setAttribute(PERMITTED_NODES, null, new ArrayList<String>(permittedNodes)); - } - catch(IllegalConfigurationException e) - { - deleted(); - throw e; - } + _permittedNodes = new ArrayList<>(getPermittedNodesFromHelper()); } - getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.CREATED()); } + @Override + public void onOpen() + { + validatePermittedNodesFormat(_permittedNodes); + super.onOpen(); + } + protected ReplicatedEnvironmentFacade getReplicatedEnvironmentFacade() { return _environmentFacade.get(); @@ -334,6 +335,24 @@ public class BDBHAVirtualHostNodeImpl ex throw new IllegalStateException("Environment facade is not created"); } + try + { + Set<ReplicationNode> remoteNodes = environmentFacade.getEnvironment().getGroup().getNodes(); + for (ReplicationNode node : remoteNodes) + { + String nodeAddress = node.getHostName() + ":" + node.getPort(); + if (!_permittedNodes.contains(nodeAddress)) + { + shutdownOnIntruder(nodeAddress); + throw new IllegalStateException("Intruder node detected: " + nodeAddress); + } + } + } + catch (DatabaseException dbe) + { + environmentFacade.handleDatabaseException("DB exception while checking for intruder node", dbe); + } + if (_environmentFacade.compareAndSet(null, environmentFacade)) { environmentFacade.setStateChangeListener(new EnvironmentStateChangeListener()); @@ -372,9 +391,15 @@ public class BDBHAVirtualHostNodeImpl ex @StateTransition( currentState = { State.ACTIVE, State.STOPPED, State.ERRORED}, desiredState = State.DELETED ) protected void doDelete() { + // get helpers before close. on close all children are closed and not available anymore Set<InetSocketAddress> helpers = getRemoteNodeAddresses(); super.doDelete(); - getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.DELETED()); + + if (getConfigurationStore() != null) + { + getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.DELETED()); + } + if (getState() == State.DELETED && !helpers.isEmpty()) { try @@ -432,20 +457,87 @@ public class BDBHAVirtualHostNodeImpl ex } @Override - public void onValidate() + protected void postResolve() { - super.onValidate(); + super.postResolve(); _virtualHostNodeLogSubject = new BDBHAVirtualHostNodeLogSubject(getGroupName(), getName()); _groupLogSubject = new GroupLogSubject(getGroupName()); _virtualHostNodePrincipalName = MessageFormat.format(VIRTUAL_HOST_PRINCIPAL_NAME_FORMAT, getGroupName(), getName()); } @Override - public void onOpen() + public void validateOnCreate() { - super.onOpen(); + super.validateOnCreate(); + + validateAddress(); - validatePermittedNodes(_permittedNodes); + validateStorePath(); + + if (!isFirstNodeInAGroup()) + { + getPermittedNodesFromHelper(); + } + } + + private Collection<String> getPermittedNodesFromHelper() + { + int dbPingSocketTimeout = getContextKeys(false).contains("qpid.bdb.ha.db_ping_socket_timeout") ? getContextValue(Integer.class, "qpid.bdb.ha.db_ping_socket_timeout") : 10000 /* JE's own default */; + return ReplicatedEnvironmentFacade.connectToHelperNodeAndCheckPermittedHosts(getName(), getAddress(), getGroupName(), getHelperNodeName(), getHelperAddress(), dbPingSocketTimeout); + } + + private void validateStorePath() + { + File storePath = new File(getStorePath()); + while (!storePath.exists()) + { + storePath = storePath.getParentFile(); + if (storePath == null) + { + throw new IllegalConfigurationException(String.format("Store path '%s' is invalid", getStorePath())); + } + } + + if (!storePath.isDirectory()) + { + throw new IllegalConfigurationException(String.format("Store path '%s' is not a folder", getStorePath())); + } + + if (!Files.isWritable(storePath.toPath())) + { + throw new IllegalConfigurationException(String.format("Store path '%s' is not writable", getStorePath())); + } + } + + private void validateAddress() + { + String address = getAddress(); + + URI uri = addressToURI(address); + + if (!PortUtil.isPortAvailable(uri.getHost(), uri.getPort())) + { + throw new IllegalConfigurationException(String.format("Cannot bind to address '%s'. Address is already in use.", address)); + } + } + + private URI addressToURI(String address) + { + if (address == null || "".equals(address)) + { + throw new IllegalConfigurationException("Node address is not set"); + } + + URI uri = null; + try + { + uri = new URI( "tcp://" + address); + } + catch (URISyntaxException e) + { + throw new IllegalConfigurationException(String.format("Invalid address specified '%s'. ", address)); + } + return uri; } private void onMaster() @@ -538,7 +630,7 @@ public class BDBHAVirtualHostNodeImpl ex private void onDetached() { - createReplicaVirtualHost(); + closeVirtualHostIfExist(); } private void createReplicaVirtualHost() @@ -578,7 +670,7 @@ public class BDBHAVirtualHostNodeImpl ex if (LOGGER.isInfoEnabled()) { - LOGGER.info("Received BDB event indicating transition to state " + state); + LOGGER.info("Received BDB event indicating transition to state " + state + " for " + getName()); } NodeRole previousRole = getRole(); try @@ -728,7 +820,7 @@ public class BDBHAVirtualHostNodeImpl ex private boolean isFirstNodeInAGroup() { - return getAddress().equals(getHelperAddress()); + return getHelperNodeName() == null; } BDBHAVirtualHostNodeLogSubject getVirtualHostNodeLogSubject() @@ -761,7 +853,7 @@ public class BDBHAVirtualHostNodeImpl ex } } - private void validatePermittedNodes(List<String> proposedPermittedNodes) + private void validatePermittedNodes(Collection<String> proposedPermittedNodes) { if (getRemoteReplicationNodes().size() > 0 && getRole() != NodeRole.MASTER && !(getState() == State.STOPPED || getState() == State.ERRORED)) { @@ -772,47 +864,48 @@ public class BDBHAVirtualHostNodeImpl ex throw new IllegalArgumentException(String.format("Attribute '%s' is mandatory and must be set", PERMITTED_NODES)); } - String missingNodeAddress = null; - if (getPermittedNodes().contains(getAddress()) && !proposedPermittedNodes.contains(getAddress())) + if (_permittedNodes != null) { - missingNodeAddress = getAddress(); - } - else - { - for (final RemoteReplicationNode<?> node : getRemoteReplicationNodes()) + String missingNodeAddress = null; + + if (_permittedNodes.contains(getAddress()) && !proposedPermittedNodes.contains(getAddress())) { - final BDBHARemoteReplicationNode<?> bdbHaRemoteReplicationNode = (BDBHARemoteReplicationNode<?>) node; - final String remoteNodeAddress = bdbHaRemoteReplicationNode.getAddress(); - if (getPermittedNodes().contains(remoteNodeAddress) && !proposedPermittedNodes.contains(remoteNodeAddress)) + missingNodeAddress = getAddress(); + } + else + { + for (final RemoteReplicationNode<?> node : getRemoteReplicationNodes()) { - missingNodeAddress = remoteNodeAddress; - break; + final BDBHARemoteReplicationNode<?> bdbHaRemoteReplicationNode = (BDBHARemoteReplicationNode<?>) node; + final String remoteNodeAddress = bdbHaRemoteReplicationNode.getAddress(); + if (_permittedNodes.contains(remoteNodeAddress) && !proposedPermittedNodes.contains(remoteNodeAddress)) + { + missingNodeAddress = remoteNodeAddress; + break; + } } } + + if (missingNodeAddress != null) + { + throw new IllegalArgumentException(String.format("The current group node '%s' cannot be removed from '%s' as its already a group member", missingNodeAddress, PERMITTED_NODES)); + } } - if (missingNodeAddress != null) + validatePermittedNodesFormat(proposedPermittedNodes); + } + + private void validatePermittedNodesFormat(Collection<String> permittedNodes) + { + if (permittedNodes == null || permittedNodes.isEmpty()) { - throw new IllegalArgumentException(String.format("The current group node '%s' cannot be removed from '%s' as its already a group member", missingNodeAddress, PERMITTED_NODES)); + throw new IllegalConfigurationException("Permitted nodes are not set"); } - for (String permittedNode: proposedPermittedNodes) + for (String permittedNode: permittedNodes) { - String[] tokens = permittedNode.split(":"); - if (tokens.length != 2) - { - throw new IllegalArgumentException(String.format("Invalid permitted node specified '%s'. ", permittedNode)); - } - try - { - Integer.parseInt(tokens[1]); - } - catch(Exception e) - { - throw new IllegalArgumentException(String.format("Invalid port is specified in permitted node '%s'. ", permittedNode)); - } + addressToURI(permittedNode); } - } private class RemoteNodesDiscoverer implements ReplicationGroupListener @@ -931,7 +1024,7 @@ public class BDBHAVirtualHostNodeImpl ex { byte[] applicationState = nodeState.getAppState(); Set<String> permittedNodes = ReplicatedEnvironmentFacade.convertApplicationStateBytesToPermittedNodeList(applicationState); - if (!_permittedNodes.equals(permittedNodes)) + if (_permittedNodes.size() != permittedNodes.size() || !_permittedNodes.containsAll(permittedNodes)) { if (_permittedNodes.contains(remoteNode.getAddress())) { @@ -972,7 +1065,7 @@ public class BDBHAVirtualHostNodeImpl ex private boolean processIntruderNode(ReplicationNode node) { - String hostAndPort = node.getHostName() + ":" + node.getPort(); + final String hostAndPort = node.getHostName() + ":" + node.getPort(); getEventLogger().message(getGroupLogSubject(), HighAvailabilityMessages.INTRUDER_DETECTED(node.getName(), hostAndPort)); boolean inManagementMode = getParent(Broker.class).isManagementMode(); @@ -994,35 +1087,16 @@ public class BDBHAVirtualHostNodeImpl ex BDBHAVirtualHostNodeImpl.this.getName(), _lastRole.get(), String.valueOf(BDBHAVirtualHostNodeImpl.this.getPermittedNodes()) )); - getTaskExecutor().submit(new Task<Void>() { @Override public Void execute() { - State state = getState(); - if (state != State.ERRORED) - { - try - { - stopAndSetStateTo(State.ERRORED); - } - catch(Exception e) - { - LOGGER.error("Unexpected exception on closing the node when intruder is detected ", e); - } - finally - { - closeEnvironment(); - - _lastRole.set(NodeRole.DETACHED); - attributeSet(ROLE, _role, NodeRole.DETACHED); - } - notifyStateChanged(state, State.ERRORED); - } + shutdownOnIntruder(hostAndPort); return null; } }); + return false; } } @@ -1044,6 +1118,28 @@ public class BDBHAVirtualHostNodeImpl ex } } + protected void shutdownOnIntruder(String intruderHostAndPort) + { + LOGGER.info("Intruder detected (" + intruderHostAndPort + "), stopping and setting state to ERRORED"); + + State initialState = getState(); + try + { + stopAndSetStateTo(State.ERRORED); + } + catch (Exception e) + { + LOGGER.error("Unexpected exception on closing the node when intruder is detected ", e); + } + finally + { + closeEnvironment(); + _lastRole.set(NodeRole.DETACHED); + attributeSet(ROLE, _role, NodeRole.DETACHED); + } + notifyStateChanged(initialState, State.ERRORED); + } + private abstract class VirtualHostNodeGroupTask implements Task<Void> { @Override Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/main/java/resources/js/qpid/management/virtualhostnode/bdb_ha/add/newgroup/add.js Fri Oct 10 09:59:55 2014 @@ -106,6 +106,7 @@ define(["dojo/_base/xhr", _changeAddress: function(address, virtualHostNodeHelperAddress) { virtualHostNodeHelperAddress.set("value", address); + this._updatePermittedNodesJson(); }, _clickAddPermittedNodeButton: function(e) { Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java Fri Oct 10 09:59:55 2014 @@ -23,13 +23,17 @@ package org.apache.qpid.server.store.ber import static org.mockito.Mockito.when; import java.io.File; +import java.net.InetSocketAddress; +import java.net.ServerSocket; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import com.sleepycat.je.Durability; @@ -38,12 +42,14 @@ import com.sleepycat.je.rep.ReplicatedEn import com.sleepycat.je.rep.ReplicationConfig; import org.apache.qpid.server.configuration.IllegalConfigurationException; +import org.apache.qpid.server.model.AbstractConfiguredObject; import org.apache.qpid.server.model.ConfigurationChangeListener; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.RemoteReplicationNode; import org.apache.qpid.server.model.State; import org.apache.qpid.server.model.VirtualHost; import org.apache.qpid.server.store.DurableConfigurationStore; +import org.apache.qpid.server.store.berkeleydb.replication.DatabasePinger; import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHost; import org.apache.qpid.server.virtualhost.berkeleydb.BDBHAVirtualHostImpl; import org.apache.qpid.server.virtualhostnode.berkeleydb.BDBHARemoteReplicationNode; @@ -53,6 +59,8 @@ import org.apache.qpid.server.virtualhos import org.apache.qpid.server.virtualhostnode.berkeleydb.NodeRole; import org.apache.qpid.test.utils.PortHelper; import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.test.utils.TestFileUtils; +import org.apache.qpid.util.FileUtils; public class BDBHAVirtualHostNodeTest extends QpidTestCase { @@ -289,6 +297,7 @@ public class BDBHAVirtualHostNodeTest ex _helper.awaitRemoteNodes(master, 2); BDBHAVirtualHostNode<?> replica = _helper.awaitAndFindNodeInRole(NodeRole.REPLICA); + _helper.awaitRemoteNodes(replica, 2); assertNotNull("Remote node " + replica.getName() + " is not found", _helper.findRemoteNode(master, replica.getName())); replica.delete(); @@ -481,21 +490,70 @@ public class BDBHAVirtualHostNodeTest ex nonMasterNode.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, amendedPermittedNodes)); } + public void testIntruderProtection() throws Exception + { + int nodePortNumber = _portHelper.getNextAvailable(); + int intruderPortNumber = _portHelper.getNextAvailable(); + + String helperAddress = "localhost:" + nodePortNumber; + String groupName = "group"; + String nodeName = "node"; + + Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress, nodeName, nodePortNumber, intruderPortNumber); + BDBHAVirtualHostNode<?> node = _helper.createAndStartHaVHN(node1Attributes); + + Map<String, Object> intruderAttributes = _helper.createNodeAttributes("intruder", groupName, "localhost:" + intruderPortNumber, helperAddress, nodeName); + intruderAttributes.put(BDBHAVirtualHostNode.PRIORITY, 0); + BDBHAVirtualHostNode<?> intruder = _helper.createAndStartHaVHN(intruderAttributes); + + final CountDownLatch stopLatch = new CountDownLatch(1); + ConfigurationChangeListener listener = new NoopConfigurationChangeListener() + { + @Override + public void stateChanged(ConfiguredObject<?> object, State oldState, State newState) + { + if (newState == State.ERRORED) + { + stopLatch.countDown(); + } + } + }; + node.addChangeListener(listener); + + List<String> permittedNodes = new ArrayList<String>(); + permittedNodes.add(helperAddress); + node.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes)); + + assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(10, TimeUnit.SECONDS)); + + // Try top re start the ERRORED node and ensure exception is thrown + try + { + node.start(); + fail("Restart of node should have thrown exception"); + } + catch (IllegalStateException ise) + { + assertEquals("Unexpected exception when restarting node post intruder detection", "Intruder node detected: " + "localhost:" + intruderPortNumber, ise.getMessage()); + } + _helper.awaitForAttributeChange(node, AbstractConfiguredObject.STATE, State.ERRORED); + } + public void testIntruderProtectionInManagementMode() throws Exception { - int node1PortNumber = _portHelper.getNextAvailable(); - int node2PortNumber = _portHelper.getNextAvailable(); + int nodePortNumber = _portHelper.getNextAvailable(); + int intruderPortNumber = _portHelper.getNextAvailable(); - String helperAddress = "localhost:" + node1PortNumber; + String helperAddress = "localhost:" + nodePortNumber; String groupName = "group"; - String nodeName = "node1"; + String nodeName = "node"; - Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress, nodeName, node1PortNumber, node2PortNumber); - BDBHAVirtualHostNode<?> node1 = _helper.createAndStartHaVHN(node1Attributes); + Map<String, Object> nodeAttributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress, nodeName, nodePortNumber, intruderPortNumber); + BDBHAVirtualHostNode<?> node = _helper.createAndStartHaVHN(nodeAttributes); - Map<String, Object> node2Attributes = _helper.createNodeAttributes("node2", groupName, "localhost:" + node2PortNumber, helperAddress, nodeName); - node2Attributes.put(BDBHAVirtualHostNode.PRIORITY, 0); - BDBHAVirtualHostNode<?> node2 = _helper.createAndStartHaVHN(node2Attributes); + Map<String, Object> intruderAttributes = _helper.createNodeAttributes("intruder", groupName, "localhost:" + intruderPortNumber, helperAddress, nodeName); + intruderAttributes.put(BDBHAVirtualHostNode.PRIORITY, 0); + BDBHAVirtualHostNode<?> intruder = _helper.createAndStartHaVHN(intruderAttributes); final CountDownLatch stopLatch = new CountDownLatch(1); ConfigurationChangeListener listener = new NoopConfigurationChangeListener() @@ -509,21 +567,85 @@ public class BDBHAVirtualHostNodeTest ex } } }; - node1.addChangeListener(listener); + node.addChangeListener(listener); List<String> permittedNodes = new ArrayList<String>(); permittedNodes.add(helperAddress); - node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes)); + node.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes)); assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(10, TimeUnit.SECONDS)); + // test that if management mode is enabled then the node can start without exception when(_helper.getBroker().isManagementMode()).thenReturn(true); - node1.start(); + node.start(); + + _helper.awaitForAttributeChange(node, AbstractConfiguredObject.STATE, State.ERRORED); + } + + public void testPermittedNodesChangedOnReplicaNodeOnlyOnceAfterBeingChangedOnMaster() throws Exception + { + int node1PortNumber = _portHelper.getNextAvailable(); + int node2PortNumber = _portHelper.getNextAvailable(); + + String helperAddress = "localhost:" + node1PortNumber; + String groupName = "group"; + String nodeName = "node1"; + + Map<String, Object> node1Attributes = _helper.createNodeAttributes(nodeName, groupName, helperAddress, helperAddress, nodeName, node1PortNumber, node2PortNumber); + BDBHAVirtualHostNode<?> node1 = _helper.createAndStartHaVHN(node1Attributes); + + Map<String, Object> node2Attributes = _helper.createNodeAttributes("node2", groupName, "localhost:" + node2PortNumber, helperAddress, nodeName); + node2Attributes.put(BDBHAVirtualHostNode.PRIORITY, 0); + BDBHAVirtualHostNode<?> node2 = _helper.createAndStartHaVHN(node2Attributes); + assertEquals("Unexpected role", NodeRole.REPLICA, node2.getRole()); + _helper.awaitRemoteNodes(node2, 1); + + BDBHARemoteReplicationNode<?> remote = _helper.findRemoteNode(node2, node1.getName()); + + final AtomicInteger permittedNodesChangeCounter = new AtomicInteger(); + final CountDownLatch _permittedNodesLatch = new CountDownLatch(1); + node2.addChangeListener(new NoopConfigurationChangeListener() + { + @Override + public void attributeSet(ConfiguredObject<?> object, String attributeName, Object oldAttributeValue, Object newAttributeValue) + { + if (attributeName.equals(BDBHAVirtualHostNode.PERMITTED_NODES)) + { + permittedNodesChangeCounter.incrementAndGet(); + _permittedNodesLatch.countDown(); + } + } + }); + List<String> permittedNodes = new ArrayList<>(node1.getPermittedNodes()); + permittedNodes.add("localhost:5000"); + node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes)); + + assertTrue("Permitted nodes were not changed on Replica", _permittedNodesLatch.await(10, TimeUnit.SECONDS)); + assertEquals("Not the same permitted nodes", new HashSet<>(node1.getPermittedNodes()), new HashSet<>(node2.getPermittedNodes())); + assertEquals("Unexpected counter of changes permitted nodes", 1, permittedNodesChangeCounter.get()); + + // change the order of permitted nodes + Collections.swap(permittedNodes, 0, 2); + node1.setAttributes(Collections.<String, Object>singletonMap(BDBHAVirtualHostNode.PERMITTED_NODES, permittedNodes)); + + // make sure that node2 onNodeState was invoked by performing transaction on master and making sure that it was replicated + performTransactionAndAwaitForRemoteNodeToGetAware(node1, remote); + + // perform transaction second time because permitted nodes are changed after last transaction id + performTransactionAndAwaitForRemoteNodeToGetAware(node1, remote); + assertEquals("Unexpected counter of changes permitted nodes", 1, permittedNodesChangeCounter.get()); + } - _helper.awaitRemoteNodes(node1, 1); + private void performTransactionAndAwaitForRemoteNodeToGetAware(BDBHAVirtualHostNode<?> node1, BDBHARemoteReplicationNode<?> remote) throws InterruptedException + { + new DatabasePinger().pingDb(((BDBConfigurationStore)node1.getConfigurationStore()).getEnvironmentFacade()); - BDBHARemoteReplicationNode<?> remote = _helper.findRemoteNode(node1, node2.getName()); - remote.delete(); + int waitCounter = 100; + while ( remote.getLastKnownReplicationTransactionId() != node1.getLastKnownReplicationTransactionId() && (waitCounter--) != 0) + { + Thread.sleep(100l); + } + assertEquals("Last transaction was not replicated", new Long(remote.getLastKnownReplicationTransactionId()), node1.getLastKnownReplicationTransactionId() ); } public void testIntruderConnected() throws Exception @@ -587,4 +709,87 @@ public class BDBHAVirtualHostNodeTest ex assertTrue("Intruder protection was not triggered during expected timeout", stopLatch.await(20, TimeUnit.SECONDS)); } + public void testValidateOnCreateForNonExistingHelperNode() throws Exception + { + int node1PortNumber = findFreePort(); + int node2PortNumber = getNextAvailable(node1PortNumber + 1); + + + Map<String, Object> attributes = _helper.createNodeAttributes("node1", "group", "localhost:" + node1PortNumber, + "localhost:" + node2PortNumber, "node2", node1PortNumber, node1PortNumber, node2PortNumber); + try + { + _helper.createAndStartHaVHN(attributes); + fail("Node creation should fail because of invalid helper address"); + } + catch(IllegalConfigurationException e) + { + assertEquals("Unexpected exception on connection to non-existing helper address", + String.format("Cannot connect to existing node '%s' at '%s'", "node2", "localhost:" + node2PortNumber), e.getMessage()); + } + } + + public void testValidateOnCreateForAlreadyBoundAddress() throws Exception + { + int node1PortNumber = findFreePort(); + + ServerSocket serverSocket = null; + try + { + serverSocket = new ServerSocket(); + serverSocket.setReuseAddress(true); + serverSocket.bind(new InetSocketAddress("localhost", node1PortNumber)); + + + Map<String, Object> attributes = _helper.createNodeAttributes("node1", "group", "localhost:" + node1PortNumber, + "localhost:" + node1PortNumber, "node2", node1PortNumber, node1PortNumber); + try + { + _helper.createAndStartHaVHN(attributes); + fail("Node creation should fail because of invalid address"); + } + catch(IllegalConfigurationException e) + { + assertEquals("Unexpected exception on attempt to create node with already bound address", + String.format("Cannot bind to address '%s'. Address is already in use.", "localhost:" + node1PortNumber), e.getMessage()); + } + } + finally + { + if (serverSocket != null) + { + serverSocket.close(); + } + } + } + + public void testValidateOnCreateForInvalidStorePath() throws Exception + { + int node1PortNumber = findFreePort(); + + File storeBaseFolder = TestFileUtils.createTestDirectory(); + File file = new File(storeBaseFolder, getTestName()); + file.createNewFile(); + File storePath = new File(file, "test"); + try + { + Map<String, Object> attributes = _helper.createNodeAttributes("node1", "group", "localhost:" + node1PortNumber, + "localhost:" + node1PortNumber, "node2", node1PortNumber, node1PortNumber); + attributes.put(BDBHAVirtualHostNode.STORE_PATH, storePath.getAbsoluteFile()); + try + { + _helper.createAndStartHaVHN(attributes); + fail("Node creation should fail because of invalid store path"); + } + catch (IllegalConfigurationException e) + { + assertEquals("Unexpected exception on attempt to create environment in invalid location", + String.format("Store path '%s' is not a folder", storePath.getAbsoluteFile()), e.getMessage()); + } + } + finally + { + FileUtils.delete(storeBaseFolder, true); + } + } } Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeOperationalLoggingTest.java Fri Oct 10 09:59:55 2014 @@ -87,6 +87,9 @@ public class BDBHAVirtualHostNodeOperati _helper.assertNodeRole(node1, NodeRole.MASTER); + // stop node to avoid running into race when role change is reported after we performed the check + node1.stop(); + assertEquals("Unexpected VHN log subject", "[grp(/group)/vhn(/node1)] ", node1.getVirtualHostNodeLogSubject().getLogString()); assertEquals("Unexpected group log subject", "[grp(/group)] ", node1.getGroupLogSubject().getLogString()); Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeTestHelper.java Fri Oct 10 09:59:55 2014 @@ -279,11 +279,14 @@ public class BDBHAVirtualHostNodeTestHel node1Attributes.put(BDBHAVirtualHostNode.ADDRESS, address); node1Attributes.put(BDBHAVirtualHostNode.HELPER_ADDRESS, helperAddress); node1Attributes.put(BDBHAVirtualHostNode.STORE_PATH, getMessageStorePath() + File.separator + nodeName); - node1Attributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, helperNodeNode); if (address.equals(helperAddress)) { node1Attributes.put(BDBHAVirtualHostNode.PERMITTED_NODES, getPermittedNodes(ports)); } + else + { + node1Attributes.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, helperNodeNode); + } Map<String, String> context = new HashMap<String, String>(); context.put(ReplicationConfig.REPLICA_ACK_TIMEOUT, "2 s"); Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/BDBHAVirtualHostNodeRestTest.java Fri Oct 10 09:59:55 2014 @@ -326,7 +326,10 @@ public class BDBHAVirtualHostNodeRestTes nodeData.put(BDBHAVirtualHostNode.GROUP_NAME, _hostName); nodeData.put(BDBHAVirtualHostNode.ADDRESS, "localhost:" + nodePort); nodeData.put(BDBHAVirtualHostNode.HELPER_ADDRESS, "localhost:" + helperPort); - nodeData.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, NODE1); + if (nodePort != helperPort) + { + nodeData.put(BDBHAVirtualHostNode.HELPER_NODE_NAME, NODE1); + } Map<String,String> context = new HashMap<>(); nodeData.put(BDBHAVirtualHostNode.CONTEXT, context); Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/bdbstore/systests/src/test/java/org/apache/qpid/server/store/berkeleydb/replication/MultiNodeTest.java Fri Oct 10 09:59:55 2014 @@ -166,8 +166,8 @@ public class MultiNodeTest extends QpidB // New connections should now fail as vhost will be unavailable try { - getConnection(_negativeFailoverUrl); - fail("Exception not thrown"); + Connection unexpectedConnection = getConnection(_negativeFailoverUrl); + fail("Got unexpected connection to node in group without quorum " + unexpectedConnection); } catch (JMSException je) { Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java Fri Oct 10 09:59:55 2014 @@ -117,9 +117,9 @@ public class SystemConfigFactoryGenerato pw.println("import org.apache.qpid.server.configuration.updater.TaskExecutor;"); pw.println("import org.apache.qpid.server.logging.EventLogger;"); pw.println("import org.apache.qpid.server.logging.LogRecorder;"); - pw.println("import org.apache.qpid.server.model.SystemConfig;"); + pw.println("import org.apache.qpid.server.model.BrokerShutdownProvider;"); pw.println("import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry;"); - pw.println(); + pw.println("import org.apache.qpid.server.model.SystemConfig;"); pw.println("import org.apache.qpid.server.plugin.PluggableService;"); pw.println("import org.apache.qpid.server.plugin.SystemConfigFactory;"); pw.println(); @@ -140,9 +140,10 @@ public class SystemConfigFactoryGenerato pw.println(" public "+objectSimpleName+" newInstance(final TaskExecutor taskExecutor,"); pw.println(" final EventLogger eventLogger,"); pw.println(" final LogRecorder logRecorder,"); - pw.println(" final BrokerOptions brokerOptions)"); + pw.println(" final BrokerOptions brokerOptions,"); + pw.println(" final BrokerShutdownProvider brokerShutdownProvider)"); pw.println(" {"); - pw.println(" return new "+objectSimpleName+"(taskExecutor, eventLogger, logRecorder, brokerOptions);"); + pw.println(" return new "+objectSimpleName+"(taskExecutor, eventLogger, logRecorder, brokerOptions, brokerShutdownProvider);"); pw.println(" }"); pw.println("}"); Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java Fri Oct 10 09:59:55 2014 @@ -40,6 +40,7 @@ import org.apache.qpid.server.logging.Lo import org.apache.qpid.server.logging.SystemOutMessageLogger; import org.apache.qpid.server.logging.log4j.LoggingManagementFacade; import org.apache.qpid.server.logging.messages.BrokerMessages; +import org.apache.qpid.server.model.BrokerShutdownProvider; import org.apache.qpid.server.model.SystemConfig; import org.apache.qpid.server.plugin.PluggableFactoryLoader; import org.apache.qpid.server.plugin.SystemConfigFactory; @@ -48,7 +49,7 @@ import org.apache.qpid.server.registry.I import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.store.DurableConfigurationStore; -public class Broker +public class Broker implements BrokerShutdownProvider { private static final Logger LOGGER = Logger.getLogger(Broker.class); @@ -143,7 +144,7 @@ public class Broker LogRecorder logRecorder = new LogRecorder(); _taskExecutor.start(); - SystemConfig systemConfig = configFactory.newInstance(_taskExecutor, _eventLogger, logRecorder, options); + SystemConfig systemConfig = configFactory.newInstance(_taskExecutor, _eventLogger, logRecorder, options, this); systemConfig.open(); DurableConfigurationStore store = systemConfig.getConfigurationStore(); Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java Fri Oct 10 09:59:55 2014 @@ -29,9 +29,12 @@ import java.util.concurrent.CopyOnWriteA import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; +import org.apache.qpid.server.configuration.IllegalConfigurationException; import org.apache.qpid.server.configuration.updater.VoidTask; import org.apache.qpid.server.exchange.AbstractExchange; import org.apache.qpid.server.exchange.ExchangeImpl; +import org.apache.qpid.server.filter.AMQInvalidArgumentException; +import org.apache.qpid.server.filter.FilterSupport; import org.apache.qpid.server.logging.EventLogger; import org.apache.qpid.server.logging.messages.BindingMessages; import org.apache.qpid.server.logging.subjects.BindingLogSubject; @@ -269,4 +272,23 @@ public class BindingImpl ); } + + @Override + public void validateOnCreate() + { + AMQQueue queue = getAMQQueue(); + Map<String, Object> arguments = getArguments(); + if (arguments!=null && !arguments.isEmpty() && FilterSupport.argumentsContainFilter(arguments)) + { + try + { + FilterSupport.createMessageFilter(arguments, queue); + } + catch (AMQInvalidArgumentException e) + { + throw new IllegalConfigurationException(e.getMessage(), e); + } + } + } + } Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java Fri Oct 10 09:59:55 2014 @@ -118,16 +118,6 @@ public abstract class AbstractExchange<T throw new IllegalArgumentException("Unknown attributes provided: " + providedAttributeNames); } _virtualHost = vhost; - // check ACL - try - { - _virtualHost.getSecurityManager().authoriseCreateExchange(this); - } - catch (AccessControlException e) - { - deleted(); - throw e; - } _logSubject = new ExchangeLogSubject(this, this.getVirtualHost()); @@ -145,6 +135,12 @@ public abstract class AbstractExchange<T } @Override + public void validateOnCreate() + { + _virtualHost.getSecurityManager().authoriseCreateExchange(this); + } + + @Override public void onValidate() { super.onValidate(); @@ -756,7 +752,7 @@ public abstract class AbstractExchange<T final Map<String, Object> oldArguments); - @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE) + @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE) private void activate() { setState(State.ACTIVE); Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java Fri Oct 10 09:59:55 2014 @@ -47,6 +47,7 @@ import java.util.concurrent.atomic.Atomi import javax.security.auth.Subject; +import org.apache.log4j.Logger; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.Version; @@ -72,6 +73,8 @@ import org.apache.qpid.util.Strings; public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> implements ConfiguredObject<X> { + private static final Logger LOGGER = Logger.getLogger(AbstractConfiguredObject.class); + private static final Map<Class, Object> SECURE_VALUES; public static final String SECURED_STRING_VALUE = "********"; @@ -156,9 +159,10 @@ public abstract class AbstractConfigured private final OwnAttributeResolver _attributeResolver = new OwnAttributeResolver(this); - @ManagedAttributeField( afterSet = "attainStateIfResolved" ) + @ManagedAttributeField( afterSet = "attainStateIfOpenedOrReopenFailed" ) private State _desiredState; private boolean _openComplete; + private boolean _openFailed; private volatile State _state = State.UNINITIALIZED; protected static Map<Class<? extends ConfiguredObject>, ConfiguredObject<?>> parentsMap(ConfiguredObject<?>... parents) @@ -404,10 +408,19 @@ public abstract class AbstractConfigured { if(_dynamicState.compareAndSet(DynamicState.UNINIT, DynamicState.OPENED)) { - doResolution(true); - doValidation(true); - doOpening(true); - doAttainState(); + _openFailed = false; + OpenExceptionHandler exceptionHandler = new OpenExceptionHandler(); + try + { + doResolution(true, exceptionHandler); + doValidation(true, exceptionHandler); + doOpening(true, exceptionHandler); + doAttainState(exceptionHandler); + } + catch(RuntimeException e) + { + exceptionHandler.handleException(e, this); + } } } @@ -485,18 +498,76 @@ public abstract class AbstractConfigured _lastUpdatedTime = currentTime; _createdTime = currentTime; - doResolution(true); - doValidation(true); + CreateExceptionHandler createExceptionHandler = new CreateExceptionHandler(); + try + { + doResolution(true, createExceptionHandler); + doValidation(true, createExceptionHandler); + validateOnCreate(); + registerWithParents(); + } + catch(RuntimeException e) + { + createExceptionHandler.handleException(e, this); + } + + AbstractConfiguredObjectExceptionHandler unregisteringExceptionHandler = new CreateExceptionHandler(true); + try + { + doCreation(true, unregisteringExceptionHandler); + doOpening(true, unregisteringExceptionHandler); + doAttainState(unregisteringExceptionHandler); + } + catch(RuntimeException e) + { + unregisteringExceptionHandler.handleException(e, this); + } + } + } + + protected void validateOnCreate() + { + } + + protected final void handleExceptionOnOpen(RuntimeException e) + { + if (e instanceof ServerScopedRuntimeException) + { + throw e; + } + + LOGGER.error("Failed to open object with name '" + getName() + "'. Object will be put into ERROR state.", e); - registerWithParents(); + try + { + onExceptionInOpen(e); + } + catch (RuntimeException re) + { + LOGGER.error("Unexpected exception while handling exception on open for " + getName(), e); + } - doCreation(true); - doOpening(true); - doAttainState(); + if (!_openComplete) + { + _openFailed = true; + _dynamicState.compareAndSet(DynamicState.OPENED, DynamicState.UNINIT); } + + //TODO: children of ERRORED CO will continue to remain in ACTIVE state + setState(State.ERRORED); + } + + /** + * Callback method to perform ConfiguredObject specific exception handling on exception in open. + * <p/> + * The method is not expected to throw any runtime exception. + * @param e open exception + */ + protected void onExceptionInOpen(RuntimeException e) + { } - private void doAttainState() + private void doAttainState(final AbstractConfiguredObjectExceptionHandler exceptionHandler) { applyToChildren(new Action<ConfiguredObject<?>>() { @@ -505,14 +576,25 @@ public abstract class AbstractConfigured { if (child instanceof AbstractConfiguredObject) { - ((AbstractConfiguredObject) child).doAttainState(); + AbstractConfiguredObject configuredObject = (AbstractConfiguredObject) child; + if (configuredObject._dynamicState.get() == DynamicState.OPENED) + { + try + { + configuredObject.doAttainState(exceptionHandler); + } + catch (RuntimeException e) + { + exceptionHandler.handleException(e, configuredObject); + } + } } } }); attainState(); } - protected void doOpening(final boolean skipCheck) + protected void doOpening(boolean skipCheck, final AbstractConfiguredObjectExceptionHandler exceptionHandler) { if(skipCheck || _dynamicState.compareAndSet(DynamicState.UNINIT,DynamicState.OPENED)) { @@ -523,9 +605,17 @@ public abstract class AbstractConfigured @Override public void performAction(final ConfiguredObject<?> child) { - if (child instanceof AbstractConfiguredObject) + if (child.getState() != State.ERRORED && child instanceof AbstractConfiguredObject) { - ((AbstractConfiguredObject) child).doOpening(false); + AbstractConfiguredObject configuredObject = (AbstractConfiguredObject) child; + try + { + configuredObject.doOpening(false, exceptionHandler); + } + catch (RuntimeException e) + { + exceptionHandler.handleException(e, configuredObject); + } } } }); @@ -533,7 +623,7 @@ public abstract class AbstractConfigured } } - protected final void doValidation(final boolean skipCheck) + protected final void doValidation(final boolean skipCheck, final AbstractConfiguredObjectExceptionHandler exceptionHandler) { if(skipCheck || _dynamicState.get() != DynamicState.OPENED) { @@ -542,9 +632,17 @@ public abstract class AbstractConfigured @Override public void performAction(final ConfiguredObject<?> child) { - if (child instanceof AbstractConfiguredObject) + if (child.getState() != State.ERRORED && child instanceof AbstractConfiguredObject) { - ((AbstractConfiguredObject) child).doValidation(false); + AbstractConfiguredObject configuredObject = (AbstractConfiguredObject) child; + try + { + configuredObject.doValidation(false, exceptionHandler); + } + catch (RuntimeException e) + { + exceptionHandler.handleException(e, configuredObject); + } } } }); @@ -552,20 +650,28 @@ public abstract class AbstractConfigured } } - protected final void doResolution(final boolean skipCheck) + protected final void doResolution(boolean skipCheck, final AbstractConfiguredObjectExceptionHandler exceptionHandler) { if(skipCheck || _dynamicState.get() != DynamicState.OPENED) { onResolve(); postResolve(); - applyToChildren(new Action<ConfiguredObject<?>>() + applyToChildren(new Action() { @Override - public void performAction(final ConfiguredObject<?> child) + public void performAction(Object child) { if (child instanceof AbstractConfiguredObject) { - ((AbstractConfiguredObject) child).doResolution(false); + AbstractConfiguredObject configuredObject = (AbstractConfiguredObject) child; + try + { + configuredObject.doResolution(false, exceptionHandler); + } + catch (RuntimeException e) + { + exceptionHandler.handleException(e, configuredObject); + } } } }); @@ -576,7 +682,7 @@ public abstract class AbstractConfigured { } - protected final void doCreation(final boolean skipCheck) + protected final void doCreation(final boolean skipCheck, final AbstractConfiguredObjectExceptionHandler exceptionHandler) { if(skipCheck || _dynamicState.get() != DynamicState.OPENED) { @@ -588,7 +694,15 @@ public abstract class AbstractConfigured { if (child instanceof AbstractConfiguredObject) { - ((AbstractConfiguredObject) child).doCreation(false); + AbstractConfiguredObject configuredObject =(AbstractConfiguredObject) child; + try + { + configuredObject.doCreation(false, exceptionHandler); + } + catch (RuntimeException e) + { + exceptionHandler.handleException(e, configuredObject); + } } } }); @@ -711,12 +825,16 @@ public abstract class AbstractConfigured } } - private void attainStateIfResolved() + private void attainStateIfOpenedOrReopenFailed() { - if(_openComplete) + if (_openComplete || getDesiredState() == State.DELETED) { attainState(); } + else if (_openFailed) + { + open(); + } } protected void onOpen() @@ -830,8 +948,13 @@ public abstract class AbstractConfigured State state = getState(); if(desiredState == getDesiredState() && desiredState != state) { - attainState(); - return getState(); + attainStateIfOpenedOrReopenFailed(); + final State currentState = getState(); + if (currentState != state) + { + notifyStateChanged(state, currentState); + } + return currentState; } else { @@ -1217,7 +1340,6 @@ public abstract class AbstractConfigured { if (_childrenByName.get(categoryClass).containsKey(name)) { - child.delete(); throw new DuplicateNameException(child); } _childrenByName.get(categoryClass).put(name, child); @@ -1756,4 +1878,54 @@ public abstract class AbstractConfigured return _name; } } + + interface AbstractConfiguredObjectExceptionHandler + { + void handleException(RuntimeException exception, AbstractConfiguredObject<?> source); + } + + private static class OpenExceptionHandler implements AbstractConfiguredObjectExceptionHandler + { + @Override + public void handleException(RuntimeException exception, AbstractConfiguredObject<?> source) + { + source.handleExceptionOnOpen(exception); + } + } + + private static class CreateExceptionHandler implements AbstractConfiguredObjectExceptionHandler + { + private final boolean _unregister; + + private CreateExceptionHandler() + { + this(false); + } + + private CreateExceptionHandler(boolean unregister) + { + _unregister = unregister; + } + + @Override + + public void handleException(RuntimeException exception, AbstractConfiguredObject<?> source) + { + try + { + if (source.getState() != State.DELETED) + { + source.delete(); + } + } + finally + { + if (_unregister) + { + source.unregister(false); + } + throw exception; + } + } + } } Modified: qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java URL: http://svn.apache.org/viewvc/qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java?rev=1630749&r1=1630748&r2=1630749&view=diff ============================================================================== --- qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java (original) +++ qpid/branches/QPID-6125-ProtocolRefactoring/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java Fri Oct 10 09:59:55 2014 @@ -49,13 +49,15 @@ public abstract class AbstractSystemConf private final EventLogger _eventLogger; private final LogRecorder _logRecorder; private final BrokerOptions _brokerOptions; + private final BrokerShutdownProvider _brokerShutdownProvider; private DurableConfigurationStore _configurationStore; public AbstractSystemConfig(final TaskExecutor taskExecutor, final EventLogger eventLogger, final LogRecorder logRecorder, - final BrokerOptions brokerOptions) + final BrokerOptions brokerOptions, + final BrokerShutdownProvider brokerShutdownProvider) { super(parentsMap(), updateAttributes(brokerOptions.convertToSystemAttributes()), @@ -64,6 +66,7 @@ public abstract class AbstractSystemConf getTaskExecutor().start(); _logRecorder = logRecorder; _brokerOptions = brokerOptions; + _brokerShutdownProvider = brokerShutdownProvider; } private static Map<String, Object> updateAttributes(Map<String, Object> attributes) @@ -212,4 +215,9 @@ public abstract class AbstractSystemConf } + @Override + public BrokerShutdownProvider getBrokerShutdownProvider() + { + return _brokerShutdownProvider; + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org