qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From oru...@apache.org
Subject svn commit: r1628867 [1/3] - in /qpid/trunk/qpid/java: bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/ bdbstore/src/test/java/org/apache/qpid/server/store/berkele...
Date Wed, 01 Oct 2014 23:48:15 GMT
Author: orudyy
Date: Wed Oct  1 23:48:14 2014
New Revision: 1628867

URL: http://svn.apache.org/r1628867
Log:
QPID-6126: Add ability to validate CO attributes on creation, transit COs into ERRORED state if exception occurs on recovery, allow ERRORED CO restart after remediation of configuration problem

Added:
    qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/
    qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/
    qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java
    qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java
      - copied, changed from r1628743, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/binding/
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/port/
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java
    qpid/trunk/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java
Modified:
    qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java
    qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
    qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
    qpid/trunk/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java
    qpid/trunk/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java
    qpid/trunk/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java
    qpid/trunk/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
    qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
    qpid/trunk/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java
    qpid/trunk/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java
    qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
    qpid/trunk/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/PortRestTest.java

Modified: qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java Wed Oct  1 23:48:14 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/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java Wed Oct  1 23:48:14 2014
@@ -20,7 +20,9 @@
  */
 package org.apache.qpid.server.virtualhostnode.berkeleydb;
 
+import java.io.File;
 import java.net.InetSocketAddress;
+import java.nio.file.Files;
 import java.security.PrivilegedAction;
 import java.text.MessageFormat;
 import java.util.ArrayList;
@@ -74,6 +76,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;
@@ -280,20 +283,6 @@ public class BDBHAVirtualHostNodeImpl ex
     public void onCreate()
     {
         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;
-            }
-        }
 
         getEventLogger().message(getVirtualHostNodeLogSubject(), HighAvailabilityMessages.CREATED());
     }
@@ -435,19 +424,102 @@ public class BDBHAVirtualHostNodeImpl ex
     public void onValidate()
     {
         super.onValidate();
+        validatePermittedNodes(_permittedNodes);
+    }
+
+    @Override
+    protected void postResolve()
+    {
+        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();
 
-        validatePermittedNodes(_permittedNodes);
+        validateAddress();
+
+        validateStorePath();
+
+        if (!isFirstNodeInAGroup())
+        {
+            // validate that helper address points to valid node
+            // we need _permittedNodes for the further validation in onValidate
+            _permittedNodes = new ArrayList<>(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();
+
+        if (address == null || "".equals(address))
+        {
+            throw new IllegalConfigurationException("Node address is not set");
+        }
+
+        String[] tokens = address.split(":");
+        if (tokens.length != 2)
+        {
+            throw new IllegalConfigurationException(String.format("Invalid address specified '%s'. ", address));
+        }
+
+        String hostName = tokens[0];
+        if ("".equals(hostName.trim()))
+        {
+            throw new IllegalConfigurationException(String.format("Invalid address specified '%s'. ", address));
+        }
+
+        int port = -1;
+        try
+        {
+            port = Integer.parseInt(tokens[1]);
+        }
+        catch(Exception e)
+        {
+            throw new IllegalConfigurationException(String.format("Invalid port is specified in address '%s'. ", address));
+        }
+        if (!PortUtil.isPortAvailable(hostName, port))
+        {
+            throw new IllegalConfigurationException(String.format("Cannot bind to address '%s'. Address is already in use.", address));
+        }
+    }
+
+
+
     private void onMaster()
     {
         try
@@ -761,7 +833,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,28 +844,32 @@ 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)
+            {
+                throw new IllegalArgumentException(String.format("The current group node '%s' cannot be removed from '%s' as its already a group member", missingNodeAddress, PERMITTED_NODES));
+            }
         }
 
         for (String permittedNode: proposedPermittedNodes)

Modified: qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java (original)
+++ qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java Wed Oct  1 23:48:14 2014
@@ -23,6 +23,8 @@ 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;
@@ -53,6 +55,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
 {
@@ -587,4 +591,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 '%s'", "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);
+        }
+    }
 }

