diff options
author | Robert Godfrey <rgodfrey@apache.org> | 2009-10-24 10:46:17 +0000 |
---|---|---|
committer | Robert Godfrey <rgodfrey@apache.org> | 2009-10-24 10:46:17 +0000 |
commit | eb09581fcc5f42f3d2d8a4b041c49597a30d4759 (patch) | |
tree | 50650c16aa59643811676c78305b2836738f930d | |
parent | 7fbe6d6762ec250721558e60c75e21d7d6b4c3c3 (diff) | |
download | qpid-python-eb09581fcc5f42f3d2d8a4b041c49597a30d4759.tar.gz |
Merged from trunk up to r829106
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-broker-0-10@829340 13f79535-47bb-0310-9956-ffa450edef68
32 files changed, 986 insertions, 501 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/NullRootMessageLogger.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/NullRootMessageLogger.java new file mode 100644 index 0000000000..6cd29b95fb --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/NullRootMessageLogger.java @@ -0,0 +1,60 @@ +/* + * + * 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.logging; + +import org.apache.qpid.server.configuration.ServerConfiguration; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.configuration.ConfigurationException; + +public class NullRootMessageLogger extends RootMessageLoggerImpl +{ + + public NullRootMessageLogger() throws ConfigurationException + { + super(new ServerConfiguration(new PropertiesConfiguration()), new NullMessageLogger()); + } + + @Override + public boolean isMessageEnabled(LogActor actor, LogSubject subject) + { + return false; + } + + @Override + public boolean isMessageEnabled(LogActor actor) + { + return false; + } + + public static class NullMessageLogger implements RawMessageLogger + { + public void rawMessage(String message) + { + // drop message + } + + public void rawMessage(String message, Throwable throwable) + { + // drop message + } + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java index 3c47cdd094..c36eeb5016 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/management/LoggingManagementMBean.java @@ -29,6 +29,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Random; import org.apache.qpid.management.common.mbeans.LoggingManagement; import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; @@ -365,10 +366,17 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM DOMSource source = new DOMSource(doc); File tmp; + Random r = new Random(); + do + { + tmp = new File(log4jConfigFile.getPath() + r.nextInt() + ".tmp"); + } + while(tmp.exists()); + + tmp.deleteOnExit(); + try { - tmp = File.createTempFile("LogManMBeanTemp", ".tmp"); - tmp.deleteOnExit(); StreamResult result = new StreamResult(tmp); transformer.transform(source, result); } @@ -377,11 +385,6 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM _logger.warn("Could not transform the XML into new file: " +e); throw new IOException("Could not transform the XML into new file: " +e); } - catch (IOException e) - { - _logger.warn("Could not create the new log4j XML file: " +e); - throw new IOException("Could not create the new log4j XML file: " +e); - } // Swap temp file in to replace existing configuration file. File old = new File(log4jConfigFile.getAbsoluteFile() + ".old"); @@ -390,30 +393,26 @@ public class LoggingManagementMBean extends AMQManagedObject implements LoggingM old.delete(); } - try + if(!log4jConfigFile.renameTo(old)) { - if(!log4jConfigFile.renameTo(old)) - { - FileUtils.copyCheckedEx(log4jConfigFile, old); - } + //unable to rename the existing file to the backup name + _logger.error("Could not backup the existing log4j XML file"); + throw new IOException("Could not backup the existing log4j XML file"); } - catch (IOException e) - { - _logger.warn("Could not backup the existing log4j XML file: " +e); - throw new IOException("Could not backup the existing log4j XML file: " +e); - } - - try + + if(!tmp.renameTo(log4jConfigFile)) { - if(!tmp.renameTo(log4jConfigFile)) + //failed to rename the new file to the required filename + + if(!old.renameTo(log4jConfigFile)) { - FileUtils.copyCheckedEx(tmp, log4jConfigFile); + //unable to return the backup to required filename + _logger.error("Could not rename the new log4j configuration file into place, and unable to restore original file"); + throw new IOException("Could not rename the new log4j configuration file into place, and unable to restore original file"); } - } - catch (IOException e) - { - _logger.warn("Could not copy the new configuration into place: " +e); - throw new IOException("Could not copy the new configuration into place: " +e); + + _logger.error("Could not rename the new log4j configuration file into place"); + throw new IOException("Could not rename the new log4j configuration file into place"); } return true; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java index 0b95d213f4..a299907e42 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java @@ -47,7 +47,6 @@ public class PrincipalPermissions private static final Object CREATE_QUEUE_QUEUES_KEY = new Object(); private static final Object CREATE_QUEUE_EXCHANGES_KEY = new Object(); - private static final Object CREATE_QUEUE_EXCHANGES_TEMPORARY_KEY = new Object(); private static final Object CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY = new Object(); private static final int PUBLISH_EXCHANGES_KEY = 0; @@ -181,165 +180,168 @@ public class PrincipalPermissions rights.put(name, className); } - private void grantCreateQueue(Permission permission, Object... parameters) { - Map createRights = (Map) _permissions.get(permission); - - if (createRights == null) - { - createRights = new ConcurrentHashMap(); - _permissions.put(permission, createRights); - - } - - //The existence of the empty map mean permission to all. - if (parameters.length == 0) - { - return; - } - - Boolean temporary = (Boolean) parameters[0]; - - AMQShortString queueName = parameters.length > 1 ? (AMQShortString) parameters[1] : null; - AMQShortString exchangeName = parameters.length > 2 ? (AMQShortString) parameters[2] : null; - //Set the routingkey to the specified value or the queueName if present - AMQShortString routingKey = (parameters.length > 3 && null != parameters[3]) ? (AMQShortString) parameters[3] : queueName; - - // Get the queues map - Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY); - - if (create_queues == null) - { - create_queues = new ConcurrentHashMap(); - createRights.put(CREATE_QUEUES_KEY, create_queues); - } - - //Allow all temp queues to be created - create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, temporary); - - //Create empty list of queues - Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY); - - if (create_queues_queues == null) - { - create_queues_queues = new ConcurrentHashMap(); - create_queues.put(CREATE_QUEUE_QUEUES_KEY, create_queues_queues); - } - - // We are granting CREATE rights to all temporary queues only - if (parameters.length == 1) - { - return; - } + private void grantCreateQueue(Permission permission, Object... parameters) + { + Map createRights = (Map) _permissions.get(permission); - // if we have a queueName then we need to store any associated exchange / rk bindings - if (queueName != null) - { - Map queue = (Map) create_queues_queues.get(queueName); - if (queue == null) - { - queue = new ConcurrentHashMap(); - create_queues_queues.put(queueName, queue); - } + if (createRights == null) + { + createRights = new ConcurrentHashMap(); + _permissions.put(permission, createRights); + } - if (exchangeName != null) - { - queue.put(exchangeName, routingKey); - } + //The existence of the empty map mean permission to all. + if (parameters.length == 0) + { + return; + } - //If no exchange is specified then the presence of the queueName in the map says any exchange is ok - } + // Get the queues map + Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY); - // Store the exchange that we are being granted rights to. This will be used as part of binding + //Initialiase the queue permissions if not already done + if (create_queues == null) + { + create_queues = new ConcurrentHashMap(); + //initialise temp queue permission to false and overwrite below if true + create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, false); + createRights.put(CREATE_QUEUES_KEY, create_queues); + } - //Lookup the list of exchanges - Map create_queues_exchanges = (Map) create_queues.get(CREATE_QUEUE_EXCHANGES_KEY); + //Create empty list of queues + Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY); - if (create_queues_exchanges == null) - { - create_queues_exchanges = new ConcurrentHashMap(); - create_queues.put(CREATE_QUEUE_EXCHANGES_KEY, create_queues_exchanges); - } + if (create_queues_queues == null) + { + create_queues_queues = new ConcurrentHashMap(); + create_queues.put(CREATE_QUEUE_QUEUES_KEY, create_queues_queues); + } - //if we have an exchange - if (exchangeName != null) - { - //Retrieve the list of permitted exchanges. - Map exchanges = (Map) create_queues_exchanges.get(exchangeName); + // If we are initialising and granting CREATE rights to all temporary queues, then that's all we do + Boolean temporary = false; + if (parameters.length == 1) + { + temporary = (Boolean) parameters[0]; + create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, temporary); + return; + } - if (exchanges == null) - { - exchanges = new ConcurrentHashMap(); - create_queues_exchanges.put(exchangeName, exchanges); - } + //From here we can be permissioning a variety of things, with varying parameters + AMQShortString queueName = parameters.length > 1 ? (AMQShortString) parameters[1] : null; + AMQShortString exchangeName = parameters.length > 2 ? (AMQShortString) parameters[2] : null; + //Set the routingkey to the specified value or the queueName if present + AMQShortString routingKey = (parameters.length > 3 && null != parameters[3]) ? (AMQShortString) parameters[3] : queueName; + // if we have a queueName then we need to store any associated exchange / rk bindings + if (queueName != null) + { + Map queue = (Map) create_queues_queues.get(queueName); + if (queue == null) + { + queue = new ConcurrentHashMap(); + create_queues_queues.put(queueName, queue); + } + + if (exchangeName != null) + { + queue.put(exchangeName, routingKey); + } + + //If no exchange is specified then the presence of the queueName in the map says any exchange is ok + } - //Store the temporary setting CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY - exchanges.put(CREATE_QUEUE_EXCHANGES_TEMPORARY_KEY, temporary); + // Store the exchange that we are being granted rights to. This will be used as part of binding - //Store the binding details of queue/rk for this exchange. - if (queueName != null) - { - //Retrieve the list of permitted routingKeys. - Map rKeys = (Map) exchanges.get(exchangeName); + //Lookup the list of exchanges + Map create_queues_exchanges = (Map) create_queues.get(CREATE_QUEUE_EXCHANGES_KEY); - if (rKeys == null) - { - rKeys = new ConcurrentHashMap(); - exchanges.put(CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY, rKeys); - } + if (create_queues_exchanges == null) + { + create_queues_exchanges = new ConcurrentHashMap(); + create_queues.put(CREATE_QUEUE_EXCHANGES_KEY, create_queues_exchanges); + } - rKeys.put(queueName, routingKey); - } - } - } + //if we have an exchange + if (exchangeName != null) + { + //Retrieve the list of permitted exchanges. + Map exchanges = (Map) create_queues_exchanges.get(exchangeName); + + if (exchanges == null) + { + exchanges = new ConcurrentHashMap(); + create_queues_exchanges.put(exchangeName, exchanges); + } + + //Store the binding details of queue/rk for this exchange. + if (queueName != null) + { + //Retrieve the list of permitted routingKeys. + Map rKeys = (Map) exchanges.get(exchangeName); + + if (rKeys == null) + { + rKeys = new ConcurrentHashMap(); + exchanges.put(CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY, rKeys); + } - private void grantConsume(Permission permission, Object... parameters) { - Map consumeRights = (Map) _permissions.get(permission); + rKeys.put(queueName, routingKey); + } + } + } - if (consumeRights == null) - { - consumeRights = new ConcurrentHashMap(); - _permissions.put(permission, consumeRights); - } + /** + * Grant consume permissions + */ + private void grantConsume(Permission permission, Object... parameters) + { + Map consumeRights = (Map) _permissions.get(permission); - //if we have parametsre - if (parameters.length > 0) - { - AMQShortString queueName = (AMQShortString) parameters[0]; - Boolean temporary = (Boolean) parameters[1]; - Boolean ownQueueOnly = (Boolean) parameters[2]; + if (consumeRights == null) + { + consumeRights = new ConcurrentHashMap(); + _permissions.put(permission, consumeRights); - if (temporary) - { - consumeRights.put(CONSUME_TEMPORARY_KEY, true); - } - else - { - consumeRights.put(CONSUME_TEMPORARY_KEY, false); - } + //initialise own and temporary rights to false to be overwritten below if set + consumeRights.put(CONSUME_TEMPORARY_KEY, false); + consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, false); + } - if (ownQueueOnly) - { - consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, true); - } - else - { - consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, false); - } + //if we only have one param then we're permissioning temporary queues and topics + if (parameters.length == 1) + { + Boolean temporary = (Boolean) parameters[0]; - LinkedList queues = (LinkedList) consumeRights.get(CONSUME_QUEUES_KEY); - if (queues == null) - { - queues = new LinkedList(); - consumeRights.put(CONSUME_QUEUES_KEY, queues); - } + if (temporary) + { + consumeRights.put(CONSUME_TEMPORARY_KEY, true); + } + } - if (queueName != null) - { - queues.add(queueName); - } - } - } + //if we have 2 parameters - should be a contract for this, but for now we'll handle it as is + if (parameters.length == 2) + { + AMQShortString queueName = (AMQShortString) parameters[0]; + Boolean ownQueueOnly = (Boolean) parameters[1]; + + if (ownQueueOnly) + { + consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, true); + } + + LinkedList queues = (LinkedList) consumeRights.get(CONSUME_QUEUES_KEY); + if (queues == null) + { + queues = new LinkedList(); + consumeRights.put(CONSUME_QUEUES_KEY, queues); + } + + if (queueName != null) + { + queues.add(queueName); + } + } + } /** * @@ -399,63 +401,64 @@ public class PrincipalPermissions //user has been granted full access to the vhost return AuthzResult.ALLOWED; } - - if (parameters.length == 1 && parameters[0] instanceof AMQQueue) - { - AMQQueue queue = ((AMQQueue) parameters[0]); - Map queuePermissions = (Map) _permissions.get(permission); - - if (queuePermissions == null) - { - //if the outer map is null, the user has no CONSUME rights at all - return AuthzResult.DENIED; - } - List queues = (List) queuePermissions.get(CONSUME_QUEUES_KEY); + if (parameters.length == 1 && parameters[0] instanceof AMQQueue) + { + AMQQueue queue = ((AMQQueue) parameters[0]); + Map queuePermissions = (Map) _permissions.get(permission); - Boolean temporayQueues = (Boolean) queuePermissions.get(CONSUME_TEMPORARY_KEY); - Boolean ownQueuesOnly = (Boolean) queuePermissions.get(CONSUME_OWN_QUEUES_ONLY_KEY); + if (queuePermissions == null) + { + //we have a problem - we've never granted this type of permission ..... + return AuthzResult.DENIED; + } - // If user is allowed to publish to temporary queues and this is a temp queue then allow it. - if (temporayQueues) - { - if (queue.isAutoDelete()) - // This will allow consumption from any temporary queue including ones not owned by this user. - // Of course the exclusivity will not be broken. - { + List queues = (List) queuePermissions.get(CONSUME_QUEUES_KEY); - // if not limited to ownQueuesOnly then ok else check queue Owner. - return (!ownQueuesOnly || new AMQShortString(queue.getPrincipalHolder().getPrincipal().getName()).equals(_user)) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - else - { - return AuthzResult.DENIED; - } - } + Boolean temporaryQueues = (Boolean) queuePermissions.get(CONSUME_TEMPORARY_KEY); + Boolean ownQueuesOnly = (Boolean) queuePermissions.get(CONSUME_OWN_QUEUES_ONLY_KEY); - // if queues are white listed then ensure it is ok - if (queues != null) - { - // if no queues are listed then ALL are ok othereise it must be specified. - if (ownQueuesOnly) - { - if ( new AMQShortString(queue.getPrincipalHolder().getPrincipal().getName()).equals(_user)) - { - return (queues.size() == 0 || queues.contains(queue.getName())) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - else - { - return AuthzResult.DENIED; - } - } - // If we are - return (queues.size() == 0 || queues.contains(queue.getName())) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - } + // If user is allowed to consume from temporary queues and this is a temp queue then allow it. + if (temporaryQueues && queue.isAutoDelete()) + { + // This will allow consumption from any temporary queue including ones not owned by this user. + // Of course the exclusivity will not be broken. + { - // Can't authenticate without the right parameters - return AuthzResult.DENIED; + // if not limited to ownQueuesOnly then ok else check queue Owner. + return (!ownQueuesOnly || new AMQShortString(queue.getPrincipalHolder().getPrincipal().getName()).equals(_user)) ? AuthzResult.ALLOWED : AuthzResult.DENIED; + } + } + //if this is a temporary queue and the user does not have permissions for temporary queues then deny + else if (!temporaryQueues && queue.isAutoDelete()) + { + return AuthzResult.DENIED; + } + + // if queues are white listed then ensure it is ok + if (queues != null) + { + // if no queues are listed then ALL are ok othereise it must be specified. + if (ownQueuesOnly) + { + if ( new AMQShortString(queue.getPrincipalHolder().getPrincipal().getName()).equals(_user)) + { + return (queues.size() == 0 || queues.contains(queue.getName())) ? AuthzResult.ALLOWED : AuthzResult.DENIED; + } + else + { + return AuthzResult.DENIED; + } + } + + // If we are + return (queues.size() == 0 || queues.contains(queue.getName())) ? AuthzResult.ALLOWED : AuthzResult.DENIED; + } + } + + // Can't authenticate without the right parameters + return AuthzResult.DENIED; } private AuthzResult authorisePublish(Permission permission, Object... parameters) @@ -663,31 +666,7 @@ public class PrincipalPermissions } else { - //There a is no white list for queues - - // So can allow all queues to be bound - // but we should first check and see if we have a temp queue and validate that we are allowed - // to bind temp queues. - - //Check to see if we have a temporary queue - if (bind_queueName.isAutoDelete()) - { - // Check and see if we have an exchange white list. - Map bind_exchanges = (Map) bind_create_queues.get(CREATE_QUEUE_EXCHANGES_KEY); - - // If the exchange exists then we must check to see if temporary queues are allowed here - if (bind_exchanges != null) - { - // Check to see if the requested exchange is allowed. - Map exchangeDetails = (Map) bind_exchanges.get(exchange.getName()); - - return ((Boolean) exchangeDetails.get(CREATE_QUEUE_EXCHANGES_TEMPORARY_KEY)) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - - //no white list so all allowed, drop through to return true below. - } - - // not a temporary queue and no white list so all allowed. + //no white list so all allowed. return AuthzResult.ALLOWED; } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java index b6d2c3ab67..69abac7bd6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java @@ -51,6 +51,7 @@ import java.io.FileOutputStream; import java.util.Properties; import java.util.List; import java.util.Enumeration; +import java.util.Random; import java.util.Set; import java.util.concurrent.locks.ReentrantLock; import java.security.Principal; @@ -439,7 +440,14 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana _accessRightsUpdate.lock(); // Create temporary file - File tmp = File.createTempFile(_accessFile.getName(), ".tmp"); + Random r = new Random(); + File tmp; + do + { + tmp = new File(_accessFile.getPath() + r.nextInt() + ".tmp"); + } + while(tmp.exists()); + tmp.deleteOnExit(); FileOutputStream output = new FileOutputStream(tmp); @@ -453,30 +461,26 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana old.delete(); } - try + if(!_accessFile.renameTo(old)) { - if(!_accessFile.renameTo(old)) - { - FileUtils.copyCheckedEx(_accessFile, old); - } + //unable to rename the existing file to the backup name + _logger.error("Could not backup the existing management rights file"); + throw new IOException("Could not backup the existing management rights file"); } - catch (IOException e) - { - _logger.warn("Could not backup the existing management rights file: " +e); - throw new IOException("Could not backup the existing management rights file: " +e); - } - - try + + if(!tmp.renameTo(_accessFile)) { - if(!tmp.renameTo(_accessFile)) + //failed to rename the new file to the required filename + + if(!old.renameTo(_accessFile)) { - FileUtils.copyCheckedEx(tmp, _accessFile); + //unable to return the backup to required filename + _logger.error("Could not rename the new management rights file into place, and unable to restore original file"); + throw new IOException("Could not rename the new management rights file into place, and unable to restore original file"); } - } - catch (IOException e) - { - _logger.warn("Could not copy the new management rights file into place: " +e); - throw new IOException("Could not copy the new management rights file into place" +e); + + _logger.error("Could not rename the new management rights file into place"); + throw new IOException("Could not rename the new management rights file into place"); } } finally diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java index 532ff0b7d6..a5bdf662af 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java @@ -179,8 +179,26 @@ public class SimpleXML implements ACLPlugin private void processConsume(Configuration config) { + boolean temporary = false; + Configuration tempConfig = null; Configuration consumeConfig = config.subset("access_control_list.consume"); + tempConfig = consumeConfig.subset("queues.temporary(0)"); + if (tempConfig != null) + { + temporary = true; + } + + //Permission all users who have rights to temp queues and topics + if (tempConfig != null && !tempConfig.isEmpty()) + { + String[] tempUsers = tempConfig.getStringArray("users.user"); + for (String user : tempUsers) + { + grant(Permission.CONSUME, user, temporary); + } + } + // Process queue limited users int queueCount = 0; Configuration queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")"); @@ -190,14 +208,14 @@ public class SimpleXML implements ACLPlugin // Get queue Name AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); // if there is no name then there may be a temporary element - boolean temporary = queueConfig.containsKey("temporary"); + boolean ownQueues = queueConfig.containsKey("own_queues"); // Process permissions for this queue String[] users = queueConfig.getStringArray("users.user"); for (String user : users) { - grant(Permission.CONSUME, user, queueName, temporary, ownQueues); + grant(Permission.CONSUME, user, queueName, ownQueues); } // See if we have another config @@ -210,14 +228,33 @@ public class SimpleXML implements ACLPlugin for (String user : users) { + //NOTE: this call does not appear to do anything inside the grant section for consume grant(Permission.CONSUME, user); } } private void processCreate(Configuration config) { + boolean temporary = false; + Configuration tempConfig = null; + Configuration createConfig = config.subset("access_control_list.create"); + tempConfig = createConfig.subset("queues.temporary(0)"); + if (tempConfig != null) + { + temporary = true; + } + + //Permission all users who have rights to temp queues and topics + if (tempConfig != null && !tempConfig.isEmpty()) + { + String[] tempUsers = tempConfig.getStringArray("users.user"); + for (String user : tempUsers) + { + grant(Permission.CREATEQUEUE, user, temporary); + } + } // Process create permissions for queue creation int queueCount = 0; Configuration queueConfig = createConfig.subset("queues.queue(" + queueCount + ")"); @@ -227,9 +264,6 @@ public class SimpleXML implements ACLPlugin // Get queue Name AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); - // if there is no name then there may be a temporary element - boolean temporary = queueConfig.containsKey("temporary"); - int exchangeCount = 0; Configuration exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); @@ -238,12 +272,15 @@ public class SimpleXML implements ACLPlugin AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name")); AMQShortString routingKey = new AMQShortString(exchangeConfig.getString("routing_key")); - + // Process permissions for this queue String[] users = exchangeConfig.getStringArray("users.user"); for (String user : users) { + //This is broken as the user name is not stored grant(Permission.CREATEEXCHANGE, user, exchange); + + //This call could be cleaned up as temporary is now being set earlier (above) grant(Permission.CREATEQUEUE, user, temporary, (queueName.equals("") ? null : queueName), (exchange .equals("") ? null : exchange), (routingKey.equals("") ? null : routingKey)); } @@ -279,6 +316,7 @@ public class SimpleXML implements ACLPlugin String[] users = exchangeConfig.getStringArray("users.user"); for (String user : users) { + //And this is broken too grant(Permission.CREATEEXCHANGE, user, exchange, clazz); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java index cd4eb0bec7..581eeabbc3 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java @@ -40,6 +40,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Pattern; @@ -428,7 +429,15 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase BufferedReader reader = null; PrintStream writer = null; - File tmp = File.createTempFile(_passwordFile.getName(), ".tmp"); + + Random r = new Random(); + File tmp; + do + { + tmp = new File(_passwordFile.getPath() + r.nextInt() + ".tmp"); + } + while(tmp.exists()); + tmp.deleteOnExit(); try @@ -528,30 +537,26 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase old.delete(); } - try - { - if(!_passwordFile.renameTo(old)) - { - FileUtils.copyCheckedEx(_passwordFile, old); - } - } - catch (IOException e) + if(!_passwordFile.renameTo(old)) { - _logger.error("Could not backup the existing password file: " +e); - throw new IOException("Could not backup the existing password file: " + e); + //unable to rename the existing file to the backup name + _logger.error("Could not backup the existing password file"); + throw new IOException("Could not backup the existing password file"); } - - try + + if(!tmp.renameTo(_passwordFile)) { - if(!tmp.renameTo(_passwordFile)) + //failed to rename the new file to the required filename + + if(!old.renameTo(_passwordFile)) { - FileUtils.copyCheckedEx(tmp, _passwordFile); + //unable to return the backup to required filename + _logger.error("Could not rename the new password file into place, and unable to restore original file"); + throw new IOException("Could not rename the new password file into place, and unable to restore original file"); } - } - catch (IOException e) - { - _logger.error("Could not copy the new password file into place: " +e); - throw new IOException("Could not copy the new password file into place: " + e); + + _logger.error("Could not rename the new password file into place"); + throw new IOException("Could not rename the new password file into place"); } } finally diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java index 6ec7cea4c0..8665e579ba 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java @@ -26,7 +26,6 @@ import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainInitialiser; import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser; import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser; -import org.apache.qpid.util.FileUtils; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; @@ -41,6 +40,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.concurrent.locks.ReentrantLock; import java.util.regex.Pattern; @@ -395,7 +395,15 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase BufferedReader reader = null; PrintStream writer = null; - File tmp = File.createTempFile(_passwordFile.getName(), ".tmp"); + + Random r = new Random(); + File tmp; + do + { + tmp = new File(_passwordFile.getPath() + r.nextInt() + ".tmp"); + } + while(tmp.exists()); + tmp.deleteOnExit(); try @@ -479,30 +487,26 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase old.delete(); } - try - { - if(!_passwordFile.renameTo(old)) - { - FileUtils.copyCheckedEx(_passwordFile, old); - } - } - catch (IOException e) + if(!_passwordFile.renameTo(old)) { - _logger.error("Could not backup the existing password file: " +e); - throw new IOException("Could not backup the existing password file: " + e); + //unable to rename the existing file to the backup name + _logger.error("Could not backup the existing password file"); + throw new IOException("Could not backup the existing password file"); } - - try + + if(!tmp.renameTo(_passwordFile)) { - if(!tmp.renameTo(_passwordFile)) + //failed to rename the new file to the required filename + + if(!old.renameTo(_passwordFile)) { - FileUtils.copyCheckedEx(tmp, _passwordFile); + //unable to return the backup to required filename + _logger.error("Could not rename the new password file into place, and unable to restore original file"); + throw new IOException("Could not rename the new password file into place, and unable to restore original file"); } - } - catch (IOException e) - { - _logger.error("Could not copy the new password file into place: " +e); - throw new IOException("Could not copy the new password file into place: " + e); + + _logger.error("Could not rename the new password file into place"); + throw new IOException("Could not rename the new password file into place"); } } diff --git a/qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java b/qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java index 9f350033d6..445c7d57f2 100644 --- a/qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/log4j/xml/QpidLog4JConfiguratorTest.java @@ -41,7 +41,7 @@ public class QpidLog4JConfiguratorTest extends TestCase File tmpFile = null; try { - tmpFile = File.createTempFile("LogManMBeanTestLog4jConfig", ".tmp"); + tmpFile = File.createTempFile("QpidLog4JConfiguratorTestLog4jConfig", ".tmp"); tmpFile.deleteOnExit(); FileWriter fstream = new FileWriter(tmpFile); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java index b5f499dee6..5bd739c0af 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java @@ -234,7 +234,8 @@ public class ServerConfigurationTest extends TestCase { // Check default ServerConfiguration serverConfig = new ServerConfiguration(_config); - assertEquals(true, serverConfig.getStatusUpdatesEnabled()); + assertEquals(ServerConfiguration.DEFAULT_STATUS_UPDATES.equalsIgnoreCase("on"), + serverConfig.getStatusUpdatesEnabled()); // Check disabling we set _config.setProperty(ServerConfiguration.STATUS_UPDATES, "off"); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java index b9779eff2e..46dc677921 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPChannelActorTest.java @@ -66,6 +66,8 @@ public class AMQPChannelActorTest extends TestCase Configuration config = new PropertiesConfiguration(); ServerConfiguration serverConfig = new ServerConfiguration(config); + serverConfig.getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on"); + setUpWithConfig(serverConfig); } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java index be72c31452..98c14efe4d 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/AMQPConnectionActorTest.java @@ -63,6 +63,8 @@ public class AMQPConnectionActorTest extends TestCase Configuration config = new PropertiesConfiguration(); ServerConfiguration serverConfig = new ServerConfiguration(config); + serverConfig.getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on"); + setUpWithConfig(serverConfig); } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java index 340c0ae837..9fc1d2a18f 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/ManagementActorTest.java @@ -57,6 +57,8 @@ public class ManagementActorTest extends TestCase Configuration config = new PropertiesConfiguration(); ServerConfiguration serverConfig = new ServerConfiguration(config); + serverConfig.getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on"); + _rawLogger = new UnitTestMessageLogger(); RootMessageLogger rootLogger = new RootMessageLoggerImpl(serverConfig, _rawLogger); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java index 5d2fe26707..727b83c60b 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/QueueActorTest.java @@ -46,6 +46,8 @@ public class QueueActorTest extends TestCase Configuration config = new PropertiesConfiguration(); ServerConfiguration serverConfig = new ServerConfiguration(config); + serverConfig.getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on"); + _rawLogger = new UnitTestMessageLogger(); RootMessageLogger rootLogger = new RootMessageLoggerImpl(serverConfig, _rawLogger); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java index 4e357ec52e..6b09087eef 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/actors/SubscriptionActorTest.java @@ -59,6 +59,8 @@ public class SubscriptionActorTest extends TestCase Configuration config = new PropertiesConfiguration(); ServerConfiguration serverConfig = new ServerConfiguration(config); + serverConfig.getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on"); + _rawLogger = new UnitTestMessageLogger(); RootMessageLogger rootLogger = new RootMessageLoggerImpl(serverConfig, _rawLogger); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java index da60db2772..eff6a6f59f 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/management/LoggingManagementMBeanTest.java @@ -59,6 +59,17 @@ public class LoggingManagementMBeanTest extends TestCase { _testConfigFile = createTempTestLog4JConfig(); } + + protected void tearDown() throws Exception + { + File oldTestConfigFile = new File(_testConfigFile.getAbsolutePath() + ".old"); + if(oldTestConfigFile.exists()) + { + oldTestConfigFile.delete(); + } + + _testConfigFile.delete(); + } private File createTempTestLog4JConfig() { diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java index 2656a8b5cb..b9b222755d 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/messages/AbstractTestMessages.java @@ -53,6 +53,8 @@ public abstract class AbstractTestMessages extends TestCase ServerConfiguration serverConfig = new ServerConfiguration(_config); + serverConfig.getConfig().setProperty(ServerConfiguration.STATUS_UPDATES, "on"); + _logger = new UnitTestMessageLogger(); RootMessageLogger rootLogger = new RootMessageLoggerImpl(serverConfig, _logger); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java index 74b448b229..68f3fed1f9 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/logging/subjects/AbstractTestLogSubject.java @@ -53,6 +53,8 @@ public abstract class AbstractTestLogSubject extends TestCase { super.setUp(); + _config.setProperty(ServerConfiguration.STATUS_UPDATES, "ON"); + VirtualHost virtualHost = ApplicationRegistry.getInstance(). getVirtualHostRegistry().getVirtualHosts().iterator().next(); @@ -276,7 +278,7 @@ public abstract class AbstractTestLogSubject extends TestCase */ public void testDisabled() throws ConfigurationException { - _config.addProperty("status-updates", "OFF"); + _config.setProperty(ServerConfiguration.STATUS_UPDATES, "OFF"); List<Object> logs = performLog(); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java index e21edd1193..73e9dac775 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java @@ -45,6 +45,7 @@ public class PrincipalPermissionsTest extends TestCase // Common things that are passed to frame constructors private AMQShortString _queueName = new AMQShortString(this.getClass().getName()+"queue"); + private AMQShortString _tempQueueName = new AMQShortString(this.getClass().getName()+"tempqueue"); private AMQShortString _exchangeName = new AMQShortString("amq.direct"); private AMQShortString _routingKey = new AMQShortString(this.getClass().getName()+"route"); private int _ticket = 1; @@ -60,7 +61,9 @@ public class PrincipalPermissionsTest extends TestCase private VirtualHost _virtualHost; private AMQShortString _owner = new AMQShortString(this.getClass().getName()+"owner"); private AMQQueue _queue; + private AMQQueue _temporaryQueue; private Boolean _temporary = false; + private Boolean _ownQueue = false; @Override public void setUp() @@ -75,6 +78,7 @@ public class PrincipalPermissionsTest extends TestCase _virtualHost = new VirtualHostImpl(new VirtualHostConfiguration("test", env)); _exchange = DirectExchange.TYPE.newInstance(_virtualHost, _exchangeName, _durable, _ticket, _autoDelete); _queue = AMQQueueFactory.createAMQQueueImpl(_queueName, false, _owner , false, _virtualHost, _arguments); + _temporaryQueue = AMQQueueFactory.createAMQQueueImpl(_tempQueueName, false, _owner , true, _virtualHost, _arguments); } catch (Exception e) { @@ -102,7 +106,7 @@ public class PrincipalPermissionsTest extends TestCase { QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments); Object[] args = new Object[]{bind, _exchange, _queue, _routingKey}; - + assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.BIND, args)); _perms.grant(Permission.BIND, (Object[]) null); assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.BIND, args)); @@ -112,7 +116,7 @@ public class PrincipalPermissionsTest extends TestCase { Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, _routingKey}; Object[] authArgs = new Object[]{_autoDelete, _queueName}; - + assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); _perms.grant(Permission.CREATEQUEUE, grantArgs); assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); @@ -145,7 +149,7 @@ public class PrincipalPermissionsTest extends TestCase public void testConsume() { Object[] authArgs = new Object[]{_queue}; - Object[] grantArgs = new Object[]{_queueName, _temporary, _temporary}; + Object[] grantArgs = new Object[]{_queueName, _ownQueue}; /* FIXME: This throws a null pointer exception QPID-1599 * assertFalse(_perms.authorise(Permission.CONSUME, authArgs)); @@ -153,12 +157,12 @@ public class PrincipalPermissionsTest extends TestCase _perms.grant(Permission.CONSUME, grantArgs); assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authArgs)); } - + public void testPublish() { Object[] authArgs = new Object[]{_exchange, _routingKey}; Object[] grantArgs = new Object[]{_exchange.getName(), _routingKey}; - + assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.PUBLISH, authArgs)); _perms.grant(Permission.PUBLISH, grantArgs); assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgs)); @@ -197,4 +201,58 @@ public class PrincipalPermissionsTest extends TestCase assertEquals("Queue creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue)); assertEquals("Binding creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.BIND, authArgsBind)); } + + /** + * If the consume permission for temporary queues is for an unnamed queue then is should + * be global for any temporary queue but not for any non-temporary queue + */ + public void testTemporaryUnnamedQueueConsume() + { + Object[] authNonTempQArgs = new Object[]{_queue}; + Object[] authTempQArgs = new Object[]{_temporaryQueue}; + Object[] grantArgs = new Object[]{true}; + + _perms.grant(Permission.CONSUME, grantArgs); + + //Next line shows up bug - non temp queue should be denied + assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); + assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); + } + + /** + * Test that temporary queue permissions before queue perms in the ACL config work correctly + */ + public void testTemporaryQueueFirstConsume() + { + Object[] authNonTempQArgs = new Object[]{_queue}; + Object[] authTempQArgs = new Object[]{_temporaryQueue}; + Object[] grantArgs = new Object[]{true}; + Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue}; + + //should not matter if the temporary permission is processed first or last + _perms.grant(Permission.CONSUME, grantNonTempQArgs); + _perms.grant(Permission.CONSUME, grantArgs); + + assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); + assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); + } + + /** + * Test that temporary queue permissions after queue perms in the ACL config work correctly + */ + public void testTemporaryQueueLastConsume() + { + Object[] authNonTempQArgs = new Object[]{_queue}; + Object[] authTempQArgs = new Object[]{_temporaryQueue}; + Object[] grantArgs = new Object[]{true}; + Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue}; + + //should not matter if the temporary permission is processed first or last + _perms.grant(Permission.CONSUME, grantArgs); + _perms.grant(Permission.CONSUME, grantNonTempQArgs); + + assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); + assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); + } + } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java index 958ee35476..dab98095c9 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBeanTest.java @@ -65,8 +65,13 @@ public class AMQUserManagementMBeanTest extends TestCase @Override protected void tearDown() throws Exception { - _passwordFile.delete(); - _accessFile.delete(); + //clean up test password/access files + File _oldPasswordFile = new File(_passwordFile.getAbsolutePath() + ".old"); + File _oldAccessFile = new File(_accessFile.getAbsolutePath() + ".old"); + _oldPasswordFile.delete(); + _oldAccessFile.delete(); + _passwordFile.delete(); + _accessFile.delete(); } public void testDeleteUser() diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java index 413b974986..2ab15d4872 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabaseTest.java @@ -37,6 +37,7 @@ import java.io.FileWriter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.Principal; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; @@ -54,6 +55,7 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase private static final Principal PRINCIPAL = new UsernamePrincipal(PRINCIPAL_USERNAME); private Base64MD5PasswordFilePrincipalDatabase _database; private File _pwdFile; + private List<File> _testPwdFiles = new ArrayList<File>(); static { @@ -84,6 +86,31 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase _pwdFile = File.createTempFile(this.getClass().getName(), "pwd"); _pwdFile.deleteOnExit(); _database.setPasswordFile(_pwdFile.getAbsolutePath()); + _testPwdFiles.clear(); + } + + public void tearDown() throws Exception + { + //clean up the created default password file and any backup + File oldPwdFile = new File(_pwdFile.getAbsolutePath() + ".old"); + if(oldPwdFile.exists()) + { + oldPwdFile.delete(); + } + + _pwdFile.delete(); + + //clean up any additional files and their backups + for(File f : _testPwdFiles) + { + oldPwdFile = new File(f.getAbsolutePath() + ".old"); + if(oldPwdFile.exists()) + { + oldPwdFile.delete(); + } + + f.delete(); + } } private File createPasswordFile(int commentLines, int users) @@ -109,6 +136,8 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase writer.flush(); writer.close(); + + _testPwdFiles.add(testFile); return testFile; @@ -178,8 +207,6 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase assertNotNull("Created User was not saved", _database.getUser(USERNAME)); assertFalse("Duplicate user created.", _database.createPrincipal(principal, PASSWORD.toCharArray())); - - testFile.delete(); } public void testCreatePrincipalIsSavedToFile() @@ -229,7 +256,6 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase { fail("Unable to valdate file contents due to:" + e.getMessage()); } - testFile.delete(); } @@ -274,8 +300,6 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase } assertNull("Deleted user still present.", _database.getUser(USERNAME + "0")); - - testFile.delete(); } public void testGetUsers() @@ -313,8 +337,6 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase { assertTrue("User " + i + " missing", verify[i]); } - - testFile.delete(); } public void testUpdatePasswordIsSavedToFile() @@ -365,7 +387,6 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase { fail("Unable to valdate file contents due to:" + e.getMessage()); } - testFile.delete(); } public void testSetPasswordFileWithMissingFile() @@ -404,8 +425,6 @@ public class Base64MD5PasswordFilePrincipalDatabaseTest extends TestCase { fail("Password File was not created." + e.getMessage()); } - - testFile.delete(); } public void testCreateUserPrincipal() throws IOException diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java index 20b8d0a7b4..a3dad19bb4 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabaseTest.java @@ -34,6 +34,7 @@ import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.security.Principal; +import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; @@ -47,12 +48,29 @@ public class PlainPasswordFilePrincipalDatabaseTest extends TestCase private Principal _principal = new UsernamePrincipal(TEST_USERNAME); private PlainPasswordFilePrincipalDatabase _database; + private List<File> _testPwdFiles = new ArrayList<File>(); public void setUp() throws Exception { _database = new PlainPasswordFilePrincipalDatabase(); + _testPwdFiles.clear(); } + public void tearDown() throws Exception + { + //clean up any additional files and their backups + for(File f : _testPwdFiles) + { + File oldPwdFile = new File(f.getAbsolutePath() + ".old"); + if(oldPwdFile.exists()) + { + oldPwdFile.delete(); + } + + f.delete(); + } + } + // ******* Test Methods ********** // public void testCreatePrincipal() @@ -368,6 +386,8 @@ public class PlainPasswordFilePrincipalDatabaseTest extends TestCase writer.flush(); writer.close(); + + _testPwdFiles.add(testFile); return testFile; diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java index 1240284a56..04339b2498 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java @@ -19,7 +19,7 @@ package org.apache.qpid.example.publisher; -import org.apache.qpid.example.shared.FileUtils; +import org.apache.qpid.util.FileUtils; import org.apache.qpid.example.shared.Statics; import java.io.*; @@ -42,10 +42,10 @@ public class FileMessageFactory try { _filename = filename; - _payload = FileUtils.getFileContent(filename); + _payload = FileUtils.readFileAsString(filename); _session = session; } - catch (IOException e) + catch (Exception e) { MessageFactoryException mfe = new MessageFactoryException(e.toString(), e); throw mfe; diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/MultiMessageDispatcher.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/MultiMessageDispatcher.java new file mode 100644 index 0000000000..a92efe99ac --- /dev/null +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/MultiMessageDispatcher.java @@ -0,0 +1,141 @@ +/* + * + * 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.example.publisher; + +import java.io.File; + +import javax.jms.JMSException; +import javax.jms.TextMessage; + + +import org.apache.qpid.example.shared.FileUtils; +import org.apache.qpid.example.shared.Statics; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; + +/** + * Class that sends parameterised number of message files to the Publisher + * Must set properties for host in properties file or uses in vm broker + */ +public class MultiMessageDispatcher +{ + + protected static final Logger _logger = LoggerFactory.getLogger(FileMessageDispatcher.class); + + protected static Publisher _publisher = null; + + /** + * To use this main method you need to specify a path or file to use for input + * This class then uses file contents from the dir/file specified to generate + * messages to publish + * Intended to be a very simple way to get going with publishing using the broker + * @param args - must specify one value, the path to file(s) for publisher + */ + public static void main(String[] args) + { + + // Check command line args ok - must provide a path or file for us to dispatch + if (args.length < 2) + { + System.out.println("Usage: MultiMessageDispatcher <numberOfMessagesToSend> <topic(true|false)>" + ""); + } + else + { + boolean topicPublisher = true; + + try + { + // publish message(s) + topicPublisher = new Boolean(args[1]).booleanValue(); + publish(new Integer(args[0]).intValue(),topicPublisher); + + // Move payload file(s) to archive location as no error + FileUtils.moveFileToNewDir(args[0], System.getProperties().getProperty(Statics.ARCHIVE_PATH)); + } + catch (Exception e) + { + // log error and exit + _logger.error("Error trying to dispatch message: " + e); + System.exit(1); + } + finally + { + + cleanup(topicPublisher); + } + } + + if (_logger.isDebugEnabled()) + { + _logger.debug("Finished dispatching message"); + } + + System.exit(0); + } + + /** + * Publish the content of a file or files from a directory as messages + * @param numMessages - from main args + * @throws javax.jms.JMSException + * @throws org.apache.qpid.example.publisher.MessageFactoryException - if cannot create message from file content + */ + public static void publish(int numMessages, boolean topicPublisher) throws JMSException, MessageFactoryException + { + { + // Send the message generated from the payload using the _publisher + getPublisher(topicPublisher).sendMessage(numMessages); + } + } + + /** + * Cleanup before exit + */ + public static void cleanup(boolean topicPublisher) + { + if (getPublisher(topicPublisher) != null) + { + getPublisher(topicPublisher).cleanup(); + } + } + + /** + * @return A Publisher instance + */ + private static Publisher getPublisher(boolean topic) + { + if (_publisher != null) + { + return _publisher; + } + + if (!topic) + { + // Create a _publisher + _publisher = new Publisher(); + } + else + { + _publisher = new TopicPublisher(); + } + return _publisher; + } + +}
\ No newline at end of file diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/Publisher.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/Publisher.java index 87fc543dbe..b5f44557a4 100644 --- a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/Publisher.java +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/Publisher.java @@ -20,13 +20,7 @@ package org.apache.qpid.example.publisher; import org.apache.qpid.client.AMQConnectionFactory; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.DeliveryMode; -import javax.jms.Queue; -import javax.jms.MessageProducer; -import javax.jms.Connection; -import javax.jms.Session; +import javax.jms.*; import javax.naming.InitialContext; @@ -50,7 +44,7 @@ public class Publisher protected String _name = "Publisher"; - protected Queue _destination; + protected Destination _destination; protected static final String _defaultDestinationDir = "/tmp"; @@ -70,6 +64,17 @@ public class Publisher AMQConnectionFactory cf = (AMQConnectionFactory) ctx.lookup("local"); _connection = cf.createConnection(); + _connection.setExceptionListener(new ExceptionListener() + { + public void onException(JMSException jmse) + { + // The connection may have broken invoke reconnect code if available. + // The connection may have broken invoke reconnect code if available. + System.err.println("ExceptionListener caught: " + jmse); + //System.exit(0); + } + }); + //create a transactional session _session = _connection.createSession(true, Session.AUTO_ACKNOWLEDGE); @@ -93,6 +98,28 @@ public class Publisher } /** + * Creates and sends the number of messages specified in the param + */ + public void sendMessage(int numMessages) + { + try + { + TextMessage txtMessage = _session.createTextMessage("msg"); + for (int i=0;i<numMessages;i++) + { + sendMessage(txtMessage); + _log.info("Sent: " + i); + } + } + catch (JMSException j) + { + _log.error("Exception in sendMessage" + j); + } + + + } + + /** * Publishes a non-persistent message using transacted session * Note that persistent is the default mode for send - so need to specify for transient */ @@ -101,7 +128,7 @@ public class Publisher try { //Send message via our producer which is not persistent - _producer.send(message, DeliveryMode.NON_PERSISTENT, _producer.getPriority(), _producer.getTimeToLive()); + _producer.send(message, DeliveryMode.PERSISTENT, _producer.getPriority(), _producer.getTimeToLive()); //commit the message send and close the transaction _session.commit(); @@ -124,7 +151,7 @@ public class Publisher } } - _log.info(_name + " finished sending message: " + message); + //_log.info(_name + " finished sending message: " + message); return true; } diff --git a/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/TopicPublisher.java b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/TopicPublisher.java new file mode 100644 index 0000000000..8645e41101 --- /dev/null +++ b/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/TopicPublisher.java @@ -0,0 +1,59 @@ +/* + * 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.example.publisher; + +import org.apache.qpid.client.BasicMessageProducer; +import org.apache.qpid.example.shared.InitialContextHelper; +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; + +import javax.jms.*; +import javax.naming.InitialContext; + +/** + * Subclass of Publisher which sends messages to a topic destination defined in example.properties + */ +public class TopicPublisher extends Publisher +{ + + private static final Logger _log = LoggerFactory.getLogger(Publisher.class); + + public TopicPublisher() + { + super(); + + try + { + _contextHelper = new InitialContextHelper(null); + InitialContext ctx = _contextHelper.getInitialContext(); + + //lookup the example topic and use it + _destination = (Topic) ctx.lookup("MyTopic"); + + //create a message producer + _producer = _session.createProducer(_destination); + } + catch (Exception e) + { + //argh + _log.error("Exception trying to construct TopicPublisher" + e); + } + + } +}
\ No newline at end of file diff --git a/qpid/java/client/src/main/java/log4j.xml b/qpid/java/client/src/main/java/log4j.xml deleted file mode 100644 index c27acba818..0000000000 --- a/qpid/java/client/src/main/java/log4j.xml +++ /dev/null @@ -1,36 +0,0 @@ -<!-- - - - - - 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. - - ---> - -<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> - <appender name="console" class="org.apache.log4j.ConsoleAppender"> - <param name="Target" value="System.out"/> - <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/> - </layout> - </appender> - - <logger name="org.apache.qpid"> - <level value="warn"/> - <appender-ref ref="console" /> - </logger> - -</log4j:configuration> diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java b/qpid/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java index 39176cd8dd..8b702c008f 100644 --- a/qpid/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java +++ b/qpid/java/client/src/main/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactory.java @@ -108,7 +108,8 @@ public class PropertiesFileInitialContextFactory implements InitialContextFactor } catch (IOException ioe) { - _logger.warn("Unable to load property file specified in Provider_URL:" + environment.get(Context.PROVIDER_URL)); + _logger.warn("Unable to load property file specified in Provider_URL:" + environment.get(Context.PROVIDER_URL) +"\n" + + "Due to:"+ioe.getMessage()); } createConnectionFactories(data, environment); diff --git a/qpid/java/systests/etc/config-systests-acl-settings.xml b/qpid/java/systests/etc/config-systests-acl-settings.xml index c5374a5c5e..d7c1ef70df 100644 --- a/qpid/java/systests/etc/config-systests-acl-settings.xml +++ b/qpid/java/systests/etc/config-systests-acl-settings.xml @@ -79,15 +79,11 @@ <!-- This section grants users the ability to consume from the broker --> <consume> <queues> - - <!-- Allow the clients to consume from their temporary queues--> - <queue> - <temporary/> + <temporary> <users> <user>client</user> </users> - </queue> - + </temporary> <!-- Only allow the server to consume from the Request Queue--> <queue> @@ -101,13 +97,18 @@ </queues> </consume> - <!-- This section grants clients the ability to create queues and exchanges --> + <!-- This section grants users the ability to create queues and exchanges --> <create> <queues> - <!-- Allow clients to create temporary queues--> + <temporary> + <users> + <user>client</user> + </users> + </temporary> + + <!-- Allow clients to create queue on this exchange--> <queue> - <temporary/> - <exchanges> + <exchanges> <exchange> <name>amq.direct</name> <users> @@ -133,6 +134,26 @@ </security> </test> </virtualhost> + + <virtualhost> + <name>test2</name> + <test2> + <security> + <access> + <class>org.apache.qpid.server.security.access.plugins.SimpleXML</class> + </access> + + <access_control_list> + <!-- This section grants specific users full permissions to all artifacts in this virtualhost --> + <access> + <users> + <user>guest</user> + </users> + </access> + </access_control_list> + </security> + </test2> + </virtualhost> </virtualhosts> </broker> diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java index 04d1ec1e72..dde235f73e 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java @@ -22,33 +22,37 @@ package org.apache.qpid.server.security.acl; import org.apache.commons.configuration.ConfigurationException; -import org.apache.qpid.AMQConnectionFailureException; -import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.AMQException; -import org.apache.qpid.test.utils.QpidTestCase; +import org.apache.qpid.AMQConnectionFailureException; +import org.apache.qpid.client.AMQAuthenticationException; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQConnectionURL; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.jms.ConnectionListener; +import org.apache.qpid.jms.ConnectionURL; +import org.apache.qpid.test.utils.QpidTestCase; import org.apache.qpid.url.URLSyntaxException; -import org.apache.qpid.client.*; -import org.apache.qpid.framing.AMQShortString; -import javax.jms.*; +import javax.jms.Connection; +import javax.jms.DeliveryMode; import javax.jms.ExceptionListener; import javax.jms.IllegalStateException; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; import javax.naming.NamingException; - import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; - -public class SimpleACLTest extends QpidTestCase implements ConnectionListener, ExceptionListener +public class SimpleACLTest extends QpidTestCase implements ConnectionListener { - private String BROKER = "vm://:"+ApplicationRegistry.DEFAULT_INSTANCE;//"tcp://localhost:5672"; - private ArrayList<Exception> _thrownExceptions = new ArrayList<Exception>(); - private CountDownLatch _awaitError = new CountDownLatch(51); - public void setUp() throws Exception { //Performing setUp here would result in a broker with the default ACL test config @@ -117,17 +121,19 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E public void testAccessVhostAuthorisedGuest() throws IOException, Exception { - //The 'guest' user normally has no access, as tested below in testAccessNoRights(), and so is unable to perform - //actions such as connecting (and by extension, creating a queue, and consuming from a queue etc). In order to test - //the vhost-wide 'access' right, we will now give the guest user 'access' ACL rights and perform various such actions. - setConfigurationProperty("virtualhosts.virtualhost.test.security.access_control_list.access.users.user", "guest"); + //The 'guest' user has no access to the 'test' vhost, as tested below in testAccessNoRights(), and so + //is unable to perform actions such as connecting (and by extension, creating a queue, and consuming + //from a queue etc). In order to test the vhost-wide 'access' ACL right, the 'guest' user has been given + //this right in the 'test2' vhost. setUpACLTest(); try { - //get a connection - Connection conn = getConnection("guest", "guest"); + //get a connection to the 'test2' vhost using the guest user and perform various actions. + Connection conn = getConnection(new AMQConnectionURL( + "amqp://username:password@clientid/test2?brokerlist='" + getBroker() + "'")); + ((AMQConnection) conn).setConnectionListener(this); Session sesh = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); @@ -187,54 +193,6 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E } } - public void testGuestConsumeWithCreateRightsAndWithoutConsumeRights() throws NamingException, ConfigurationException, IOException, Exception - { - //Customise the ACL config to give the guest user some create (could be any, non-consume) rights to - //force creation of a PrincipalPermissions instance to perform the consume rights check against. - setConfigurationProperty("virtualhosts.virtualhost.test.security.access_control_list.create.queues.queue.users.user", "guest"); - - setUpACLTest(); - - //QPID-2081: use a latch to sync on exception causing connection close, to work - //around the connection close race during tearDown() causing sporadic failures - final CountDownLatch exceptionReceived = new CountDownLatch(1); - - try - { - Connection conn = getConnection("guest", "guest"); - - conn.setExceptionListener(new ExceptionListener() - { - public void onException(JMSException e) - { - exceptionReceived.countDown(); - } - }); - - - Session sesh = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - - conn.start(); - - sesh.createConsumer(sesh.createQueue("example.RequestQueue")); - - conn.close(); - } - catch (JMSException e) - { - Throwable cause = e.getLinkedException(); - - assertNotNull("There was no liked exception", cause); - assertEquals("Wrong linked exception type", AMQAuthenticationException.class, cause.getClass()); - assertEquals("Incorrect error code received", 403, ((AMQAuthenticationException) cause).getErrorCode().getCode()); - - //use the latch to ensure the control thread waits long enough for the exception thread - //to have done enough to mark the connection closed before teardown commences - assertTrue("Timed out waiting for conneciton to report close", - exceptionReceived.await(2, TimeUnit.SECONDS)); - } - } - public void testClientConsumeFromTempQueueValid() throws AMQException, URLSyntaxException, Exception { setUpACLTest(); @@ -455,40 +413,43 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); conn.start(); - conn.setExceptionListener(this); + MessageProducer sender = ((AMQSession) session).createProducer(null); - Queue queue = session.createQueue("NewQueueThatIDoNotHaveRightsToPublishToo"); - + Queue queue = session.createQueue("Invalid"); + // Send a message that we will wait to be sent, this should give the broker time to close the connection // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not // queue existence. ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"), DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true); - _awaitError.await(1, TimeUnit.SECONDS); + // Test the connection with a valid consumer + // This may fail as the session may be closed before the queue or the consumer created. + Queue temp = session.createTemporaryQueue(); + + session.createConsumer(temp).close(); + + //Connection should now be closed and will throw the exception caused by the above send + conn.close(); + + fail("Close is not expected to succeed."); } catch (JMSException e) { - fail("Unknown exception thrown:" + e.getMessage()); - } - boolean foundCorrectException = false; - for (Exception cause : _thrownExceptions) - { - if (cause instanceof JMSException) + Throwable cause = e.getLinkedException(); + if (!(cause instanceof AMQAuthenticationException)) { - if (((JMSException) cause).getLinkedException() instanceof AMQAuthenticationException) - { - foundCorrectException = true; - } + e.printStackTrace(); + } + assertEquals("Incorrect exception", AMQAuthenticationException.class, cause.getClass()); + assertEquals("Incorrect error code thrown", 403, ((AMQAuthenticationException) cause).getErrorCode().getCode()); //use the latch to ensure the control thread waits long enough for the exception thread //to have done enough to mark the connection closed before teardown commences assertTrue("Timed out waiting for conneciton to report close", exceptionReceived.await(2, TimeUnit.SECONDS)); - } } - assertTrue("Did not get AMQAuthenticationException thrown", foundCorrectException); } public void testServerConsumeFromNamedQueueValid() throws AMQException, URLSyntaxException, Exception @@ -683,9 +644,9 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E //around the connection close race during tearDown() causing sporadic failures final CountDownLatch exceptionReceived = new CountDownLatch(1); + Connection conn = getConnection("server", "guest"); try { - Connection conn = getConnection("server", "guest"); conn.setExceptionListener(new ExceptionListener() { @@ -702,7 +663,6 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E session.createTemporaryQueue(); fail("Test failed as creation succeded."); - //conn will be automatically closed } catch (JMSException e) { @@ -717,6 +677,17 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E assertTrue("Timed out waiting for conneciton to report close", exceptionReceived.await(2, TimeUnit.SECONDS)); } + finally + { + try + { + conn.close(); + } + catch (Exception e) + { + // This normally fails because we are denied + } + } } public void testServerCreateAutoDeleteQueueInvalid() throws NamingException, JMSException, AMQException, Exception @@ -945,10 +916,4 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E public void failoverComplete() { } - - public void onException(JMSException arg0) - { - _thrownExceptions.add(arg0); - _awaitError.countDown(); - } } diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/store/PersistentStoreTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/store/PersistentStoreTest.java index ac07372c68..65127e50ec 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/server/store/PersistentStoreTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/store/PersistentStoreTest.java @@ -21,14 +21,18 @@ package org.apache.qpid.server.store; +import org.apache.qpid.test.utils.QpidTestCase; + import javax.jms.Connection; +import javax.jms.Destination; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; - -import org.apache.qpid.test.utils.QpidTestCase; +import java.util.ArrayList; +import java.util.List; public class PersistentStoreTest extends QpidTestCase { @@ -48,14 +52,12 @@ public class PersistentStoreTest extends QpidTestCase _destination = _session.createQueue(getTestQueueName()); _consumer = _session.createConsumer(_destination); _consumer.close(); - + sendMessage(_session, _destination, NUM_MESSAGES); _session.commit(); } - - /** - * Checks that a new consumer on a new connection can get NUM_MESSAGES from _destination - */ + + /** Checks that a new consumer on a new connection can get NUM_MESSAGES from _destination */ private void checkMessages() throws Exception, JMSException { _con = getConnection(); @@ -65,11 +67,11 @@ public class PersistentStoreTest extends QpidTestCase for (int i = 0; i < NUM_MESSAGES; i++) { Message msg = _consumer.receive(RECEIVE_TIMEOUT); - assertNotNull("Message "+i+" not received", msg); + assertNotNull("Message " + i + " not received", msg); } assertNull("No more messages should be received", _consumer.receive(100)); } - + // /** // * starts the server, sends 100 messages, restarts the server and gets 100 messages back // * the test formerly referred to as BDB-Qpid-1 @@ -81,11 +83,11 @@ public class PersistentStoreTest extends QpidTestCase // checkMessages(); // } - - /** + /** * starts the server, sends 100 messages, nukes then starts the server and gets 100 messages back * the test formerly referred to as BDB-Qpid-2 - * @throws Exception + * + * @throws Exception */ public void testForcibleStartStop() throws Exception { @@ -106,11 +108,12 @@ public class PersistentStoreTest extends QpidTestCase // checkMessages(); // } - /** - * starts the server, sends 100 committed messages, 5 uncommited ones, + /** + * starts the server, sends 100 committed messages, 5 uncommited ones, * nukes and starts the server and gets 100 messages back * the test formerly referred to as BDB-Qpid-6 - * @throws Exception + * + * @throws Exception */ public void testForcibleStartStopMidTransaction() throws Exception { @@ -119,13 +122,14 @@ public class PersistentStoreTest extends QpidTestCase checkMessages(); } - /** - * starts the server, sends 100 committed messages, 5 uncommited ones, + /** + * starts the server, sends 100 committed messages, 5 uncommited ones, * restarts the client and gets 100 messages back. * the test formerly referred to as BDB-Qpid-7 - * + * * FIXME: is this a PersistentStoreTest? Seems more like a transaction test to me.. aidan - * @throws Exception + * + * @throws Exception */ public void testClientDeathMidTransaction() throws Exception { @@ -133,7 +137,7 @@ public class PersistentStoreTest extends QpidTestCase _con.close(); checkMessages(); } - + // /** // * starts the server, sends 50 committed messages, copies $QPID_WORK to a new location, // * sends 10 messages, stops the server, nukes the store, restores the copy, starts the server @@ -143,5 +147,37 @@ public class PersistentStoreTest extends QpidTestCase // { // -- removing as this will leave 100msgs on a queue // } - + + /** + * This test requires that we can send messages without commiting. + * QTC always commits the messages sent via sendMessages. + * + * @param session the session to use for sending + * @param destination where to send them to + * @param count no. of messages to send + * + * @return the sent messges + * + * @throws Exception + */ + @Override + public List<Message> sendMessage(Session session, Destination destination, + int count) throws Exception + { + List<Message> messages = new ArrayList<Message>(count); + + MessageProducer producer = session.createProducer(destination); + + for (int i = 0;i < (count); i++) + { + Message next = createNextMessage(session, i); + + producer.send(next); + + messages.add(next); + } + + return messages; + } + } diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java index 6c1b1c7b8d..b7ca40213a 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/utils/QpidTestCase.java @@ -1080,18 +1080,62 @@ public class QpidTestCase extends TestCase return count; } + /** + * Send messages to the given destination. + * + * If session is transacted then messages will be commited before returning + * + * @param session the session to use for sending + * @param destination where to send them to + * @param count no. of messages to send + * + * @return the sent messges + * + * @throws Exception + */ public List<Message> sendMessage(Session session, Destination destination, int count) throws Exception { return sendMessage(session, destination, count, 0, 0); } + /** + * Send messages to the given destination. + * + * If session is transacted then messages will be commited before returning + * + * @param session the session to use for sending + * @param destination where to send them to + * @param count no. of messages to send + * + * @param batchSize the batchSize in which to commit, 0 means no batching, + * but a single commit at the end + * @return the sent messgse + * + * @throws Exception + */ public List<Message> sendMessage(Session session, Destination destination, int count, int batchSize) throws Exception { return sendMessage(session, destination, count, 0, batchSize); } + /** + * Send messages to the given destination. + * + * If session is transacted then messages will be commited before returning + * + * @param session the session to use for sending + * @param destination where to send them to + * @param count no. of messages to send + * + * @param offset offset allows the INDEX value of the message to be adjusted. + * @param batchSize the batchSize in which to commit, 0 means no batching, + * but a single commit at the end + * @return the sent messgse + * + * @throws Exception + */ public List<Message> sendMessage(Session session, Destination destination, int count, int offset, int batchSize) throws Exception { diff --git a/qpid/java/test-profiles/010Excludes b/qpid/java/test-profiles/010Excludes index 454aede07e..7dfed6cee0 100755 --- a/qpid/java/test-profiles/010Excludes +++ b/qpid/java/test-profiles/010Excludes @@ -98,3 +98,13 @@ org.apache.qpid.server.queue.ProducerFlowControlTest#* //QPID-1950 : Commit to test this failure. This is a MINA only failure so it cannot be tested when using 010. org.apache.qpid.server.failover.MessageDisappearWithIOExceptionTest#* + +// These are recent test additions that are failing with the c++ broker +// Temporarily disabling until properly investigated. +org.apache.qpid.test.unit.publish.DirtyTrasactedPubilshTest#* +org.apache.qpid.test.unit.ack.FailoverBeforeConsumingRecoverTest#* +org.apache.qpid.test.unit.ack.AcknowledgeAfterFailoverTest#* +org.apache.qpid.test.unit.ack.AcknowledgeAfterFailoverOnMessageTest#* + +org.apache.qpid.test.client.RollbackOrderTest#testOrderingAfterRollbackOnMessage#* + |