summaryrefslogtreecommitdiff
path: root/qpid/java
diff options
context:
space:
mode:
authorAlex Rudyy <orudyy@apache.org>2014-10-01 23:48:14 +0000
committerAlex Rudyy <orudyy@apache.org>2014-10-01 23:48:14 +0000
commita638bc903339cac26e522df787ad4fcbca2344aa (patch)
tree94a5bae92749b96c229ca36590e681032f6aa752 /qpid/java
parentf84ed512e919a6c717cbdbcc22e8139bc64bc205 (diff)
downloadqpid-python-a638bc903339cac26e522df787ad4fcbca2344aa.tar.gz
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
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1628867 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java')
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java6
-rw-r--r--qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java144
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java87
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java106
-rw-r--r--qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java92
-rw-r--r--qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java9
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java5
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java22
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java18
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java229
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java10
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java26
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java5
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java2
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java22
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java97
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java110
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java5
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java13
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java14
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java4
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java20
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java50
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java69
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java44
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java30
-rw-r--r--qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java40
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java76
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java2
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java4
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java127
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java117
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java54
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java105
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java104
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java123
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java58
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java61
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java4
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java247
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java192
-rw-r--r--qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java6
-rw-r--r--qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java31
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java79
-rw-r--r--qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java6
-rw-r--r--qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java6
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java2
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java2
-rw-r--r--qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java6
-rw-r--r--qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java49
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java7
-rw-r--r--qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/PortRestTest.java6
52 files changed, 2420 insertions, 333 deletions
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java
index 0fc44605fe..5d65d6e16d 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBSystemConfigImpl.java
@@ -26,6 +26,7 @@ import org.apache.qpid.server.logging.EventLogger;
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 AbstractSystemConfig<BDBSystemConfigImp
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
diff --git a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
index e6109954c0..98b9cc3cf0 100644
--- a/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
+++ b/qpid/java/bdbstore/src/main/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBHAVirtualHostNodeImpl.java
@@ -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.berkeleydb.BDBConfigurationStore;
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 extends AbstractVirtualHostNode<BDBHAVirtu
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 extends AbstractVirtualHostNode<BDBHAVirtu
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 extends AbstractVirtualHostNode<BDBHAVirtu
}
}
- 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 extends AbstractVirtualHostNode<BDBHAVirtu
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)
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
index e9bcc5d754..16486e3564 100644
--- a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBHAVirtualHostNodeTest.java
@@ -23,6 +23,8 @@ package org.apache.qpid.server.store.berkeleydb;
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.virtualhostnode.berkeleydb.BDBHAVirtualHostNodeTes
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 extends QpidTestCase
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);
+ }
+ }
}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java
new file mode 100644
index 0000000000..92da465dbd
--- /dev/null
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhost/berkeleydb/BDBVirtualHostImplTest.java
@@ -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"));
+ }
+ }
+
+}
diff --git a/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java
new file mode 100644
index 0000000000..6608312088
--- /dev/null
+++ b/qpid/java/bdbstore/src/test/java/org/apache/qpid/server/virtualhostnode/berkeleydb/BDBVirtualHostNodeTest.java
@@ -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"));
+ }
+ }
+
+}
diff --git a/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java b/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java
index c569bc4641..317e0f7c74 100644
--- a/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java
+++ b/qpid/java/broker-codegen/src/main/java/org/apache/qpid/server/model/SystemConfigFactoryGenerator.java
@@ -117,9 +117,9 @@ public class SystemConfigFactoryGenerator extends AbstractProcessor
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 SystemConfigFactoryGenerator extends AbstractProcessor
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("}");
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
index 0a1979128f..0b925d130c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/Broker.java
@@ -40,6 +40,7 @@ import org.apache.qpid.server.logging.LogRecorder;
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.IApplicationRegistry;
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();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java
index b71d667fe0..6c67a44bb0 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/binding/BindingImpl.java
@@ -29,9 +29,12 @@ import java.util.concurrent.CopyOnWriteArrayList;
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);
+ }
+ }
+ }
+
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
index fd0333f6e7..989a4abea5 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/exchange/AbstractExchange.java
@@ -118,16 +118,6 @@ public abstract class AbstractExchange<T extends 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 extends 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 extends 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);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
index d3741cd846..9ff7e224cd 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractConfiguredObject.java
@@ -47,6 +47,7 @@ import java.util.concurrent.atomic.AtomicReference;
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
_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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
- 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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
- 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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
}
- 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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
}
}
- 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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
State state = getState();
if(desiredState == getDesiredState() && desiredState != state)
{
- attainState();
+ attainStateIfOpenedOrReopenFailed();
return getState();
}
else
@@ -1217,7 +1343,6 @@ public abstract class AbstractConfiguredObject<X extends ConfiguredObject<X>> im
{
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 AbstractConfiguredObject<X extends ConfiguredObject<X>> im
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;
+ }
+ }
+ }
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
index 19f6139387..f8dac7cbe9 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/AbstractSystemConfig.java
@@ -49,13 +49,15 @@ public abstract class AbstractSystemConfig<X extends SystemConfig<X>>
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 AbstractSystemConfig<X extends SystemConfig<X>>
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 AbstractSystemConfig<X extends SystemConfig<X>>
}
+ @Override
+ public BrokerShutdownProvider getBrokerShutdownProvider()
+ {
+ return _brokerShutdownProvider;
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java
new file mode 100644
index 0000000000..5c8ab3e850
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/BrokerShutdownProvider.java
@@ -0,0 +1,26 @@
+/*
+ *
+ * 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.model;
+
+public interface BrokerShutdownProvider
+{
+ void shutdown();
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java
index 1763aca524..c9a828e7e4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/JsonSystemConfigImpl.java
@@ -38,9 +38,10 @@ public class JsonSystemConfigImpl extends AbstractSystemConfig<JsonSystemConfigI
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()
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java
index 7943c32c42..ec063142b4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/SystemConfig.java
@@ -37,4 +37,6 @@ public interface SystemConfig<X extends SystemConfig<X>> extends ConfiguredObjec
LogRecorder getLogRecorder();
DurableConfigurationStore getConfigurationStore();
+
+ BrokerShutdownProvider getBrokerShutdownProvider();
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
index 92ac43e629..109aaff5bd 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
@@ -943,6 +943,28 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple
_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);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
index c96f4c0849..1b3d0591c0 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImpl.java
@@ -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();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java
index f2be4fd861..60be3592f8 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderImpl.java
@@ -76,20 +76,72 @@ public class FileSystemPreferencesProviderImpl
_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 FileSystemPreferencesProviderImpl
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 FileSystemPreferencesProviderImpl
@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 FileSystemPreferencesProviderImpl
}
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 FileSystemPreferencesProviderImpl
}
- private void createStoreIfNotExist()
- {
- _store.createIfNotExist();
- }
-
public static class FileSystemPreferencesStore
{
private final ObjectMapper _objectMapper;
@@ -294,18 +362,18 @@ public class FileSystemPreferencesProviderImpl
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);
}
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
index c0aa99a7d6..e2e7eff322 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AbstractPort.java
@@ -317,7 +317,7 @@ abstract public class AbstractPort<X extends AbstractPort<X>> extends AbstractCo
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 extends AbstractPort<X>> extends AbstractCo
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);
}
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
index fe7d419c78..afe3c9a44e 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/AmqpPortImpl.java
@@ -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 AbstractClientAuthCapablePortWithAuthProvider<
}
}
+ @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();
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java
index 1774f16ab6..3be5854645 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/port/HttpPortImpl.java
@@ -22,10 +22,12 @@ package org.apache.qpid.server.model.port;
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 AbstractClientAuthCapablePortWithAuthProvider<
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));
+ }
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java
index 9162f9e095..885194d939 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/SystemConfigFactory.java
@@ -24,6 +24,7 @@ import org.apache.qpid.server.BrokerOptions;
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 extends SystemConfig<X>> extends Pluggabl
public X newInstance(final TaskExecutor taskExecutor,
final EventLogger eventLogger,
final LogRecorder logRecorder,
- final BrokerOptions brokerOptions);
+ final BrokerOptions brokerOptions,
+ final BrokerShutdownProvider brokerShutdownProvider);
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
index a5156c9073..38cea2cdb7 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
@@ -254,6 +254,12 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
}
@Override
+ protected void validateOnCreate()
+ {
+ _virtualHost.getSecurityManager().authoriseCreateQueue(this);
+ }
+
+ @Override
protected void onCreate()
{
super.onCreate();
@@ -304,6 +310,7 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
}
}
+ @Override
protected void onOpen()
{
super.onOpen();
@@ -319,17 +326,6 @@ public abstract class AbstractQueue<X extends AbstractQueue<X>>
_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 extends AbstractQueue<X>>
//=============
- @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE)
+ @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
private void activate()
{
setState(State.ACTIVE);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index a6a2ea8d34..192a096d12 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -76,25 +76,32 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
}
@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 PrincipalDatabaseAuthenticationManager<T extends Principal
{
super.onOpen();
_principalDatabase = createDatabase();
- try
+ initialise();
+ List<Principal> users = _principalDatabase == null ? Collections.<Principal>emptyList() : _principalDatabase.getUsers();
+ for (Principal user : users)
{
- 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);
-
+ PrincipalAdapter principalAdapter = new PrincipalAdapter(user);
+ principalAdapter.registerWithParents();
+ principalAdapter.open();
+ _userMap.put(user, principalAdapter);
}
}
@@ -457,7 +455,7 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal
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);
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java
new file mode 100644
index 0000000000..5d093bd3d5
--- /dev/null
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/PortUtil.java
@@ -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);
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
index f52c1967f8..26ce6aca4c 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhost/AbstractVirtualHost.java
@@ -37,7 +37,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
import javax.security.auth.Subject;
@@ -231,6 +230,47 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
}
@Override
+ public void validateOnCreate()
+ {
+ super.validateOnCreate();
+ validateMessageStoreCreation();
+ }
+
+ private void validateMessageStoreCreation()
+ {
+ MessageStore store = createMessageStore();
+ if (store != null)
+ {
+ try
+ {
+ store.openMessageStore(this);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalConfigurationException("Cannot open virtual host message store:" + e.getMessage(), e);
+ }
+ finally
+ {
+ try
+ {
+ store.closeMessageStore();
+ }
+ catch(Exception e)
+ {
+ _logger.warn("Failed to close database", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void onExceptionInOpen(RuntimeException e)
+ {
+ super.onExceptionInOpen(e);
+ closeMessageStore();
+ }
+
+ @Override
protected void onOpen()
{
super.onOpen();
@@ -1355,7 +1395,7 @@ public abstract class AbstractVirtualHost<X extends AbstractVirtualHost<X>> exte
getDurableConfigurationStore().create(new ConfiguredObjectRecordImpl(record.getId(), record.getType(), record.getAttributes()));
}
- @StateTransition( currentState = { State.UNINITIALIZED }, desiredState = State.ACTIVE )
+ @StateTransition( currentState = { State.UNINITIALIZED,State.ERRORED }, desiredState = State.ACTIVE )
private void onActivate()
{
_houseKeepingTasks = new ScheduledThreadPoolExecutor(getHousekeepingThreadCount());
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
index ce97502124..03c30a9cd4 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNode.java
@@ -41,6 +41,7 @@ import org.apache.qpid.server.model.VirtualHostNode;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
import org.apache.qpid.server.store.ConfiguredObjectRecordImpl;
+import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.VirtualHostStoreUpgraderAndRecoverer;
public abstract class AbstractStandardVirtualHostNode<X extends AbstractStandardVirtualHostNode<X>> extends AbstractVirtualHostNode<X>
@@ -169,4 +170,33 @@ public abstract class AbstractStandardVirtualHostNode<X extends AbstractStandard
{
return Collections.emptyList();
}
+
+ @Override
+ public void validateOnCreate()
+ {
+ super.validateOnCreate();
+ DurableConfigurationStore store = createConfigurationStore();
+ if (store != null)
+ {
+ try
+ {
+ store.openConfigurationStore(this, false);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalConfigurationException("Cannot open node configuration store:" + e.getMessage(), e);
+ }
+ finally
+ {
+ try
+ {
+ store.closeConfigurationStore();
+ }
+ catch(Exception e)
+ {
+ LOGGER.warn("Failed to close database", e);
+ }
+ }
+ }
+ }
}
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
index 5cbfb0942a..1b363890dc 100644
--- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
+++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/virtualhostnode/AbstractVirtualHostNode.java
@@ -36,7 +36,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicReference;
import org.apache.log4j.Logger;
@@ -100,8 +99,6 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
{
super.onOpen();
_durableConfigurationStore = createConfigurationStore();
- _configurationStoreLogSubject = new MessageStoreLogSubject(getName(), _durableConfigurationStore.getClass().getSimpleName());
-
}
@Override
@@ -167,11 +164,6 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
return _eventLogger;
}
- protected DurableConfigurationStore getDurableConfigurationStore()
- {
- return _durableConfigurationStore;
- }
-
protected MessageStoreLogSubject getConfigurationStoreLogSubject()
{
return _configurationStoreLogSubject;
@@ -205,11 +197,29 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
protected void stopAndSetStateTo(State stoppedState)
{
closeChildren();
- closeConfigurationStore();
+ closeConfigurationStoreSafely();
setState(stoppedState);
}
@Override
+ protected void onExceptionInOpen(RuntimeException e)
+ {
+ super.onExceptionInOpen(e);
+ closeConfigurationStoreSafely();
+ }
+
+ @Override
+ protected void postResolve()
+ {
+ DurableConfigurationStore store = getConfigurationStore();
+ if (store == null)
+ {
+ store = createConfigurationStore();
+ }
+ _configurationStoreLogSubject = new MessageStoreLogSubject(getName(), store.getClass().getSimpleName());
+ }
+
+ @Override
protected void onClose()
{
closeConfigurationStore();
@@ -262,6 +272,18 @@ public abstract class AbstractVirtualHostNode<X extends AbstractVirtualHostNode<
}
}
+ private void closeConfigurationStoreSafely()
+ {
+ try
+ {
+ closeConfigurationStore();
+ }
+ catch(Exception e)
+ {
+ LOGGER.warn("Unexpected exception on close of configuration store", e);
+ }
+ }
+
@Override
public String getVirtualHostInitialConfiguration()
{
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java
new file mode 100644
index 0000000000..93fa9114fb
--- /dev/null
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/binding/BindingImplTest.java
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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.binding;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.common.AMQPFilterTypes;
+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.exchange.ExchangeImpl;
+import org.apache.qpid.server.model.Binding;
+import org.apache.qpid.server.model.BrokerModel;
+import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class BindingImplTest extends QpidTestCase
+{
+ private TaskExecutor _taskExecutor;
+ private Model _model;
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance();
+ _model = BrokerModel.getInstance();
+ }
+
+ public void testBindingValidationOnCreateWithInvalidSelector()
+ {
+ Map<String, String> arguments = new HashMap<>();
+ arguments.put(AMQPFilterTypes.JMS_SELECTOR.toString(), "test in (");
+ Map<String,Object> attributes = new HashMap<>();
+ attributes.put(Binding.ARGUMENTS, arguments);
+ attributes.put(Binding.NAME, getTestName());
+ AMQQueue queue = mock(AMQQueue.class);
+ when(queue.getTaskExecutor()).thenReturn(_taskExecutor);
+ when(queue.getModel()).thenReturn(_model);
+ ExchangeImpl exchange = mock(ExchangeImpl.class);
+ when(exchange.getTaskExecutor()).thenReturn(_taskExecutor);
+ when(exchange.getModel()).thenReturn(_model);
+ BindingImpl binding = new BindingImpl(attributes, queue, exchange);
+ try
+ {
+ binding.create();
+ fail("Exception is expected on validation with invalid selector");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertTrue("Unexpected exception message " + e.getMessage(), e.getMessage().startsWith("Cannot parse JMS selector"));
+ }
+ }
+}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java
index 4b4891d838..b4f92990eb 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/startup/FileKeyStoreCreationTest.java
@@ -63,7 +63,7 @@ public class FileKeyStoreCreationTest extends TestCase
Map<String, Object> attributesCopy = new HashMap<String, Object>(attributes);
Broker broker = mock(Broker.class);
- TaskExecutor executor = new CurrentThreadTaskExecutor();
+ TaskExecutor executor = CurrentThreadTaskExecutor.newStartedInstance();
when(broker.getObjectFactory()).thenReturn(_factory);
when(broker.getModel()).thenReturn(_factory.getModel());
when(broker.getTaskExecutor()).thenReturn(executor);
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
index 36353f0dba..fbb08cdd2a 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandlerTest.java
@@ -34,6 +34,7 @@ import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
+import org.apache.qpid.server.model.BrokerShutdownProvider;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -78,7 +79,8 @@ public class ManagementModeStoreHandlerTest extends QpidTestCase
_taskExecutor.start();
_systemConfig = new JsonSystemConfigImpl(_taskExecutor, mock(EventLogger.class),
- mock(LogRecorder.class), new BrokerOptions());
+ mock(LogRecorder.class), new BrokerOptions(),
+ mock(BrokerShutdownProvider.class));
ConfiguredObjectRecord systemContextRecord = _systemConfig.asObjectRecord();
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java
index e5c5a89c10..a09910b7e2 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/AbstractConfiguredObjectTest.java
@@ -26,7 +26,9 @@ import java.util.Map;
import junit.framework.TestCase;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.model.testmodel.TestChildCategory;
+import org.apache.qpid.server.model.testmodel.TestConfiguredObject;
import org.apache.qpid.server.model.testmodel.TestModel;
import org.apache.qpid.server.model.testmodel.TestRootCategory;
import org.apache.qpid.server.store.ConfiguredObjectRecord;
@@ -257,4 +259,129 @@ public class AbstractConfiguredObjectTest extends TestCase
parent.getChildren(TestChildCategory.class).isEmpty());
}
+ public void testOpeningResultsInErroredStateWhenResolutionFails() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnPostResolve(true);
+ object.open();
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ERRORED, object.getState());
+
+ object.setThrowExceptionOnPostResolve(false);
+ object.setAttributes(Collections.<String, Object>singletonMap(Port.DESIRED_STATE, State.ACTIVE));
+ assertTrue("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ACTIVE, object.getState());
+ }
+
+ public void testOpeningInERROREDStateAfterFailedOpenOnDesiredStateChangeToActive() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnOpen(true);
+ object.open();
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ERRORED, object.getState());
+
+ object.setThrowExceptionOnOpen(false);
+ object.setAttributes(Collections.<String, Object>singletonMap(Port.DESIRED_STATE, State.ACTIVE));
+ assertTrue("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ACTIVE, object.getState());
+ }
+
+ public void testOpeningInERROREDStateAfterFailedOpenOnStart() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnOpen(true);
+ object.open();
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ERRORED, object.getState());
+
+ object.setThrowExceptionOnOpen(false);
+ object.start();
+ assertTrue("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ACTIVE, object.getState());
+ }
+
+ public void testDeletionERROREDStateAfterFailedOpenOnDelete() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnOpen(true);
+ object.open();
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ERRORED, object.getState());
+
+ object.delete();
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.DELETED, object.getState());
+ }
+
+ public void testDeletionInERROREDStateAfterFailedOpenOnDesiredStateChangeToDelete() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnOpen(true);
+ object.open();
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ERRORED, object.getState());
+
+ object.setAttributes(Collections.<String, Object>singletonMap(Port.DESIRED_STATE, State.DELETED));
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.DELETED, object.getState());
+ }
+
+
+ public void testCreationWithExceptionThrownFromValidationOnCreate() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnValidationOnCreate(true);
+ try
+ {
+ object.create();
+ fail("IllegalConfigurationException is expected to be thrown");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ //pass
+ }
+ assertFalse("Unexpected opened", object.isOpened());
+ }
+
+ public void testCreationWithoutExceptionThrownFromValidationOnCreate() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnValidationOnCreate(false);
+ object.create();
+ assertTrue("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ACTIVE, object.getState());
+ }
+
+ public void testCreationWithExceptionThrownFromOnOpen() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnOpen(true);
+ object.create();
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ERRORED, object.getState());
+
+ object.setThrowExceptionOnOpen(false);
+ object.start();
+ assertTrue("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.ACTIVE, object.getState());
+ }
+
+ public void testCreationWithExceptionThrownFromOnCreate() throws Exception
+ {
+ TestConfiguredObject object = new TestConfiguredObject(getName());
+ object.setThrowExceptionOnCreate(true);
+ try
+ {
+ object.create();
+ fail("Exception should have been re-thrown");
+ }
+ catch (RuntimeException re)
+ {
+ // pass
+ }
+
+ assertFalse("Unexpected opened", object.isOpened());
+ assertEquals("Unexpected state", State.DELETED, object.getState());
+ }
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java
new file mode 100644
index 0000000000..50a4e5a86e
--- /dev/null
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileBasedGroupProviderImplTest.java
@@ -0,0 +1,117 @@
+/*
+ *
+ * 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.model.adapter;
+
+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.security.SecurityManager;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.test.utils.TestFileUtils;
+
+public class FileBasedGroupProviderImplTest extends QpidTestCase
+{
+ private TaskExecutor _taskExecutor;
+ private Broker _broker;
+ private File _groupFile;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance();
+
+ _broker = mock(Broker.class);
+ when(_broker.getTaskExecutor()).thenReturn(_taskExecutor);
+ when(_broker.getModel()).thenReturn(BrokerModel.getInstance());
+ when(_broker.getId()).thenReturn(UUID.randomUUID());
+ when(_broker.getSecurityManager()).thenReturn(new SecurityManager(_broker, false));
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_groupFile.exists())
+ {
+ _groupFile.delete();
+ }
+ _taskExecutor.stop();
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testValidationOnCreateWithInvalidPath()
+ {
+ Map<String,Object> attributes = new HashMap<>();
+ _groupFile = TestFileUtils.createTempFile(this, "groups");
+
+ String groupsFile = _groupFile.getAbsolutePath() + File.separator + "groups";
+ assertFalse("File should not exist", new File(groupsFile).exists());
+ attributes.put(FileBasedGroupProvider.PATH, groupsFile);
+ attributes.put(FileBasedGroupProvider.NAME, getTestName());
+
+ FileBasedGroupProviderImpl groupsProvider = new FileBasedGroupProviderImpl(attributes, _broker);
+ try
+ {
+ groupsProvider.create();
+ fail("Exception is expected on validation of groups provider with invalid path");
+ } catch (IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot create groups file at '%s'", groupsFile), e.getMessage());
+ }
+ }
+
+ public void testValidationOnCreateWithInvalidGroups()
+ {
+ _groupFile = TestFileUtils.createTempFile(this, "groups", "=blah");
+ Map<String, Object> attributes = new HashMap<>();
+ String groupsFile = _groupFile.getAbsolutePath();
+ attributes.put(FileBasedGroupProvider.PATH, groupsFile);
+ attributes.put(FileBasedGroupProvider.NAME, getTestName());
+
+ FileBasedGroupProviderImpl groupsProvider = new FileBasedGroupProviderImpl(attributes, _broker);
+ try
+ {
+ groupsProvider.create();
+ fail("Exception is expected on validation of groups provider with invalid group file");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot load groups from '%s'", groupsFile), e.getMessage());
+ }
+ }
+
+}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
index 9bb004e4c2..f532a9325b 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/FileSystemPreferencesProviderTest.java
@@ -31,6 +31,7 @@ import java.util.Map;
import java.util.Set;
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.AuthenticationProvider;
@@ -109,7 +110,7 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase
attributes.put(ConfiguredObject.ID, UUID.randomUUID());
attributes.put(ConfiguredObject.NAME, getTestName());
_preferencesProvider = new FileSystemPreferencesProviderImpl(attributes, _authenticationProvider);
- _preferencesProvider.open();
+ _preferencesProvider.create();
assertEquals(State.ACTIVE, _preferencesProvider.getState());
assertTrue("Preferences file was not created", nonExistingFile.exists());
@@ -120,6 +121,57 @@ public class FileSystemPreferencesProviderTest extends QpidTestCase
}
}
+ public void testValidationOnCreateForInvalidPath() throws Exception
+ {
+ File file = new File(TMP_FOLDER + File.separator + getTestName() + System.nanoTime() );
+ file.createNewFile();
+ String path = file.getAbsolutePath() + File.separator + "users";
+
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(FileSystemPreferencesProvider.PATH, path);
+ attributes.put(ConfiguredObject.ID, UUID.randomUUID());
+ attributes.put(ConfiguredObject.NAME, getTestName());
+ _preferencesProvider = new FileSystemPreferencesProviderImpl(attributes, _authenticationProvider);
+
+ try
+ {
+
+ _preferencesProvider.create();
+
+ fail("Creation of preferences provider with invalid path should have failed");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot create preferences store file at '%s'", path), e.getMessage());
+ }
+ }
+
+ public void testValidationOnCreateWithInvalidPreferences()
+ {
+ File tmp = TestFileUtils.createTempFile(this, "preferences", "{blah:=boo}");
+ try
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(FileSystemPreferencesProvider.PATH, tmp.getAbsolutePath());
+ attributes.put(ConfiguredObject.ID, UUID.randomUUID());
+ attributes.put(ConfiguredObject.NAME, getTestName());
+ _preferencesProvider = new FileSystemPreferencesProviderImpl(attributes, _authenticationProvider);
+ try
+ {
+ _preferencesProvider.create();
+ fail("Exception is expected on validation of groups provider with invalid preferences format");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message:" + e.getMessage(), "Cannot parse preferences json in " + tmp.getName(), e.getMessage());
+ }
+ }
+ finally
+ {
+ tmp.delete();
+ }
+ }
+
public void testConstructionWithEmptyFile() throws Exception
{
File emptyPrefsFile = new File(TMP_FOLDER, "preferences-" + getTestName() + ".json");
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
index 523203c756..642ea06ede 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/PortFactoryTest.java
@@ -54,7 +54,7 @@ import org.apache.qpid.test.utils.QpidTestCase;
public class PortFactoryTest extends QpidTestCase
{
private UUID _portId = UUID.randomUUID();
- private int _portNumber = 123;
+ private int _portNumber;
private Set<String> _tcpStringSet = Collections.singleton(Transport.TCP.name());
private Set<Transport> _tcpTransports = Collections.singleton(Transport.TCP);
private Set<String> _sslStringSet = Collections.singleton(Transport.SSL.name());
@@ -68,11 +68,13 @@ public class PortFactoryTest extends QpidTestCase
private String _authProviderName = "authProvider";
private AuthenticationProvider _authProvider = mock(AuthenticationProvider.class);
private ConfiguredObjectFactoryImpl _factory;
+ private Port<?> _port;
@Override
protected void setUp() throws Exception
{
+ _portNumber = findFreePort();
TaskExecutor executor = CurrentThreadTaskExecutor.newStartedInstance();
when(_authProvider.getName()).thenReturn(_authProviderName);
when(_broker.getChildren(eq(AuthenticationProvider.class))).thenReturn(Collections.singleton(_authProvider));
@@ -109,30 +111,45 @@ public class PortFactoryTest extends QpidTestCase
_attributes.put(Port.BINDING_ADDRESS, "127.0.0.1");
}
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_port != null)
+ {
+ _port.close();
+ }
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
public void testCreatePortWithMinimumAttributes()
{
Map<String, Object> attributes = new HashMap<String, Object>();
- attributes.put(Port.PORT, 1);
+ attributes.put(Port.PORT, _portNumber);
attributes.put(Port.NAME, getName());
attributes.put(Port.AUTHENTICATION_PROVIDER, _authProviderName);
attributes.put(Port.DESIRED_STATE, State.QUIESCED);
- Port<?> port = _factory.create(Port.class, attributes, _broker);
+ _port = _factory.create(Port.class, attributes, _broker);
- assertNotNull(port);
- assertTrue(port instanceof AmqpPort);
- assertEquals("Unexpected port", 1, port.getPort());
- assertEquals("Unexpected transports", Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports());
+ assertNotNull(_port);
+ assertTrue(_port instanceof AmqpPort);
+ assertEquals("Unexpected _port", _portNumber, _port.getPort());
+ assertEquals("Unexpected transports", Collections.singleton(PortFactory.DEFAULT_TRANSPORT), _port.getTransports());
assertEquals("Unexpected send buffer size", PortFactory.DEFAULT_AMQP_SEND_BUFFER_SIZE,
- port.getAttribute(AmqpPort.SEND_BUFFER_SIZE));
+ _port.getAttribute(AmqpPort.SEND_BUFFER_SIZE));
assertEquals("Unexpected receive buffer size", PortFactory.DEFAULT_AMQP_RECEIVE_BUFFER_SIZE,
- port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE));
+ _port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE));
assertEquals("Unexpected need client auth", PortFactory.DEFAULT_AMQP_NEED_CLIENT_AUTH,
- port.getAttribute(Port.NEED_CLIENT_AUTH));
+ _port.getAttribute(Port.NEED_CLIENT_AUTH));
assertEquals("Unexpected want client auth", PortFactory.DEFAULT_AMQP_WANT_CLIENT_AUTH,
- port.getAttribute(Port.WANT_CLIENT_AUTH));
- assertEquals("Unexpected tcp no delay", PortFactory.DEFAULT_AMQP_TCP_NO_DELAY, port.getAttribute(Port.TCP_NO_DELAY));
- assertEquals("Unexpected binding", PortFactory.DEFAULT_AMQP_BINDING, port.getAttribute(Port.BINDING_ADDRESS));
+ _port.getAttribute(Port.WANT_CLIENT_AUTH));
+ assertEquals("Unexpected tcp no delay", PortFactory.DEFAULT_AMQP_TCP_NO_DELAY, _port.getAttribute(Port.TCP_NO_DELAY));
+ assertEquals("Unexpected binding", PortFactory.DEFAULT_AMQP_BINDING, _port.getAttribute(Port.BINDING_ADDRESS));
}
public void testCreateAmqpPort()
@@ -256,27 +273,27 @@ public class PortFactoryTest extends QpidTestCase
_attributes.put(Port.DESIRED_STATE, State.QUIESCED);
- Port<?> port = _factory.create(Port.class, _attributes, _broker);
+ _port = _factory.create(Port.class, _attributes, _broker);
- assertNotNull(port);
- assertTrue(port instanceof AmqpPort);
- assertEquals(_portId, port.getId());
- assertEquals(_portNumber, port.getPort());
+ assertNotNull(_port);
+ assertTrue(_port instanceof AmqpPort);
+ assertEquals(_portId, _port.getId());
+ assertEquals(_portNumber, _port.getPort());
if(useSslTransport)
{
- assertEquals(_sslTransports, port.getTransports());
+ assertEquals(_sslTransports, _port.getTransports());
}
else
{
- assertEquals(_tcpTransports, port.getTransports());
+ assertEquals(_tcpTransports, _port.getTransports());
}
- assertEquals(amqp010ProtocolSet, port.getProtocols());
- assertEquals("Unexpected send buffer size", 2, port.getAttribute(AmqpPort.SEND_BUFFER_SIZE));
- assertEquals("Unexpected receive buffer size", 1, port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE));
- assertEquals("Unexpected need client auth", needClientAuth, port.getAttribute(Port.NEED_CLIENT_AUTH));
- assertEquals("Unexpected want client auth", wantClientAuth, port.getAttribute(Port.WANT_CLIENT_AUTH));
- assertEquals("Unexpected tcp no delay", true, port.getAttribute(Port.TCP_NO_DELAY));
- assertEquals("Unexpected binding", "127.0.0.1", port.getAttribute(Port.BINDING_ADDRESS));
+ assertEquals(amqp010ProtocolSet, _port.getProtocols());
+ assertEquals("Unexpected send buffer size", 2, _port.getAttribute(AmqpPort.SEND_BUFFER_SIZE));
+ assertEquals("Unexpected receive buffer size", 1, _port.getAttribute(AmqpPort.RECEIVE_BUFFER_SIZE));
+ assertEquals("Unexpected need client auth", needClientAuth, _port.getAttribute(Port.NEED_CLIENT_AUTH));
+ assertEquals("Unexpected want client auth", wantClientAuth, _port.getAttribute(Port.WANT_CLIENT_AUTH));
+ assertEquals("Unexpected tcp no delay", true, _port.getAttribute(Port.TCP_NO_DELAY));
+ assertEquals("Unexpected binding", "127.0.0.1", _port.getAttribute(Port.BINDING_ADDRESS));
}
public void testCreateNonAmqpPort()
@@ -291,14 +308,14 @@ public class PortFactoryTest extends QpidTestCase
_attributes.put(Port.NAME, getName());
_attributes.put(Port.ID, _portId);
- Port<?> port = _factory.create(Port.class, _attributes, _broker);
+ _port = _factory.create(Port.class, _attributes, _broker);
- assertNotNull(port);
- assertFalse("Port should not be an AMQP-specific subclass", port instanceof AmqpPort);
- assertEquals(_portId, port.getId());
- assertEquals(_portNumber, port.getPort());
- assertEquals(_tcpTransports, port.getTransports());
- assertEquals(nonAmqpProtocolSet, port.getProtocols());
+ assertNotNull(_port);
+ assertFalse("Port should not be an AMQP-specific subclass", _port instanceof AmqpPort);
+ assertEquals(_portId, _port.getId());
+ assertEquals(_portNumber, _port.getPort());
+ assertEquals(_tcpTransports, _port.getTransports());
+ assertEquals(nonAmqpProtocolSet, _port.getProtocols());
}
public void testCreateNonAmqpPortWithPartiallySetAttributes()
@@ -312,14 +329,14 @@ public class PortFactoryTest extends QpidTestCase
_attributes.put(Port.NAME, getName());
_attributes.put(Port.ID, _portId);
- Port<?> port = _factory.create(Port.class, _attributes, _broker);
+ _port = _factory.create(Port.class, _attributes, _broker);
- assertNotNull(port);
- assertFalse("Port not be an AMQP-specific port subclass", port instanceof AmqpPort);
- assertEquals(_portId, port.getId());
- assertEquals(_portNumber, port.getPort());
- assertEquals(Collections.singleton(PortFactory.DEFAULT_TRANSPORT), port.getTransports());
- assertEquals(nonAmqpProtocolSet, port.getProtocols());
+ assertNotNull(_port);
+ assertFalse("Port not be an AMQP-specific _port subclass", _port instanceof AmqpPort);
+ assertEquals(_portId, _port.getId());
+ assertEquals(_portNumber, _port.getPort());
+ assertEquals(Collections.singleton(PortFactory.DEFAULT_TRANSPORT), _port.getTransports());
+ assertEquals(nonAmqpProtocolSet, _port.getProtocols());
}
@@ -330,7 +347,7 @@ public class PortFactoryTest extends QpidTestCase
try
{
- Port<?> port = _factory.create(Port.class, _attributes, _broker);
+ _port = _factory.create(Port.class, _attributes, _broker);
fail("Exception not thrown");
}
catch (IllegalConfigurationException e)
@@ -353,7 +370,7 @@ public class PortFactoryTest extends QpidTestCase
try
{
- Port<?> port = _factory.create(Port.class, attributes, _broker);
+ _port = _factory.create(Port.class, attributes, _broker);
fail("RMI port creation should fail as another one already exist");
}
catch(IllegalConfigurationException e)
@@ -377,7 +394,7 @@ public class PortFactoryTest extends QpidTestCase
try
{
- Port<?> port = _factory.create(Port.class, attributes, _broker);
+ _port = _factory.create(Port.class, attributes, _broker);
fail("RMI port creation should fail due to requesting SSL");
}
catch(IllegalConfigurationException e)
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java
new file mode 100644
index 0000000000..78ce0d1356
--- /dev/null
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/port/AmqpPortImplTest.java
@@ -0,0 +1,104 @@
+package org.apache.qpid.server.model.port;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.util.Collections;
+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.logging.EventLogger;
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.BrokerModel;
+import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class AmqpPortImplTest extends QpidTestCase
+{
+ private static final String AUTHENTICATION_PROVIDER_NAME = "test";
+ private TaskExecutor _taskExecutor;
+ private Broker _broker;
+ private ServerSocket _socket;
+ private AmqpPortImpl _port;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance();
+ Model model = BrokerModel.getInstance();
+
+ _broker = mock(Broker.class);
+ when(_broker.getTaskExecutor()).thenReturn(_taskExecutor);
+ when(_broker.getModel()).thenReturn(model);
+ when(_broker.getId()).thenReturn(UUID.randomUUID());
+ when(_broker.getSecurityManager()).thenReturn(new SecurityManager(_broker, false));
+ when(_broker.getCategoryClass()).thenReturn(Broker.class);
+ when(_broker.getEventLogger()).thenReturn(new EventLogger());
+ AuthenticationProvider<?> provider = mock(AuthenticationProvider.class);
+ when(provider.getName()).thenReturn(AUTHENTICATION_PROVIDER_NAME);
+ when(provider.getParent(Broker.class)).thenReturn(_broker);
+ when(_broker.getChildren(AuthenticationProvider.class)).thenReturn(Collections.<AuthenticationProvider>singleton(provider));
+ when(_broker.getChildByName(AuthenticationProvider.class, AUTHENTICATION_PROVIDER_NAME)).thenReturn(provider);
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_socket != null)
+ {
+ _socket.close();
+ }
+ _taskExecutor.stop();
+ }
+ finally
+ {
+ if (_port != null)
+ {
+ _port.close();
+ }
+ super.tearDown();
+ }
+ }
+
+ public void testValidateOnCreate() throws Exception
+ {
+ _socket = openSocket();
+
+ Map<String, Object> attributes = new HashMap<>();
+ attributes.put(AmqpPort.PORT, _socket.getLocalPort());
+ attributes.put(AmqpPort.NAME, getTestName());
+ attributes.put(AmqpPort.AUTHENTICATION_PROVIDER, AUTHENTICATION_PROVIDER_NAME);
+ _port = new AmqpPortImpl(attributes, _broker);
+ try
+ {
+ _port.create();
+ fail("Creation should fail due to validation check");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message",
+ String.format("Cannot bind to port %d and binding address '%s'. Port is already is use.",
+ _socket.getLocalPort(), "*"), e.getMessage());
+ }
+ }
+
+ private ServerSocket openSocket() throws IOException
+ {
+ ServerSocket serverSocket = new ServerSocket();
+ serverSocket.setReuseAddress(true);
+ serverSocket.bind(new InetSocketAddress(findFreePort()));
+ return serverSocket;
+ }
+}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java
new file mode 100644
index 0000000000..0ba5673f91
--- /dev/null
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/testmodel/TestConfiguredObject.java
@@ -0,0 +1,123 @@
+package org.apache.qpid.server.model.testmodel;
+
+import static org.mockito.Mockito.mock;
+
+import java.util.Collections;
+import java.util.Map;
+
+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.AbstractConfiguredObject;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.StateTransition;
+
+@ManagedObject
+public class TestConfiguredObject extends AbstractConfiguredObject
+{
+ private boolean _throwExceptionOnOpen;
+ private boolean _opened;
+ private boolean _throwExceptionOnValidationOnCreate;
+ private boolean _throwExceptionOnPostResolve;
+ private boolean _throwExceptionOnCreate;
+
+ public TestConfiguredObject(String name)
+ {
+ this(createParents(), Collections.<String, Object>singletonMap(ConfiguredObject.NAME, name), createTaskExecutor(), new TestModel(null));
+ }
+
+ public final static Map<Class<? extends ConfiguredObject>, ConfiguredObject<?>> createParents()
+ {
+ return Collections.<Class<? extends ConfiguredObject>, ConfiguredObject<?>>singletonMap(null, mock(ConfiguredObject.class));
+ }
+
+ public final static TaskExecutor createTaskExecutor()
+ {
+ TaskExecutor taskExecutor = new CurrentThreadTaskExecutor();
+ taskExecutor.start();
+ return taskExecutor;
+ }
+
+ public TestConfiguredObject(Map parents, Map<String, Object> attributes, TaskExecutor taskExecutor, Model model)
+ {
+ super(parents, attributes, taskExecutor, model);
+ _opened = false;
+ }
+
+ @Override
+ protected void postResolve()
+ {
+ if (_throwExceptionOnPostResolve)
+ {
+ throw new IllegalConfigurationException("Cannot resolve");
+ }
+ }
+
+ @Override
+ protected void onCreate()
+ {
+ if (_throwExceptionOnCreate)
+ {
+ throw new IllegalConfigurationException("Cannot create");
+ }
+ }
+
+ @Override
+ protected void onOpen()
+ {
+ if (_throwExceptionOnOpen)
+ {
+ throw new IllegalConfigurationException("Cannot open");
+ }
+ _opened = true;
+ }
+
+ @Override
+ protected void validateOnCreate()
+ {
+ if (_throwExceptionOnValidationOnCreate)
+ {
+ throw new IllegalConfigurationException("Cannot validate on create");
+ }
+ }
+
+ @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED}, desiredState = State.ACTIVE )
+ protected void activate()
+ {
+ setState(State.ACTIVE);
+ }
+
+ @StateTransition( currentState = {State.ERRORED, State.UNINITIALIZED}, desiredState = State.DELETED )
+ protected void doDelete()
+ {
+ setState(State.DELETED);
+ }
+
+ public boolean isOpened()
+ {
+ return _opened;
+ }
+
+ public void setThrowExceptionOnOpen(boolean throwException)
+ {
+ _throwExceptionOnOpen = throwException;
+ }
+
+ public void setThrowExceptionOnValidationOnCreate(boolean throwException)
+ {
+ _throwExceptionOnValidationOnCreate = throwException;
+ }
+
+ public void setThrowExceptionOnPostResolve(boolean throwException)
+ {
+ _throwExceptionOnPostResolve = throwException;
+ }
+
+ public void setThrowExceptionOnCreate(boolean throwExceptionOnCreate)
+ {
+ _throwExceptionOnCreate = throwExceptionOnCreate;
+ }
+}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
index 703a8d43c9..84ba7a3822 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java
@@ -90,31 +90,28 @@ public class PrincipalDatabaseAuthenticationManagerTest extends QpidTestCase
private void setupMocks() throws Exception
{
- _principalDatabase = mock(PrincipalDatabase.class);
-
- when(_principalDatabase.getMechanisms()).thenReturn(Collections.singletonList(MOCK_MECH_NAME));
- when(_principalDatabase.createSaslServer(MOCK_MECH_NAME, LOCALHOST, null)).thenReturn(new MySaslServer(false, true));
+ setUpPrincipalDatabase();
setupManager(false);
_manager.initialise();
}
+ private void setUpPrincipalDatabase() throws SaslException
+ {
+ _principalDatabase = mock(PrincipalDatabase.class);
+
+ when(_principalDatabase.getMechanisms()).thenReturn(Collections.singletonList(MOCK_MECH_NAME));
+ when(_principalDatabase.createSaslServer(MOCK_MECH_NAME, LOCALHOST, null)).thenReturn(new MySaslServer(false, true));
+ }
+
private void setupManager(final boolean recovering)
{
Map<String,Object> attrs = new HashMap<String, Object>();
attrs.put(ConfiguredObject.ID, UUID.randomUUID());
attrs.put(ConfiguredObject.NAME, getTestName());
attrs.put("path", _passwordFileLocation);
- _manager = new PrincipalDatabaseAuthenticationManager(attrs, BrokerTestHelper.createBrokerMock())
- {
- @Override
- protected PrincipalDatabase createDatabase()
- {
- return _principalDatabase;
- }
-
- };
+ _manager = getPrincipalDatabaseAuthenticationManager(attrs);
if(recovering)
{
_manager.open();
@@ -273,6 +270,41 @@ public class PrincipalDatabaseAuthenticationManagerTest extends QpidTestCase
assertFalse("Password file was not deleted", new File(_passwordFileLocation).exists());
}
+ public void testCreateForInvalidPath() throws Exception
+ {
+ setUpPrincipalDatabase();
+
+ Map<String,Object> attrs = new HashMap<>();
+ attrs.put(ConfiguredObject.ID, UUID.randomUUID());
+ attrs.put(ConfiguredObject.NAME, getTestName());
+ String path = TMP_FOLDER + File.separator + getTestName() + System.nanoTime() + File.separator + "users";
+ attrs.put("path", path);
+
+ _manager = getPrincipalDatabaseAuthenticationManager(attrs);
+ try
+ {
+ _manager.create();
+ fail("Creation with invalid path should have failed");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message:" + e.getMessage(), String.format("Cannot create password file at '%s'", path), e.getMessage());
+ }
+ }
+
+ PrincipalDatabaseAuthenticationManager getPrincipalDatabaseAuthenticationManager(final Map<String, Object> attrs)
+ {
+ return new PrincipalDatabaseAuthenticationManager(attrs, BrokerTestHelper.createBrokerMock())
+ {
+ @Override
+ protected PrincipalDatabase createDatabase()
+ {
+ return _principalDatabase;
+ }
+
+ };
+ }
+
private void deletePasswordFileIfExists()
{
File passwordFile = new File(_passwordFileLocation);
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java
index 52f70e7fd6..c220876a23 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerRecovererTest.java
@@ -21,7 +21,9 @@
package org.apache.qpid.server.store;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
import java.util.Arrays;
import java.util.Collections;
@@ -40,6 +42,7 @@ import org.apache.qpid.server.logging.LogRecorder;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.BrokerModel;
+import org.apache.qpid.server.model.BrokerShutdownProvider;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.model.JsonSystemConfigImpl;
@@ -55,6 +58,7 @@ public class BrokerRecovererTest extends TestCase
private UUID _authenticationProvider1Id = UUID.randomUUID();
private SystemConfig<?> _systemConfig;
private TaskExecutor _taskExecutor;
+ private BrokerShutdownProvider _brokerShutdownProvider;
@Override
protected void setUp() throws Exception
@@ -63,8 +67,11 @@ public class BrokerRecovererTest extends TestCase
_taskExecutor = new CurrentThreadTaskExecutor();
_taskExecutor.start();
+ _brokerShutdownProvider = mock(BrokerShutdownProvider.class);
_systemConfig = new JsonSystemConfigImpl(_taskExecutor,
- mock(EventLogger.class), mock(LogRecorder.class), new BrokerOptions());
+ mock(EventLogger.class), mock(LogRecorder.class),
+ new BrokerOptions(),
+ _brokerShutdownProvider);
when(_brokerEntry.getId()).thenReturn(_brokerId);
when(_brokerEntry.getType()).thenReturn(Broker.class.getSimpleName());
@@ -251,18 +258,10 @@ public class BrokerRecovererTest extends TestCase
brokerAttributes.put(Broker.NAME, getName());
when(_brokerEntry.getAttributes()).thenReturn(brokerAttributes);
- try
- {
- resolveObjects(_brokerEntry);
- Broker<?> broker = _systemConfig.getBroker();
- broker.open();
- fail("The broker creation should fail due to unsupported model version");
- }
- catch (IllegalConfigurationException e)
- {
- assertEquals("The model version '" + incompatibleVersion
- + "' in configuration is incompatible with the broker model version '" + BrokerModel.MODEL_VERSION + "'", e.getMessage());
- }
+ resolveObjects(_brokerEntry);
+ Broker<?> broker = _systemConfig.getBroker();
+ broker.open();
+ verify(_brokerShutdownProvider).shutdown();
}
}
@@ -276,20 +275,12 @@ public class BrokerRecovererTest extends TestCase
when(_brokerEntry.getAttributes()).thenReturn(brokerAttributes);
- try
- {
- UnresolvedConfiguredObject<? extends ConfiguredObject> recover =
- _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig);
+ UnresolvedConfiguredObject<? extends ConfiguredObject> recover =
+ _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig);
- Broker<?> broker = (Broker<?>) recover.resolve();
- broker.open();
- fail("The broker creation should fail due to unsupported model version");
- }
- catch (IllegalConfigurationException e)
- {
- assertEquals("The model version '" + incompatibleVersion
- + "' in configuration is incompatible with the broker model version '" + BrokerModel.MODEL_VERSION + "'", e.getMessage());
- }
+ Broker<?> broker = (Broker<?>) recover.resolve();
+ broker.open();
+ verify(_brokerShutdownProvider).shutdown();
}
public void testIncorrectModelVersion() throws Exception
@@ -303,18 +294,12 @@ public class BrokerRecovererTest extends TestCase
brokerAttributes.put(Broker.MODEL_VERSION, modelVersion);
when(_brokerEntry.getAttributes()).thenReturn(brokerAttributes);
- try
- {
- UnresolvedConfiguredObject<? extends ConfiguredObject> recover =
- _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig);
- Broker<?> broker = (Broker<?>) recover.resolve();
- broker.open();
- fail("The broker creation should fail due to unsupported model version");
- }
- catch (IllegalConfigurationException e)
- {
- // pass
- }
+ UnresolvedConfiguredObject<? extends ConfiguredObject> recover =
+ _systemConfig.getObjectFactory().recover(_brokerEntry, _systemConfig);
+ Broker<?> broker = (Broker<?>) recover.resolve();
+ broker.open();
+ verify(_brokerShutdownProvider).shutdown();
+ reset(_brokerShutdownProvider);
}
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java
index c94a0ef9c4..45b595b62e 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/store/BrokerStoreUpgraderAndRecovererTest.java
@@ -32,6 +32,7 @@ import org.apache.qpid.server.BrokerOptions;
import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor;
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.ConfiguredObject;
import org.apache.qpid.server.model.JsonSystemConfigImpl;
import org.apache.qpid.server.model.SystemConfig;
@@ -60,7 +61,8 @@ public class BrokerStoreUpgraderAndRecovererTest extends QpidTestCase
_systemConfig = new JsonSystemConfigImpl(_taskExecutor,
mock(EventLogger.class),
mock(LogRecorder.class),
- new BrokerOptions());
+ new BrokerOptions(),
+ mock(BrokerShutdownProvider.class));
}
public void testUpgradeVirtualHostWithJDBCStoreAndBoneCPPool()
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java
new file mode 100644
index 0000000000..889097f850
--- /dev/null
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhost/AbstractVirtualHostTest.java
@@ -0,0 +1,247 @@
+/*
+ *
+ * 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;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doThrow;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.configuration.updater.TaskExecutorImpl;
+import org.apache.qpid.server.logging.EventLogger;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.BrokerModel;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.model.SystemConfig;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.model.VirtualHostNode;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.store.DurableConfigurationStore;
+import org.apache.qpid.server.store.MessageStore;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.mockito.verification.VerificationMode;
+
+public class AbstractVirtualHostTest extends QpidTestCase
+{
+ private TaskExecutor _taskExecutor;
+ private VirtualHostNode<?> _node;
+ private MessageStore _failingStore;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+
+ SystemConfig systemConfig = mock(SystemConfig.class);
+ when(systemConfig.getEventLogger()).thenReturn(mock(EventLogger.class));
+ Broker<?> broker = mock(Broker.class);
+ when(broker.getParent(SystemConfig.class)).thenReturn(systemConfig);
+ when(broker.getSecurityManager()).thenReturn(new SecurityManager(broker, false));
+
+ _taskExecutor = new TaskExecutorImpl();
+ _taskExecutor.start();
+ when(broker.getTaskExecutor()).thenReturn(_taskExecutor);
+
+ _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));
+
+ _failingStore = mock(MessageStore.class);
+ doThrow(new RuntimeException("Cannot open store")).when(_failingStore).openMessageStore(any(ConfiguredObject.class));
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ if (_taskExecutor != null)
+ {
+ _taskExecutor.stopImmediately();
+ }
+ }
+ finally
+ {
+ super.tearDown();
+ }
+ }
+
+ public void testValidateOnCreateFails()
+ {
+ Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName());
+
+ AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node)
+ {
+ @Override
+ protected MessageStore createMessageStore()
+ {
+ return _failingStore;
+ }
+ };
+
+ try
+ {
+ host.validateOnCreate();
+ fail("Validation on creation should fail");
+ }
+ catch(IllegalConfigurationException e)
+ {
+ assertTrue("Unexpected exception " + e.getMessage(), e.getMessage().startsWith("Cannot open virtual host message store"));
+ }
+ }
+
+ public void testValidateOnCreateSucceeds()
+ {
+ Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName());
+ final MessageStore store = mock(MessageStore.class);
+ AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node)
+ {
+ @Override
+ protected MessageStore createMessageStore()
+ {
+ return store;
+ }
+ };
+
+ host.validateOnCreate();
+ verify(store).openMessageStore(host);
+ verify(store).closeMessageStore();
+ }
+
+ public void testOpenFails()
+ {
+ Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName());
+
+ AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node)
+ {
+ @Override
+ protected MessageStore createMessageStore()
+ {
+ return _failingStore;
+ }
+ };
+
+ host.open();
+ assertEquals("Unexpected host state", State.ERRORED, host.getState());
+ }
+
+ public void testOpenSucceeds()
+ {
+ Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName());
+ final MessageStore store = mock(MessageStore.class);
+ AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node)
+ {
+ @Override
+ protected MessageStore createMessageStore()
+ {
+ return store;
+ }
+ };
+
+ host.open();
+ assertEquals("Unexpected host state", State.ACTIVE, host.getState());
+ verify(store).openMessageStore(host);
+
+ // make sure that method AbstractVirtualHost.onExceptionInOpen was not called
+ verify(store, times(0)).closeMessageStore();
+ }
+
+ public void testDeleteInErrorStateAfterOpen()
+ {
+ Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName());
+ AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node)
+ {
+ @Override
+ protected MessageStore createMessageStore()
+ {
+ return _failingStore;
+ }
+ };
+
+ host.open();
+
+ assertEquals("Unexpected state", State.ERRORED, host.getState());
+
+ host.delete();
+ assertEquals("Unexpected state", State.DELETED, host.getState());
+ }
+
+ public void testActivateInErrorStateAfterOpen() throws Exception
+ {
+ Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName());
+ final MessageStore store = mock(MessageStore.class);
+ doThrow(new RuntimeException("Cannot open store")).when(store).openMessageStore(any(ConfiguredObject.class));
+ AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node)
+ {
+ @Override
+ protected MessageStore createMessageStore()
+ {
+ return store;
+ }
+ };
+
+ host.open();
+ assertEquals("Unexpected state", State.ERRORED, host.getState());
+
+ doNothing().when(store).openMessageStore(any(ConfiguredObject.class));
+
+ host.setAttributes(Collections.<String, Object>singletonMap(VirtualHost.DESIRED_STATE, State.ACTIVE));
+ assertEquals("Unexpected state", State.ACTIVE, host.getState());
+ }
+
+ public void testStartInErrorStateAfterOpen() throws Exception
+ {
+ Map<String,Object> attributes = Collections.<String, Object>singletonMap(AbstractVirtualHost.NAME, getTestName());
+ final MessageStore store = mock(MessageStore.class);
+ doThrow(new RuntimeException("Cannot open store")).when(store).openMessageStore(any(ConfiguredObject.class));
+ AbstractVirtualHost host = new AbstractVirtualHost(attributes, _node)
+ {
+ @Override
+ protected MessageStore createMessageStore()
+ {
+ return store;
+ }
+ };
+
+ host.open();
+ assertEquals("Unexpected state", State.ERRORED, host.getState());
+
+ doNothing().when(store).openMessageStore(any(ConfiguredObject.class));
+
+ host.start();
+ assertEquals("Unexpected state", State.ACTIVE, host.getState());
+ }
+}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
index 971c96b2ff..b17f383217 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/AbstractStandardVirtualHostNodeTest.java
@@ -20,22 +20,30 @@
*/
package org.apache.qpid.server.virtualhostnode;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.security.AccessControlException;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
+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.ConfiguredObject;
import org.apache.qpid.server.model.ConfiguredObjectFactoryImpl;
import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.model.RemoteReplicationNode;
import org.apache.qpid.server.model.State;
import org.apache.qpid.server.model.SystemConfig;
import org.apache.qpid.server.model.VirtualHost;
@@ -348,6 +356,132 @@ public class AbstractStandardVirtualHostNodeTest extends QpidTestCase
assertEquals("Virtual host node state changed unexpectedly", State.ACTIVE, node.getState());
}
+ public void testValidateOnCreateFails() throws Exception
+ {
+ String nodeName = getTestName();
+ Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName);
+
+ final DurableConfigurationStore store = mock(DurableConfigurationStore.class);
+ doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class));
+ AbstractStandardVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store);
+
+ try
+ {
+ node.validateOnCreate();
+ fail("Cannot create node");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertTrue("Unexpected exception " + e.getMessage(), e.getMessage().startsWith("Cannot open node configuration store"));
+ }
+ }
+
+ public void testValidateOnCreateSucceeds() throws Exception
+ {
+ String nodeName = getTestName();
+ Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName);
+
+ final DurableConfigurationStore store = mock(DurableConfigurationStore.class);
+ AbstractStandardVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store);
+
+ node.validateOnCreate();
+ verify(store).openConfigurationStore(node, false);
+ verify(store).closeConfigurationStore();
+ }
+
+ public void testOpenFails() throws Exception
+ {
+ String nodeName = getTestName();
+ Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName);
+
+ DurableConfigurationStore store = mock(DurableConfigurationStore.class);
+ AbstractVirtualHostNode node = new TestAbstractVirtualHostNode( _broker, attributes, store);
+ node.open();
+ assertEquals("Unexpected node state", State.ERRORED, node.getState());
+ }
+
+ public void testOpenSucceeds() throws Exception
+ {
+ String nodeName = getTestName();
+ Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName);
+
+ final AtomicBoolean onFailureFlag = new AtomicBoolean();
+ DurableConfigurationStore store = mock(DurableConfigurationStore.class);
+ AbstractVirtualHostNode node = new TestAbstractVirtualHostNode( _broker, attributes, store)
+ {
+ @Override
+ public void onValidate()
+ {
+ // no op
+ }
+
+ @Override
+ protected void onExceptionInOpen(RuntimeException e)
+ {
+ try
+ {
+ super.onExceptionInOpen(e);
+ }
+ finally
+ {
+ onFailureFlag.set(true);
+ }
+ }
+ };
+
+ node.open();
+ assertEquals("Unexpected node state", State.ACTIVE, node.getState());
+ assertFalse("onExceptionInOpen was called", onFailureFlag.get());
+ }
+
+
+ public void testDeleteInErrorStateAfterOpen()
+ {
+ String nodeName = getTestName();
+ Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName);
+
+ final DurableConfigurationStore store = mock(DurableConfigurationStore.class);
+ doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class));
+ AbstractStandardVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store);
+ node.open();
+ assertEquals("Unexpected node state", State.ERRORED, node.getState());
+
+ node.delete();
+ assertEquals("Unexpected state", State.DELETED, node.getState());
+ }
+
+ public void testActivateInErrorStateAfterOpen() throws Exception
+ {
+ String nodeName = getTestName();
+ Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName);
+
+ DurableConfigurationStore store = mock(DurableConfigurationStore.class);
+ doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class));
+ AbstractVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store);
+ node.open();
+ assertEquals("Unexpected node state", State.ERRORED, node.getState());
+ doNothing().when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class));
+
+ node.setAttributes(Collections.<String, Object>singletonMap(VirtualHostNode.DESIRED_STATE, State.ACTIVE));
+ assertEquals("Unexpected state", State.ACTIVE, node.getState());
+ }
+
+ public void testStartInErrorStateAfterOpen() throws Exception
+ {
+ String nodeName = getTestName();
+ Map<String, Object> attributes = Collections.<String, Object>singletonMap(TestVirtualHostNode.NAME, nodeName);
+
+ DurableConfigurationStore store = mock(DurableConfigurationStore.class);
+ doThrow(new RuntimeException("Cannot open store")).when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class));
+ AbstractVirtualHostNode node = createAbstractStandardVirtualHostNode(attributes, store);
+ node.open();
+ assertEquals("Unexpected node state", State.ERRORED, node.getState());
+ doNothing().when(store).openConfigurationStore(any(ConfiguredObject.class), any(boolean.class));
+
+ node.start();
+ assertEquals("Unexpected state", State.ACTIVE, node.getState());
+ }
+
private ConfiguredObjectRecord createVirtualHostConfiguredObjectRecord(UUID virtualHostId)
{
Map<String, Object> virtualHostAttributes = new HashMap<>();
@@ -384,4 +518,62 @@ public class AbstractStandardVirtualHostNodeTest extends QpidTestCase
return configStoreThatProduces(null);
}
+
+ private AbstractStandardVirtualHostNode createAbstractStandardVirtualHostNode(final Map<String, Object> attributes, final DurableConfigurationStore store)
+ {
+ return new AbstractStandardVirtualHostNode(attributes, _broker){
+
+ @Override
+ protected void writeLocationEventLog()
+ {
+
+ }
+
+ @Override
+ protected DurableConfigurationStore createConfigurationStore()
+ {
+ return store;
+ }
+ };
+ }
+
+ private class TestAbstractVirtualHostNode extends AbstractVirtualHostNode
+ {
+ private DurableConfigurationStore _store;
+
+ public TestAbstractVirtualHostNode(Broker parent, Map attributes, DurableConfigurationStore store)
+ {
+ super(parent, attributes);
+ _store = store;
+ }
+
+ @Override
+ public void onValidate()
+ {
+ throw new RuntimeException("Cannot validate");
+ }
+
+ @Override
+ protected DurableConfigurationStore createConfigurationStore()
+ {
+ return _store;
+ }
+
+ @Override
+ protected void activate()
+ {
+ }
+
+ @Override
+ protected ConfiguredObjectRecord enrichInitialVirtualHostRootRecord(ConfiguredObjectRecord vhostRecord)
+ {
+ return null;
+ }
+
+ @Override
+ public Collection<? extends RemoteReplicationNode> getRemoteReplicationNodes()
+ {
+ return null;
+ }
+ }
}
diff --git a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java
index 277ef8b400..4fe8136624 100644
--- a/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java
+++ b/qpid/java/broker-core/src/test/java/org/apache/qpid/server/virtualhostnode/TestVirtualHostNode.java
@@ -53,6 +53,12 @@ public class TestVirtualHostNode extends AbstractStandardVirtualHostNode<TestVir
}
@Override
+ public DurableConfigurationStore getConfigurationStore()
+ {
+ return _store;
+ }
+
+ @Override
protected void writeLocationEventLog()
{
}
diff --git a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java
index f0edc59025..1adc6561c7 100644
--- a/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java
+++ b/qpid/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImpl.java
@@ -25,10 +25,10 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
import org.apache.qpid.server.model.AbstractConfiguredObject;
import org.apache.qpid.server.model.AccessControlProvider;
import org.apache.qpid.server.model.Broker;
@@ -83,6 +83,29 @@ public class ACLFileAccessControlProviderImpl
}
@Override
+ protected void validateOnCreate()
+ {
+ DefaultAccessControl accessControl = null;
+ try
+ {
+ accessControl = new DefaultAccessControl(getPath(), _broker);
+ accessControl.validate();
+ accessControl.open();
+ }
+ catch(RuntimeException e)
+ {
+ throw new IllegalConfigurationException(e.getMessage(), e);
+ }
+ finally
+ {
+ if (accessControl != null)
+ {
+ accessControl.close();
+ }
+ }
+ }
+
+ @Override
protected void onOpen()
{
super.onOpen();
@@ -105,6 +128,7 @@ public class ACLFileAccessControlProviderImpl
@StateTransition(currentState = {State.UNINITIALIZED, State.QUIESCED, State.ERRORED}, desiredState = State.ACTIVE)
private void activate()
{
+
if(_broker.isManagementMode())
{
@@ -136,7 +160,10 @@ public class ACLFileAccessControlProviderImpl
protected void onClose()
{
super.onClose();
- _accessControl.close();
+ if (_accessControl != null)
+ {
+ _accessControl.close();
+ }
}
@StateTransition(currentState = State.UNINITIALIZED, desiredState = State.QUIESCED)
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java
new file mode 100644
index 0000000000..781e553fe5
--- /dev/null
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/ACLFileAccessControlProviderImplTest.java
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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.security.access.plugins;
+
+
+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.Model;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class ACLFileAccessControlProviderImplTest extends QpidTestCase
+{
+ private TaskExecutor _taskExecutor;
+ private Model _model;
+ private Broker _broker;
+
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _taskExecutor = CurrentThreadTaskExecutor.newStartedInstance();
+ _model = BrokerModel.getInstance();
+
+ _broker = mock(Broker.class);
+ when(_broker.getTaskExecutor()).thenReturn(_taskExecutor);
+ when(_broker.getModel()).thenReturn(_model);
+ when(_broker.getId()).thenReturn(UUID.randomUUID());
+ }
+
+ public void testValidationOnCreateWithNonExistingACLFile()
+ {
+ Map<String,Object> attributes = new HashMap<>();
+ String aclFilePath = TMP_FOLDER + File.separator + "test_" + getTestName() + System.nanoTime() + ".acl";
+ attributes.put("path", aclFilePath);
+ attributes.put(ACLFileAccessControlProvider.NAME, getTestName());
+
+
+ ACLFileAccessControlProviderImpl aclProvider = new ACLFileAccessControlProviderImpl(attributes, _broker);
+ try
+ {
+ aclProvider.create();
+ fail("Exception is expected on validation with non-existing ACL file");
+ }
+ catch (IllegalConfigurationException e)
+ {
+ assertEquals("Unexpected exception message:" + e.getMessage(), String.format("ACL file '%s' is not found", aclFilePath ), e.getMessage());
+ }
+ }
+
+}
diff --git a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java
index 32c5bcd541..a8b9edaa12 100644
--- a/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java
+++ b/qpid/java/broker-plugins/derby-store/src/main/java/org/apache/qpid/server/store/derby/DerbySystemConfigImpl.java
@@ -26,6 +26,7 @@ import org.apache.qpid.server.logging.EventLogger;
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;
@@ -47,9 +48,10 @@ public class DerbySystemConfigImpl extends AbstractSystemConfig<DerbySystemConfi
public DerbySystemConfigImpl(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
diff --git a/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java b/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
index fd1cad7de4..a552b170a0 100644
--- a/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
+++ b/qpid/java/broker-plugins/jdbc-store/src/main/java/org/apache/qpid/server/store/jdbc/JDBCSystemConfigImpl.java
@@ -26,6 +26,7 @@ import org.apache.qpid.server.logging.EventLogger;
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;
@@ -49,9 +50,10 @@ public class JDBCSystemConfigImpl extends AbstractSystemConfig<JDBCSystemConfigI
public JDBCSystemConfigImpl(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
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
index e07705656a..936cc4789a 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
@@ -122,7 +122,7 @@ public class HttpManagement extends AbstractPluginAdapter<HttpManagement> implem
super(attributes, broker);
}
- @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE)
+ @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
private void doStart()
{
getBroker().getEventLogger().message(ManagementConsoleMessages.STARTUP(OPERATIONAL_LOGGING_NAME));
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
index a38aa9e349..85916bf5f2 100644
--- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagementPluginImpl.java
@@ -103,7 +103,7 @@ public class JMXManagementPluginImpl
return _usePlatformMBeanServer;
}
- @StateTransition(currentState = State.UNINITIALIZED, desiredState = State.ACTIVE)
+ @StateTransition(currentState = {State.UNINITIALIZED,State.ERRORED}, desiredState = State.ACTIVE)
private void doStart() throws JMException, IOException
{
_allowPortActivation = true;
diff --git a/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java b/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java
index f644b8f46b..3f5215219b 100644
--- a/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java
+++ b/qpid/java/broker-plugins/memory-store/src/main/java/org/apache/qpid/server/store/MemorySystemConfigImpl.java
@@ -26,6 +26,7 @@ import org.apache.qpid.server.logging.EventLogger;
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.ManagedObject;
import org.apache.qpid.server.model.SystemConfigFactoryConstructor;
@@ -39,9 +40,10 @@ public class MemorySystemConfigImpl extends AbstractSystemConfig<MemorySystemCon
public MemorySystemConfigImpl(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
diff --git a/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java
index 26bbe151d2..00231039c3 100644
--- a/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java
+++ b/qpid/java/qpid-test-utils/src/main/java/org/apache/qpid/test/utils/TestFileUtils.java
@@ -121,33 +121,38 @@ public class TestFileUtils
File file = createTempFile(testcase, suffix);
if (content != null)
{
- FileOutputStream fos = null;
- try
- {
- fos = new FileOutputStream(file);
- fos.write(content.getBytes("UTF-8"));
- fos.flush();
- }
- catch (Exception e)
- {
- throw new RuntimeException("Cannot add the content into temp file " + file.getAbsolutePath(), e);
- }
- finally
+ saveTextContentInFile(content, file);
+ }
+ return file;
+ }
+
+ public static void saveTextContentInFile(String content, File file)
+ {
+ FileOutputStream fos = null;
+ try
+ {
+ fos = new FileOutputStream(file);
+ fos.write(content.getBytes("UTF-8"));
+ fos.flush();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Cannot add the content into temp file " + file.getAbsolutePath(), e);
+ }
+ finally
+ {
+ if (fos != null)
{
- if (fos != null)
+ try
{
- try
- {
- fos.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException("Cannot close output stream into temp file " + file.getAbsolutePath(), e);
- }
+ fos.close();
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Cannot close output stream into temp file " + file.getAbsolutePath(), e);
}
}
}
- return file;
}
/**
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
index 70e1b27fba..c7bcdd2edb 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/TestBrokerConfiguration.java
@@ -49,6 +49,7 @@ import org.apache.qpid.server.model.AccessControlProvider;
import org.apache.qpid.server.model.AuthenticationProvider;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.BrokerModel;
+import org.apache.qpid.server.model.BrokerShutdownProvider;
import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.GroupProvider;
import org.apache.qpid.server.model.JsonSystemConfigImpl;
@@ -105,7 +106,8 @@ public class TestBrokerConfiguration
final AbstractSystemConfig parentObject = new JsonSystemConfigImpl(taskExecutor,
mock(EventLogger.class),
mock(LogRecorder.class),
- brokerOptions);
+ brokerOptions,
+ mock(BrokerShutdownProvider.class));
ConfiguredObjectRecordConverter converter = new ConfiguredObjectRecordConverter(BrokerModel.getInstance());
@@ -215,7 +217,8 @@ public class TestBrokerConfiguration
final SystemConfig parentObject = configFactory.newInstance(_taskExecutor,
mock(EventLogger.class),
mock(LogRecorder.class),
- brokerOptions);
+ brokerOptions,
+ mock(BrokerShutdownProvider.class));
parentObject.open();
DurableConfigurationStore configurationStore = parentObject.getConfigurationStore();
diff --git a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/PortRestTest.java b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/PortRestTest.java
index 8b86163aa6..538bd3b32a 100644
--- a/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/PortRestTest.java
+++ b/qpid/java/systests/src/test/java/org/apache/qpid/systest/rest/PortRestTest.java
@@ -358,9 +358,9 @@ public class PortRestTest extends QpidRestTestCase
attributes.put(Port.AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER);
int responseCode = getRestTestHelper().submitRequest("port/" + newPortName, "PUT", attributes);
- assertEquals("Unexpected response code for port creation", 201, responseCode);
+ assertEquals("Unexpected response code for port creation", 409, responseCode);
- portData = getRestTestHelper().getJsonAsSingletonList("port/" + URLDecoder.decode(newPortName, "UTF-8"));
- Asserts.assertPortAttributes(portData, State.ERRORED);
+ List<Map<String,Object>> ports = getRestTestHelper().getJsonAsList("port/" + URLDecoder.decode(newPortName, "UTF-8"));
+ assertTrue("Port should not be created", ports.isEmpty());
}
}