Added: qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java?rev=1628867&view=auto
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java (added)
+++ qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java Wed Oct  1 23:48:14 2014
@@ -0,0 +1,106 @@
+/*
+ *
+ * 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.virtualhost.berkeleydb;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.BrokerModel;
+import org.apache.qpid.server.model.VirtualHostNode;
+import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+import org.apache.qpid.util.FileUtils;
+
+public class BDBVirtualHostImplTest extends QpidTestCase
+{
+    private File _storePath;
+    private VirtualHostNode<?> _node;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        Broker broker = BrokerTestHelper.createBrokerMock();
+
+        TaskExecutor taskExecutor = CurrentThreadTaskExecutor.newStartedInstance();
+        when(broker.getTaskExecutor()).thenReturn(taskExecutor);
+
+        _storePath = TestFileUtils.createTestDirectory();
+
+        _node = mock(VirtualHostNode.class);
+        when(_node.getParent(Broker.class)).thenReturn(broker);
+        when(_node.getModel()).thenReturn(BrokerModel.getInstance());
+        when(_node.getTaskExecutor()).thenReturn(taskExecutor);
+        when(_node.getConfigurationStore()).thenReturn(mock(DurableConfigurationStore.class));
+        when(_node.getId()).thenReturn(UUID.randomUUID());
+    }
+
+    @Override
+    public void  tearDown() throws Exception
+    {
+        try
+        {
+            if (_storePath != null)
+            {
+                FileUtils.delete(_storePath, true);
+            }
+        }
+        finally
+        {
+            super.tearDown();
+        }
+    }
+
+    public void testValidateOnCreateForInvalidStorePath() throws Exception
+    {
+        String hostName = getTestName();
+        File file = new File(_storePath + File.separator + hostName);
+        assertTrue("Empty file is not created", file.createNewFile());
+        Map<String, Object> attributes = new HashMap<>();
+        attributes.put(BDBVirtualHost.ID, UUID.randomUUID());
+        attributes.put(BDBVirtualHost.TYPE, BDBVirtualHostImpl.VIRTUAL_HOST_TYPE);
+        attributes.put(BDBVirtualHost.NAME, hostName);
+        attributes.put(BDBVirtualHost.STORE_PATH, file.getAbsoluteFile());
+
+        BDBVirtualHostImpl host = new BDBVirtualHostImpl(attributes, _node);
+        try
+        {
+            host.create();
+            fail("Cannot create DBD virtual host from existing empty file");
+        }
+        catch (IllegalConfigurationException e)
+        {
+            assertTrue("Unexpected exception " + e.getMessage(), e.getMessage().startsWith("Cannot open virtual host message store"));
+        }
+    }
+
+}

Added: qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java?rev=1628867&view=auto
==============================================================================
--- qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java (added)
+++ qpid/trunk/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java Wed Oct  1 23:48:14 2014
@@ -0,0 +1,92 @@
+/*
+ *
+ * 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.berkeleydb;
+
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.util.BrokerTestHelper;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+import org.apache.qpid.util.FileUtils;
+
+public class BDBVirtualHostNodeTest extends QpidTestCase
+{
+    private Broker<?> _broker;
+    private File _storePath;
+
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        _broker = BrokerTestHelper.createBrokerMock();
+        when(_broker.getTaskExecutor()).thenReturn(CurrentThreadTaskExecutor.newStartedInstance());
+
+        _storePath = TestFileUtils.createTestDirectory();
+    }
+
+    @Override
+    public void  tearDown() throws Exception
+    {
+        try
+        {
+            if (_storePath != null)
+            {
+                FileUtils.delete(_storePath, true);
+            }
+        }
+        finally
+        {
+            super.tearDown();
+        }
+    }
+
+    public void testValidateOnCreateForInvalidStorePath() throws Exception
+    {
+        String nodeName = getTestName();
+        File file = new File(_storePath + File.separator + nodeName);
+        assertTrue("Empty file is not created", file.createNewFile());
+        Map<String, Object> attributes = new HashMap<>();
+        attributes.put(BDBVirtualHostNode.ID, UUID.randomUUID());
+        attributes.put(BDBVirtualHostNode.TYPE, BDBVirtualHostNodeImpl.VIRTUAL_HOST_NODE_TYPE);
+        attributes.put(BDBVirtualHostNode.NAME, nodeName);
+        attributes.put(BDBVirtualHostNode.STORE_PATH, file.getAbsolutePath());
+
+        BDBVirtualHostNodeImpl node = new BDBVirtualHostNodeImpl(attributes, _broker);
+        try
+        {
+            node.create();
+            fail("Cannot create DBD node from existing empty file");
+        }
+        catch (IllegalConfigurationException e)
+        {
+            assertTrue("Unexpected exception " + e.getMessage(), e.getMessage().startsWith("Cannot open node configuration store"));
+        }
+    }
+
+}

Modified: qpid/trunk/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java (original)
+++ qpid/trunk/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java Wed Oct  1 23:48:14 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/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java Wed Oct  1 23:48:14 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/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java Wed Oct  1 23:48:14 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/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java Wed Oct  1 23:48:14 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/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java Wed Oct  1 23:48:14 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,84 @@ public abstract class AbstractConfigured
             _lastUpdatedTime = currentTime;
             _createdTime = currentTime;
 
-            doResolution(true);
-            doValidation(true);
+            CreateExceptionHandler createExceptionHandler = new CreateExceptionHandler();
+            try
+            {
+                doResolution(true, createExceptionHandler);
+                validateOnCreate();
+                doValidation(true, createExceptionHandler);
+                registerWithParents();
+            }
+            catch(RuntimeException e)
+            {
+                createExceptionHandler.handleException(e, this);
+            }
+
+            AbstractConfiguredObjectExceptionHandler unregisteringExceptionHandler = new CreateExceptionHandler(true);
+            try
+            {
+                doCreation(true, unregisteringExceptionHandler);
+            }
+            catch(RuntimeException e)
+            {
+                unregisteringExceptionHandler.handleException(e, this);
+            }
+
+            OpenExceptionHandler openExceptionHandler = new OpenExceptionHandler();
+            try
+            {
+                doOpening(true, openExceptionHandler);
+                doAttainState(openExceptionHandler);
+            }
+            catch(RuntimeException e)
+            {
+                openExceptionHandler.handleException(e, this);
+            }
+        }
+    }
+
+    protected void validateOnCreate()
+    {
+    }
+
+    protected final void handleExceptionOnOpen(RuntimeException e, AbstractConfiguredObject<?> configuredObject)
+    {
+        if (e instanceof ServerScopedRuntimeException)
+        {
+            throw e;
+        }
 
-            registerWithParents();
+        LOGGER.error("Exception occurred on open for " + configuredObject.getName(), e);
 
-            doCreation(true);
-            doOpening(true);
-            doAttainState();
+        try
+        {
+            configuredObject.onExceptionInOpen(e);
+        }
+        catch (RuntimeException re)
+        {
+            LOGGER.error("Unexpected exception while handling exception on open for " + configuredObject.getName(), e);
         }
+
+        if (!configuredObject._openComplete)
+        {
+            configuredObject._openFailed = true;
+            configuredObject._dynamicState.compareAndSet(DynamicState.OPENED, DynamicState.UNINIT);
+        }
+        configuredObject.closeChildren();
+        configuredObject.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 +584,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))
         {
@@ -525,7 +615,15 @@ public abstract class AbstractConfigured
                 {
                     if (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 +631,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)
         {
@@ -544,7 +642,15 @@ public abstract class AbstractConfigured
                 {
                     if (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 +658,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 +690,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 +702,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 +833,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,7 +956,7 @@ public abstract class AbstractConfigured
                                 State state = getState();
                                 if(desiredState == getDesiredState() && desiredState != state)
                                 {
-                                    attainState();
+                                    attainStateIfOpenedOrReopenFailed();
                                     return getState();
                                 }
                                 else
@@ -1217,7 +1343,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 +1881,54 @@ public abstract class AbstractConfigured
             return _name;
         }
     }
+
+    interface AbstractConfiguredObjectExceptionHandler
+    {
+        void handleException(RuntimeException exception, AbstractConfiguredObject<?> source);
+    }
+
+    private class OpenExceptionHandler implements AbstractConfiguredObjectExceptionHandler
+    {
+        @Override
+        public void handleException(RuntimeException exception, AbstractConfiguredObject<?> source)
+        {
+            handleExceptionOnOpen(exception, source);
+        }
+    }
+
+    private class CreateExceptionHandler implements AbstractConfiguredObjectExceptionHandler
+    {
+        private boolean _unregister;
+
+        private CreateExceptionHandler()
+        {
+            this(false);
+        }
+
+        private CreateExceptionHandler(boolean unregister)
+        {
+            this._unregister = unregister;
+        }
+
+        @Override
+
+        public void handleException(RuntimeException exception, AbstractConfiguredObject<?> source)
+        {
+            if (source.getState() != State.DELETED)
+            {
+                try
+                {
+                    source.delete();
+                }
+                finally
+                {
+                    if (_unregister)
+                    {
+                        source.unregister(false);
+                    }
+                    throw exception;
+                }
+            }
+        }
+    }
 }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java Wed Oct  1 23:48:14 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;
+    }
 }

Copied: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java (from r1628743, qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java?p2=qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java&p1=qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java&r1=1628743&r2=1628867&rev=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java Wed Oct  1 23:48:14 2014
@@ -20,21 +20,7 @@
  */
 package org.apache.qpid.server.model;
 
-import org.apache.qpid.server.BrokerOptions;
-import org.apache.qpid.server.logging.EventLogger;
-import org.apache.qpid.server.logging.LogRecorder;
-import org.apache.qpid.server.store.DurableConfigurationStore;
-
-@ManagedObject (creatable = false)
-public interface SystemConfig<X extends SystemConfig<X>> extends ConfiguredObject<X>
+public interface BrokerShutdownProvider
 {
-    EventLogger getEventLogger();
-
-    BrokerOptions getBrokerOptions();
-
-    Broker getBroker();
-
-    LogRecorder getLogRecorder();
-
-    DurableConfigurationStore getConfigurationStore();
+    void shutdown();
 }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java Wed Oct  1 23:48:14 2014
@@ -38,9 +38,10 @@ public class JsonSystemConfigImpl extend
     public JsonSystemConfigImpl(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);
     }
 
     public String getStorePath()

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java Wed Oct  1 23:48:14 2014
@@ -37,4 +37,6 @@ public interface SystemConfig<X extends 
     LogRecorder getLogRecorder();
 
     DurableConfigurationStore getConfigurationStore();
+
+    BrokerShutdownProvider getBrokerShutdownProvider();
 }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java Wed Oct  1 23:48:14 2014
@@ -943,6 +943,28 @@ public class BrokerAdapter extends Abstr
         _eventLogger = eventLogger;
     }
 
+    @Override
+    protected void onExceptionInOpen(RuntimeException e)
+    {
+        SystemConfig systemConfig = getParent(SystemConfig.class);
+        if (systemConfig != null)
+        {
+            BrokerShutdownProvider shutdownProvider = systemConfig.getBrokerShutdownProvider();
+            if (shutdownProvider != null)
+            {
+                shutdownProvider.shutdown();
+            }
+            else
+            {
+                throw new IllegalStateException("Shutdown provider is not found in system config");
+            }
+        }
+        else
+        {
+            throw new IllegalStateException("SystemConfig is not found among broker parents");
+        }
+    }
+
     public void registerMessageDelivered(long messageSize)
     {
         _messagesDelivered.registerEvent(1L);

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java Wed Oct  1 23:48:14 2014
@@ -114,22 +114,27 @@ public class FileBasedGroupProviderImpl
             throw new IllegalArgumentException("Cannot change the path");
         }
     }
+
+    @Override
     protected void onOpen()
     {
         super.onOpen();
-        if(_groupDatabase == null)
+        FileGroupDatabase groupDatabase = new FileGroupDatabase();
+        try
         {
-            _groupDatabase = new FileGroupDatabase();
-            try
-            {
-                _groupDatabase.setGroupFile(getPath());
-            }
-            catch (IOException e)
+            groupDatabase.setGroupFile(getPath());
+        }
+        catch(IOException | RuntimeException e)
+        {
+            if (e instanceof IllegalConfigurationException)
             {
-                setState(State.ERRORED);
-                LOGGER.warn(("Unable to open preferences file at " + _path));
+                throw (IllegalConfigurationException) e;
             }
+            throw new IllegalConfigurationException(String.format("Cannot load groups from '%s'", getPath()), e);
         }
+
+        _groupDatabase = groupDatabase;
+
         Set<Principal> groups = getGroupPrincipals();
         Collection<Group> principals = new ArrayList<Group>(groups.size());
         for (Principal group : groups)
@@ -150,43 +155,47 @@ public class FileBasedGroupProviderImpl
     protected void onCreate()
     {
         super.onCreate();
-        _groupDatabase = new FileGroupDatabase();
-
         File file = new File(_path);
         if (!file.exists())
         {
             File parent = file.getParentFile();
-            if (!parent.exists())
+            if (!parent.exists() && !file.getParentFile().mkdirs())
             {
-                parent.mkdirs();
+                throw new IllegalConfigurationException(String.format("Cannot create groups file at '%s'",_path));
             }
-            if (parent.exists())
+            try
             {
-                try
-                {
-                    file.createNewFile();
-                }
-                catch (IOException e)
-                {
-                    throw new IllegalConfigurationException("Cannot create group file");
-                }
+                file.createNewFile();
             }
-            else
+            catch (IOException e)
             {
-                throw new IllegalConfigurationException("Cannot create group file");
+                throw new IllegalConfigurationException(String.format("Cannot create groups file at '%s'", _path), e);
             }
         }
-        try
-        {
-            _groupDatabase.setGroupFile(getPath());
-        }
-        catch (IOException e)
-        {
-            setState(State.ERRORED);
-            LOGGER.warn(("Unable to open preferences file at " + _path));
-        }
+    }
 
+    @Override
+    protected void validateOnCreate()
+    {
+        super.validateOnCreate();
+        File groupsFile = new File(_path);
+        if (groupsFile.exists())
+        {
+            if (!groupsFile.canRead())
+            {
+                throw new IllegalConfigurationException(String.format("Cannot read groups file '%s'. Please check permissions.", _path));
+            }
 
+            FileGroupDatabase groupDatabase = new FileGroupDatabase();
+            try
+            {
+                groupDatabase.setGroupFile(_path);
+            }
+            catch (Exception e)
+            {
+                throw new IllegalConfigurationException(String.format("Cannot load groups from '%s'", _path), e);
+            }
+        }
     }
 
     @Override
@@ -205,6 +214,11 @@ public class FileBasedGroupProviderImpl
 
             getSecurityManager().authoriseGroupOperation(Operation.CREATE, groupName);
 
+            if (getState() != State.ACTIVE)
+            {
+                throw new IllegalConfigurationException(String.format("Group provider '%s' is not activated. Cannot create a group.", getName()));
+            }
+
             _groupDatabase.createGroup(groupName);
 
             Map<String,Object> attrMap = new HashMap<String, Object>();
@@ -247,20 +261,22 @@ public class FileBasedGroupProviderImpl
         return _broker.getSecurityManager();
     }
 
-    @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED }, desiredState = State.ACTIVE )
+    @StateTransition( currentState = { State.UNINITIALIZED, State.QUIESCED, State.ERRORED }, desiredState = State.ACTIVE )
     private void activate()
     {
-        try
+        if (_groupDatabase != null)
         {
-            _groupDatabase.setGroupFile(getPath());
             setState(State.ACTIVE);
         }
-        catch(IOException | RuntimeException e)
+        else
         {
-            setState(State.ERRORED);
             if (_broker.isManagementMode())
             {
-                LOGGER.warn("Failed to activate group provider: " + getName(), e);
+                        LOGGER.warn("Failed to activate group provider: " + getName());
+            }
+            else
+            {
+                throw new IllegalConfigurationException(String.format("Cannot load groups from '%s'", getPath()));
             }
         }
     }
@@ -268,6 +284,7 @@ public class FileBasedGroupProviderImpl
     @StateTransition( currentState = { State.QUIESCED, State.ACTIVE, State.ERRORED}, desiredState = State.DELETED )
     private void doDelete()
     {
+        close();
         File file = new File(getPath());
         if (file.exists())
         {
@@ -289,7 +306,7 @@ public class FileBasedGroupProviderImpl
 
     public Set<Principal> getGroupPrincipalsForUser(String username)
     {
-        Set<String> groups = _groupDatabase.getGroupsForUser(username);
+        Set<String> groups = _groupDatabase == null ? Collections.<String>emptySet(): _groupDatabase.getGroupsForUser(username);
         if (groups.isEmpty())
         {
             return Collections.emptySet();

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java Wed Oct  1 23:48:14 2014
@@ -76,20 +76,72 @@ public class FileSystemPreferencesProvid
         _authenticationProvider = authenticationProvider;
     }
 
-    @StateTransition( currentState = State.UNINITIALIZED, desiredState = State.ACTIVE )
+    @Override
+    protected void validateOnCreate()
+    {
+        super.validateOnCreate();
+        File storeFile  = new File(_path);
+        if (storeFile.exists() )
+        {
+            if (!storeFile.canRead())
+            {
+                throw new IllegalConfigurationException(String.format("Cannot read preferences file '%s'. Please check permissions.", _path));
+            }
+
+            FileSystemPreferencesStore store = null;
+            try
+            {
+                store = new FileSystemPreferencesStore(storeFile);
+                store.open();
+            }
+            catch (RuntimeException e)
+            {
+                if (e instanceof IllegalConfigurationException)
+                {
+                    throw e;
+                }
+                throw new IllegalConfigurationException(String.format("Cannot open preferences store at '%s'", _path), e);
+            }
+            finally
+            {
+                if (store != null)
+                {
+                    store.close();
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate()
+    {
+        super.validateOnCreate();
+        File storeFile  = new File(_path);
+        if (!storeFile.exists() )
+        {
+            new FileSystemPreferencesStore(storeFile).createIfNotExist();
+        }
+    }
+
+    @Override
+    protected void onOpen()
+    {
+        FileSystemPreferencesStore store = new FileSystemPreferencesStore(new File(_path));
+        store.open();
+        _store = store;
+        _open = true;
+    }
+
+    @StateTransition( currentState = {State.UNINITIALIZED, State.ERRORED}, desiredState = State.ACTIVE )
     private void activate()
     {
-        try
+        if (_store != null)
         {
-            _store = new FileSystemPreferencesStore(new File(_path));
-            createStoreIfNotExist();
-            _store.open();
-            _open = true;
             setState(State.ACTIVE);
         }
-        catch( RuntimeException e )
+        else
         {
-            setState(State.ERRORED);
+            throw new IllegalStateException("Cannot open preferences provider " + getName() + " in state " + getState() );
         }
     }
 
@@ -148,9 +200,14 @@ public class FileSystemPreferencesProvid
         setState(State.DELETED);
     }
 
-    @StateTransition(currentState = { State.QUIESCED, State.ERRORED }, desiredState = State.ACTIVE )
+    @StateTransition(currentState = State.QUIESCED, desiredState = State.ACTIVE )
     private void restart()
     {
+        if (_store == null)
+        {
+            throw new IllegalStateException("Cannot open preferences provider " + getName() + " in state " + getState() );
+        }
+
         _store.open();
         setState(State.ACTIVE);
     }
@@ -158,24 +215,39 @@ public class FileSystemPreferencesProvid
     @Override
     public Map<String, Object> getPreferences(String userId)
     {
-        return _store.getPreferences(userId);
+        return _store == null? Collections.<String, Object>emptyMap() : _store.getPreferences(userId);
     }
 
     @Override
     public Map<String, Object> setPreferences(String userId, Map<String, Object> preferences)
     {
+        if (_store == null)
+        {
+            throw new IllegalStateException("Cannot set preferences with preferences provider " + getName() + " in state " + getState() );
+        }
+
         return _store.setPreferences(userId, preferences);
     }
 
     @Override
     public String[] deletePreferences(String... userIDs)
     {
+        if (_store == null)
+        {
+            throw new IllegalStateException("Cannot delete preferences with preferences provider " + getName() + " in state " + getState() );
+        }
+
         return _store.deletePreferences(userIDs);
     }
 
     @Override
     public Set<String> listUserIDs()
     {
+        if (_store == null)
+        {
+            return Collections.emptySet();
+        }
+
         return _store.listUserIDs();
     }
 
@@ -215,9 +287,10 @@ public class FileSystemPreferencesProvid
             }
             else
             {
-                _store = new FileSystemPreferencesStore(new File(_path));
-                createStoreIfNotExist();
-                _store.open();
+                FileSystemPreferencesStore store = new FileSystemPreferencesStore(new File(_path));
+                store.createIfNotExist();
+                store.open();
+                _store = store;
             }
         }
     }
@@ -265,11 +338,6 @@ public class FileSystemPreferencesProvid
 
     }
 
-    private void createStoreIfNotExist()
-    {
-        _store.createIfNotExist();
-    }
-
     public static class FileSystemPreferencesStore
     {
         private final ObjectMapper _objectMapper;
@@ -294,18 +362,18 @@ public class FileSystemPreferencesProvid
                 File parent = _storeFile.getParentFile();
                 if (!parent.exists() && !parent.mkdirs())
                 {
-                    throw new IllegalConfigurationException("Cannot create preferences store folders");
+                    throw new IllegalConfigurationException(String.format("Cannot create preferences store folder at '%s'", _storeFile.getAbsolutePath()));
                 }
                 try
                 {
                     if (_storeFile.createNewFile() && !_storeFile.exists())
                     {
-                        throw new IllegalConfigurationException("Preferences store file was not created:" + _storeFile.getAbsolutePath());
+                        throw new IllegalConfigurationException(String.format("Cannot create preferences store file at '%s'", _storeFile.getAbsolutePath()));
                     }
                 }
                 catch (IOException e)
                 {
-                    throw new IllegalConfigurationException("Cannot create preferences store file");
+                    throw new IllegalConfigurationException(String.format("Cannot create preferences store file at '%s'", _storeFile.getAbsolutePath()), e);
                 }
             }
         }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java Wed Oct  1 23:48:14 2014
@@ -317,7 +317,7 @@ abstract public class AbstractPort<X ext
         setState(State.DELETED);
     }
 
-    @StateTransition( currentState = {State.UNINITIALIZED, State.QUIESCED}, desiredState = State.ACTIVE )
+    @StateTransition( currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE )
     protected void activate()
     {
         try
@@ -327,8 +327,7 @@ abstract public class AbstractPort<X ext
         catch (RuntimeException e)
         {
             setState(State.ERRORED);
-            LOGGER.error("Unable to active port '" + getName() + "'of type " + getType() + " on port " + getPort(),
-                         e);
+            throw new IllegalConfigurationException("Unable to active port '" + getName() + "'of type " + getType() + " on " + getPort(), e);
         }
     }
 

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java Wed Oct  1 23:48:14 2014
@@ -34,6 +34,7 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 
+import org.apache.qpid.server.util.PortUtil;
 import org.codehaus.jackson.map.ObjectMapper;
 
 import org.apache.qpid.server.configuration.BrokerProperties;
@@ -187,6 +188,18 @@ public class AmqpPortImpl extends Abstra
         }
     }
 
+    @Override
+    public void validateOnCreate()
+    {
+        super.validateOnCreate();
+        String bindingAddress = getBindingAddress();
+        if (!PortUtil.isPortAvailable(bindingAddress, getPort()))
+        {
+            throw new IllegalConfigurationException(String.format("Cannot bind to port %d and binding address '%s'. Port is already is use.",
+                    getPort(), bindingAddress == null || "".equals(bindingAddress) ? "*" : bindingAddress));
+        }
+    }
+
     private SSLContext createSslContext()
     {
         KeyStore keyStore = getKeyStore();

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java Wed Oct  1 23:48:14 2014
@@ -22,10 +22,12 @@ package org.apache.qpid.server.model.por
 
 import java.util.Map;
 
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ManagedAttributeField;
 import org.apache.qpid.server.model.ManagedObjectFactoryConstructor;
 import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.util.PortUtil;
 
 public class HttpPortImpl extends AbstractClientAuthCapablePortWithAuthProvider<HttpPortImpl> implements HttpPort<HttpPortImpl>
 {
@@ -65,4 +67,16 @@ public class HttpPortImpl extends Abstra
             return State.QUIESCED;
         }
     }
+
+    @Override
+    public void validateOnCreate()
+    {
+        super.validateOnCreate();
+        String bindingAddress = getBindingAddress();
+        if (!PortUtil.isPortAvailable(bindingAddress, getPort()))
+        {
+            throw new IllegalConfigurationException(String.format("Cannot bind to port %d and binding address '%s'. Port is already is use.",
+                    getPort(), bindingAddress == null || "".equals(bindingAddress) ? "*" : bindingAddress));
+        }
+    }
 }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java Wed Oct  1 23:48:14 2014
@@ -24,6 +24,7 @@ import org.apache.qpid.server.BrokerOpti
 import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.logging.EventLogger;
 import org.apache.qpid.server.logging.LogRecorder;
+import org.apache.qpid.server.model.BrokerShutdownProvider;
 import org.apache.qpid.server.model.SystemConfig;
 
 public interface SystemConfigFactory<X extends SystemConfig<X>> extends Pluggable
@@ -31,5 +32,6 @@ public interface SystemConfigFactory<X e
     public X newInstance(final TaskExecutor taskExecutor,
                          final EventLogger eventLogger,
                          final LogRecorder logRecorder,
-                         final BrokerOptions brokerOptions);
+                         final BrokerOptions brokerOptions,
+                         final BrokerShutdownProvider brokerShutdownProvider);
 }

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java Wed Oct  1 23:48:14 2014
@@ -254,6 +254,12 @@ public abstract class AbstractQueue<X ex
     }
 
     @Override
+    protected void validateOnCreate()
+    {
+        _virtualHost.getSecurityManager().authoriseCreateQueue(this);
+    }
+
+    @Override
     protected void onCreate()
     {
         super.onCreate();
@@ -304,6 +310,7 @@ public abstract class AbstractQueue<X ex
         }
     }
 
+    @Override
     protected void onOpen()
     {
         super.onOpen();
@@ -319,17 +326,6 @@ public abstract class AbstractQueue<X ex
 
         _logSubject = new QueueLogSubject(this);
 
-        try
-        {
-
-            _virtualHost.getSecurityManager().authoriseCreateQueue(this);
-        }
-        catch(AccessControlException e)
-        {
-            deleted();
-            throw e;
-        }
-
         Subject activeSubject = Subject.getSubject(AccessController.getContext());
         Set<SessionPrincipal> sessionPrincipals = activeSubject == null ? Collections.<SessionPrincipal>emptySet() : activeSubject.getPrincipals(SessionPrincipal.class);
         AMQSessionModel<?,?> sessionModel;
@@ -2798,7 +2794,7 @@ public abstract class AbstractQueue<X ex
 
     //=============
 
-    @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE)
+    @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
     private void activate()
     {
         setState(State.ACTIVE);

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java?rev=1628867&r1=1628866&r2=1628867&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java Wed Oct  1 23:48:14 2014
@@ -76,25 +76,32 @@ public abstract class PrincipalDatabaseA
     }
 
     @Override
+    protected void validateOnCreate()
+    {
+        super.validateOnCreate();
+        File passwordFile = new File(_path);
+        if (passwordFile.exists() && !passwordFile.canRead())
+        {
+            throw new IllegalConfigurationException(String.format("Cannot read password file '%s'. Please check permissions.", _path));
+        }
+    }
+
+    @Override
     protected void onCreate()
     {
         super.onCreate();
-        try
+        File passwordFile = new File(_path);
+        if (!passwordFile.exists())
         {
-            File passwordFile = new File(_path);
-            if (!passwordFile.exists())
+            try
             {
                 passwordFile.createNewFile();
             }
-            else if (!passwordFile.canRead())
+            catch (IOException e)
             {
-                throw new IllegalConfigurationException("Cannot read password file" + _path + ". Check permissions.");
+                throw new IllegalConfigurationException(String.format("Cannot create password file at '%s'", _path), e);
             }
         }
-        catch (IOException e)
-        {
-            throw new IllegalConfigurationException("Cannot use password database at :" + _path, e);
-        }
     }
 
     @Override
@@ -102,23 +109,14 @@ public abstract class PrincipalDatabaseA
     {
         super.onOpen();
         _principalDatabase = createDatabase();
-        try
-        {
-            initialise();
-            List<Principal> users =
-                    _principalDatabase == null ? Collections.<Principal>emptyList() : _principalDatabase.getUsers();
-            for (Principal user : users)
-            {
-                PrincipalAdapter principalAdapter = new PrincipalAdapter(user);
-                principalAdapter.registerWithParents();
-                principalAdapter.open();
-                _userMap.put(user, principalAdapter);
-            }
-        }
-        catch(IllegalConfigurationException e)
-        {
-            setState(State.ERRORED);
-
+        initialise();
+        List<Principal> users = _principalDatabase == null ? Collections.<Principal>emptyList() : _principalDatabase.getUsers();
+        for (Principal user : users)
+        {
+            PrincipalAdapter principalAdapter = new PrincipalAdapter(user);
+            principalAdapter.registerWithParents();
+            principalAdapter.open();
+            _userMap.put(user, principalAdapter);
         }
     }
 
@@ -457,7 +455,7 @@ public abstract class PrincipalDatabaseA
             return super.changeAttribute(name, expected, desired);
         }
 
-        @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE)
+        @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
         private void activate()
         {
             setState(State.ACTIVE);

Added: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java?rev=1628867&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java (added)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java Wed Oct  1 23:48:14 2014
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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.util;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+
+public class PortUtil
+{
+    public static boolean isPortAvailable(String hostName, int port)
+    {
+        InetSocketAddress socketAddress = null;
+        if ( hostName == null || "".equals(hostName) || "*".equals(hostName) )
+        {
+            socketAddress = new InetSocketAddress(port);
+        }
+        else
+        {
+            socketAddress = new InetSocketAddress(hostName, port);
+        }
+
+        ServerSocket serverSocket = null;
+        try
+        {
+            serverSocket = new ServerSocket();
+            serverSocket.setReuseAddress(true);
+            serverSocket.bind(socketAddress);
+            return true;
+        }
+        catch (IOException e)
+        {
+            return false;
+        }
+        finally
+        {
+            if (serverSocket != null)
+            {
+                try
+                {
+                    serverSocket.close();
+                }
+                catch (IOException e)
+                {
+                    throw new RuntimeException("Couldn't close port " + port + " that was created to check its availability", e);
+                }
+            }
+        }
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message