You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2012/08/21 23:33:40 UTC

svn commit: r1375808 - in /qpid/branches/qpid-2393/qpid/cpp/src: ./ qpid/acl/ qpid/broker/ tests/

Author: chug
Date: Tue Aug 21 21:33:40 2012
New Revision: 1375808

URL: http://svn.apache.org/viewvc?rev=1375808&view=rev
Log:
QPID-2393 Count queues per user
This patch adds a new class designed for managing thing like queues, 
exchanges, or bindings. Unlike connections the objects do not exist
until after the Acl code issues approval.

The per-user queue limit is a command line option --max-queues-per-user
that is applied to all users.

The queue limit is reported by QMF as a property, violations are
emitted as events and counted as statistics.

Self test code demonstrates two users running into their limits and
later deleting and creating more queues.


Added:
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.h
Modified:
    qpid/branches/qpid-2393/qpid/cpp/src/CMakeLists.txt
    qpid/branches/qpid-2393/qpid/cpp/src/acl.mk
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.cpp
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.h
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclPlugin.cpp
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/management-schema.xml
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/AclModule.h
    qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/Broker.cpp
    qpid/branches/qpid-2393/qpid/cpp/src/tests/acl.py
    qpid/branches/qpid-2393/qpid/cpp/src/tests/run_acl_tests

Modified: qpid/branches/qpid-2393/qpid/cpp/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/CMakeLists.txt?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/CMakeLists.txt (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/CMakeLists.txt Tue Aug 21 21:33:40 2012
@@ -600,6 +600,8 @@ if (BUILD_ACL)
        qpid/acl/AclPlugin.cpp
        qpid/acl/AclReader.cpp
        qpid/acl/AclReader.h
+       qpid/acl/AclResourceCounter.cpp
+       qpid/acl/AclResourceCounter.h
        qpid/acl/AclValidator.cpp
        qpid/acl/AclValidator.h
       )

Modified: qpid/branches/qpid-2393/qpid/cpp/src/acl.mk
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/acl.mk?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/acl.mk (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/acl.mk Tue Aug 21 21:33:40 2012
@@ -31,6 +31,8 @@ acl_la_SOURCES = \
   qpid/acl/AclPlugin.cpp \
   qpid/acl/AclReader.cpp \
   qpid/acl/AclReader.h \
+  qpid/acl/AclResourceCounter.cpp \
+  qpid/acl/AclResourceCounter.h \
   qpid/acl/AclValidator.cpp \
   qpid/acl/AclValidator.h
 

Modified: qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.cpp?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.cpp (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.cpp Tue Aug 21 21:33:40 2012
@@ -18,6 +18,7 @@
 
 #include "qpid/acl/Acl.h"
 #include "qpid/acl/AclConnectionCounter.h"
+#include "qpid/acl/AclResourceCounter.h"
 #include "qpid/acl/AclData.h"
 #include "qpid/acl/AclValidator.h"
 #include "qpid/sys/Mutex.h"
@@ -32,6 +33,7 @@
 #include "qmf/org/apache/qpid/acl/Package.h"
 #include "qmf/org/apache/qpid/acl/EventAllow.h"
 #include "qmf/org/apache/qpid/acl/EventConnectionDeny.h"
+#include "qmf/org/apache/qpid/acl/EventQueueQuotaDeny.h"
 #include "qmf/org/apache/qpid/acl/EventDeny.h"
 #include "qmf/org/apache/qpid/acl/EventFileLoaded.h"
 #include "qmf/org/apache/qpid/acl/EventFileLoadFailed.h"
@@ -51,8 +53,8 @@ using qpid::management::Args;
 namespace _qmf = qmf::org::apache::qpid::acl;
 
 Acl::Acl (AclValues& av, Broker& b): aclValues(av), broker(&b), transferAcl(false), mgmtObject(0),
-    connectionCounter(new ConnectionCounter(*this, aclValues.aclMaxConnectPerUser, aclValues.aclMaxConnectPerIp, aclValues.aclMaxConnectTotal))
-{
+    connectionCounter(new ConnectionCounter(*this, aclValues.aclMaxConnectPerUser, aclValues.aclMaxConnectPerIp, aclValues.aclMaxConnectTotal)),
+    resourceCounter(new ResourceCounter(*this, aclValues.aclMaxQueuesPerUser)){
 
     agent = broker->getManagementAgent();
 
@@ -84,6 +86,15 @@ void Acl::reportConnectLimit(const std::
 }
 
 
+void Acl::reportQueueLimit(const std::string user, const std::string queueName)
+{
+    if (mgmtObject!=0)
+        mgmtObject->inc_queueQuotaDenyCount();
+
+    agent->raiseEvent(_qmf::EventQueueQuotaDeny(user, queueName));
+}
+
+
 bool Acl::authorise(
     const std::string&               id,
     const Action&                    action,
@@ -136,6 +147,18 @@ void Acl::setUserId(const qpid::broker::
 }
 
 
+bool Acl::approveCreateQueue(const std::string& userId, const std::string& queueName)
+{
+    return resourceCounter->approveCreateQueue(userId, queueName);
+}
+
+
+void Acl::recordDestroyQueue(const std::string& queueName)
+{
+    resourceCounter->recordDestroyQueue(queueName);
+}
+
+
 bool Acl::result(
     const AclResult&   aclreslt,
     const std::string& id,

Modified: qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.h
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.h?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.h (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/Acl.h Tue Aug 21 21:33:40 2012
@@ -43,12 +43,14 @@ class Connection;
 
 namespace acl {
 class ConnectionCounter;
+class ResourceCounter;
 
 struct AclValues {
     std::string aclFile;
     uint16_t    aclMaxConnectPerUser;
     uint16_t    aclMaxConnectPerIp;
     uint16_t    aclMaxConnectTotal;
+    uint16_t    aclMaxQueuesPerUser;
 };
 
 
@@ -64,6 +66,7 @@ private:
     qpid::management::ManagementAgent*   agent;
     mutable qpid::sys::Mutex             dataLock;
     boost::shared_ptr<ConnectionCounter> connectionCounter;
+    boost::shared_ptr<ResourceCounter>   resourceCounter;
 
 public:
     Acl (AclValues& av, broker::Broker& b);
@@ -72,6 +75,7 @@ public:
      * issue management counts and alerts for denied connections
      */
     void reportConnectLimit(const std::string user, const std::string addr);
+    void reportQueueLimit(const std::string user, const std::string queueName);
 
     inline virtual bool doTransferAcl() {
         return transferAcl;
@@ -92,9 +96,11 @@ public:
         const std::string&               ExchangeName,
         const std::string&               RoutingKey);
 
+    // Resource quota tracking
     virtual bool approveConnection(const broker::Connection& connection);
-
     virtual void setUserId(const broker::Connection& connection, const std::string& username);
+    virtual bool approveCreateQueue(const std::string& userId, const std::string& queueName);
+    virtual void recordDestroyQueue(const std::string& queueName);
 
     virtual ~Acl();
 private:

Modified: qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclPlugin.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclPlugin.cpp?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclPlugin.cpp (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclPlugin.cpp Tue Aug 21 21:33:40 2012
@@ -45,6 +45,7 @@ struct AclOptions : public Options {
             ("max-connections"         , optValue(values.aclMaxConnectTotal, "N"),   "The maximum combined number of connections allowed. 0 implies no limit.")
             ("max-connections-per-user", optValue(values.aclMaxConnectPerUser, "N"), "The maximum number of connections allowed per user. 0 implies no limit.")
             ("max-connections-per-ip"  , optValue(values.aclMaxConnectPerIp, "N"),   "The maximum number of connections allowed per host IP address. 0 implies no limit.")
+            ("max-queues-per-user",      optValue(values.aclMaxQueuesPerUser, "N"),  "The maximum number of queues allowed per user. 0 implies no limit.")
             ;
     }
 };

Added: qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp?rev=1375808&view=auto
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp (added)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.cpp Tue Aug 21 21:33:40 2012
@@ -0,0 +1,165 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "AclResourceCounter.h"
+#include "Acl.h"
+#include "qpid/log/Statement.h"
+#include "qpid/sys/Mutex.h"
+#include <assert.h>
+#include <sstream>
+
+using namespace qpid::sys;
+
+namespace qpid {
+namespace acl {
+
+//
+// This module approves various resource creation requests:
+//   Queues
+//
+
+
+//
+//
+//
+ResourceCounter::ResourceCounter(Acl& a, uint16_t ql) :
+    acl(a), queueLimit(ql) {
+        QPID_LOG(critical, "ACL RESOURCE_COUNTER queueLimit:" << queueLimit);
+    }
+
+ResourceCounter::~ResourceCounter() {}
+
+
+//
+// limitApproveLH
+//
+// Resource creation approver.
+// If user is under limit increment count and return true.
+// Called with lock held.
+//
+bool ResourceCounter::limitApproveLH(
+    const std::string& theTitle,
+    countsMap_t& theMap,
+    const std::string& theName,
+    uint16_t theLimit,
+    bool emitLog) {
+
+    bool result(true);
+    if (theLimit > 0) {
+        uint16_t count;
+        countsMap_t::iterator eRef = theMap.find(theName);
+        if (eRef != theMap.end()) {
+            count = (uint16_t)(*eRef).second;
+            result = count < theLimit;
+            if (result) {
+                count += 1;
+                (*eRef).second = count;
+            }
+        } else {
+            // Not found
+            theMap[theName] = count = 1;
+        }
+        if (emitLog) {
+            QPID_LOG(trace, theTitle << theName
+            << " limit=" << theLimit
+            << " curValue=" << count
+            << " result=" << (result ? "allow" : "deny"));
+        }
+    }
+    return result;
+}
+
+
+//
+// releaseLH
+//
+// Decrement the name's count in map.
+// called with dataLock already taken
+//
+void ResourceCounter::releaseLH(
+    const std::string& theTitle, countsMap_t& theMap, const std::string& theName, uint16_t theLimit) {
+
+    if (theLimit > 0) {
+        countsMap_t::iterator eRef = theMap.find(theName);
+        if (eRef != theMap.end()) {
+            uint16_t count = (uint16_t) (*eRef).second;
+            assert (count > 0);
+            if (1 == count) {
+                theMap.erase (eRef);
+            } else {
+                (*eRef).second = count - 1;
+            }
+        } else {
+            // User had no connections.
+            QPID_LOG(notice, theTitle << theName
+                << "' not found in resource count pool");
+        }
+    }
+}
+
+
+//
+// approveCreateQueue
+//  Count an attempted queue creation by this user.
+//  Disapprove if over limit.
+//
+bool ResourceCounter::approveCreateQueue(const std::string& userId, const std::string& queueName)
+{
+    Mutex::ScopedLock locker(dataLock);
+
+    bool okByQ = limitApproveLH("ACL Queue creation approver. userId:", queuePerUserMap, userId, queueLimit, true);
+
+    if (okByQ) {
+        // Queue is owned by this userId
+        queueOwnerMap[queueName] = userId;
+
+        QPID_LOG(trace, "ACL create queue approved for user '" << userId
+            << "' queue '" << queueName << "'");
+    } else {
+
+        QPID_LOG(error, "Client max queue count limit of " << queueLimit
+            << " exceeded by '" << userId << "' creating queue '"
+            << queueName << "'. Queue creation denied.");
+    }
+    return okByQ;
+}
+
+
+//
+// recordDestroyQueue
+//  Return a destroyed queue to a user's quota
+//
+void ResourceCounter::recordDestroyQueue(const std::string& queueName)
+{
+    Mutex::ScopedLock locker(dataLock);
+
+    queueOwnerMap_t::iterator eRef = queueOwnerMap.find(queueName);
+    if (eRef != queueOwnerMap.end()) {
+        releaseLH("ACL resource counter: Queue owner for queue '", queuePerUserMap, (*eRef).second, queueLimit);
+
+        queueOwnerMap.erase(eRef);
+    } else {
+        QPID_LOG(notice, "ACL resource counter: Queue '" << queueName
+            << "' not found in queue owner map");
+    }
+}
+
+}} // namespace qpid::acl

Added: qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.h
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.h?rev=1375808&view=auto
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.h (added)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/AclResourceCounter.h Tue Aug 21 21:33:40 2012
@@ -0,0 +1,78 @@
+#ifndef QPID_ACL_RESOURCECOUNTER_H
+#define QPID_ACL_RESOURCECOUNTER_H
+
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "qpid/sys/Mutex.h"
+#include <boost/iterator/iterator_concepts.hpp>
+
+#include <map>
+
+namespace qpid {
+
+namespace acl {
+class Acl;
+
+ /**
+ * Approve or disapprove resource creation requests
+ */
+class ResourceCounter
+{
+private:
+    typedef std::map<std::string, uint32_t> countsMap_t;
+    typedef std::map<std::string, std::string> queueOwnerMap_t;
+
+    Acl&             acl;
+    uint16_t         queueLimit;
+    qpid::sys::Mutex dataLock;
+
+    /** Records queueName-queueUserId */
+    queueOwnerMap_t queueOwnerMap;
+
+    /** Records queue-by-owner counts */
+    countsMap_t queuePerUserMap;
+
+    /** Return approval for proposed resource creation */
+    bool limitApproveLH(const std::string& theTitle,
+                        countsMap_t& theMap,
+                        const std::string& theName,
+                        uint16_t theLimit,
+                        bool emitLog);
+
+    /** Release a connection */
+    void releaseLH(const std::string& theTitle,
+                   countsMap_t& theMap,
+                   const std::string& theName,
+                   uint16_t theLimit);
+
+public:
+    ResourceCounter(Acl& acl, uint16_t ql);
+    ~ResourceCounter();
+
+    // Queue counting
+    bool approveCreateQueue(const std::string& userId, const std::string& queueName);
+    void recordDestroyQueue(const std::string& queueName);
+};
+
+}} // namespace qpid::acl
+
+#endif  /*!QPID_ACL_RESOURCECOUNTER_H*/

Modified: qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/management-schema.xml
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/management-schema.xml?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/management-schema.xml (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/acl/management-schema.xml Tue Aug 21 21:33:40 2012
@@ -25,8 +25,10 @@
     <property name="maxConnections"        type="uint16"  access="RO"       desc="Maximum allowed connections"/>
     <property name="maxConnectionsPerIp"   type="uint16"  access="RO"       desc="Maximum allowed connections"/>
     <property name="maxConnectionsPerUser" type="uint16"  access="RO"       desc="Maximum allowed connections"/>
+    <property name="maxQueuesPerUser"      type="uint16"  access="RO"       desc="Maximum allowed queues"/>
     <statistic name="aclDenyCount"         type="count64" unit="request"    desc="Number of ACL requests denied"/>
     <statistic name="connectionDenyCount"  type="count64" unit="connection" desc="Number of connections denied"/>
+    <statistic name="queueQuotaDenyCount"  type="count64" unit="connection" desc="Number of queue creations denied"/>
 
     <method name="reloadACLFile" desc="Reload the ACL file"/>
 
@@ -70,11 +72,13 @@
     <arg name="reason"     type="lstr"/>
     <arg name="userId"     type="sstr"/>
     <arg name="clientAddr" type="sstr"/>
+    <arg name="queueName"  type="sstr"/>
   </eventArguments>
 
   <event name="allow"          sev="inform" args="userId, action, objectType, objectName, arguments"/>
   <event name="deny"           sev="notice" args="userId, action, objectType, objectName, arguments"/>
   <event name="connectionDeny" sev="notice" args="userId, clientAddr"/>
+  <event name="queueQuotaDeny" sev="notice" args="userId, queueName"/>
   <event name="fileLoaded"     sev="inform" args="userId"/>
   <event name="fileLoadFailed" sev="error"  args="userId, reason"/>
 

Modified: qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/AclModule.h
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/AclModule.h?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/AclModule.h (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/AclModule.h Tue Aug 21 21:33:40 2012
@@ -151,6 +151,11 @@ namespace broker {
          */
         virtual void setUserId(const Connection& connection, const std::string& username)=0;
 
+        /** Approve queue creation by counting per-user.
+         */
+        virtual bool approveCreateQueue(const std::string& userId, const std::string& queueName)=0;
+        virtual void recordDestroyQueue(const std::string& queueName)=0;
+
         virtual ~AclModule() {};
     };
 } // namespace broker

Modified: qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/Broker.cpp
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/Broker.cpp?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/Broker.cpp (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/qpid/broker/Broker.cpp Tue Aug 21 21:33:40 2012
@@ -1072,6 +1072,9 @@ std::pair<boost::shared_ptr<Queue>, bool
 
         if (!acl->authorise(userId,acl::ACT_CREATE,acl::OBJ_QUEUE,name,&params) )
             throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << userId));
+
+        if (!acl->approveCreateQueue(userId,name) )
+            throw framing::UnauthorizedAccessException(QPID_MSG("ACL denied queue create request from " << userId));
     }
 
     Exchange::shared_ptr alternate;
@@ -1116,6 +1119,8 @@ void Broker::deleteQueue(const std::stri
     Queue::shared_ptr queue = queues.find(name);
     if (queue) {
         if (check) check(queue);
+        if (acl)
+            acl->recordDestroyQueue(name);
         queues.destroy(name);
         queue->destroyed();
     } else {

Modified: qpid/branches/qpid-2393/qpid/cpp/src/tests/acl.py
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/tests/acl.py?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/tests/acl.py (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/tests/acl.py Tue Aug 21 21:33:40 2012
@@ -53,6 +53,9 @@ class ACLTests(TestBase010):
     def port_u(self):
         return int(self.defines["port-u"])
 
+    def port_q(self):
+        return int(self.defines["port-q"])
+
     def get_session_by_port(self, user, passwd, byPort):
         socket = connect(self.broker.host, byPort)
         connection = Connection (sock=socket, username=user, password=passwd,
@@ -2243,6 +2246,62 @@ class ACLTests(TestBase010):
         self.LookupPublish("joe@QPID", "QPID-work",  "QPID",        "allow")
         self.LookupPublish("joe@QPID", "QPID-work2", "QPID",        "allow")
 
+   #=====================================
+   # Queue per-user quota
+   #=====================================
+
+    def test_queue_per_user_quota(self):
+        """
+        Test ACL queue counting limits.
+        port_q has a limit of 2
+        """
+        # bob should be able to create two queues
+        session = self.get_session_by_port('bob','bob', self.port_q())
+
+        try:
+            session.queue_declare(queue="queue1")
+            session.queue_declare(queue="queue2")
+        except qpid.session.SessionException, e:
+            self.fail("Error during queue create request");
+
+        # third queue should fail
+        try:
+            session.queue_declare(queue="queue3")
+            self.fail("Should not be able to create third queue")
+        except Exception, e:
+            result = None
+            session = self.get_session_by_port('bob','bob', self.port_q())
+
+        # alice should be able to create two queues
+        session2 = self.get_session_by_port('alice','alice', self.port_q())
+
+        try:
+            session2.queue_declare(queue="queuea1")
+            session2.queue_declare(queue="queuea2")
+        except qpid.session.SessionException, e:
+            self.fail("Error during queue create request");
+
+        # third queue should fail
+        try:
+            session2.queue_declare(queue="queuea3")
+            self.fail("Should not be able to create third queue")
+        except Exception, e:
+            result = None
+            session2 = self.get_session_by_port('alice','alice', self.port_q())
+
+        # bob should be able to delete a queue and create another
+        try:
+            session.queue_delete(queue="queue1")
+            session.queue_declare(queue="queue3")
+        except qpid.session.SessionException, e:
+            self.fail("Error during queue create request");
+
+        # alice should be able to delete a queue and create another
+        try:
+            session2.queue_delete(queue="queuea1")
+            session2.queue_declare(queue="queuea3")
+        except qpid.session.SessionException, e:
+            self.fail("Error during queue create request");
 
 class BrokerAdmin:
     def __init__(self, broker, username=None, password=None):

Modified: qpid/branches/qpid-2393/qpid/cpp/src/tests/run_acl_tests
URL: http://svn.apache.org/viewvc/qpid/branches/qpid-2393/qpid/cpp/src/tests/run_acl_tests?rev=1375808&r1=1375807&r2=1375808&view=diff
==============================================================================
--- qpid/branches/qpid-2393/qpid/cpp/src/tests/run_acl_tests (original)
+++ qpid/branches/qpid-2393/qpid/cpp/src/tests/run_acl_tests Tue Aug 21 21:33:40 2012
@@ -24,22 +24,26 @@ source ./test_env.sh
 DATA_DIR=`pwd`/data_dir
 DATA_DIRI=`pwd`/data_diri
 DATA_DIRU=`pwd`/data_diru
+DATA_DIRQ=`pwd`/data_dirq
 
 trap stop_brokers INT TERM QUIT
 
 start_brokers() {
-    ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIR --load-module $ACL_LIB --acl-file policy.acl --auth no --log-to-file local.log > qpidd.port
+    ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIR --load-module $ACL_LIB --acl-file policy.acl --auth no                               --log-to-file local.log > qpidd.port
     LOCAL_PORT=`cat qpidd.port`
-    ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRI --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-ip 2 --log-to-file locali.log > qpiddi.port
+    ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRI --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-ip 2   --log-to-file locali.log > qpiddi.port
     LOCAL_PORTI=`cat qpiddi.port`
     ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRU --load-module $ACL_LIB --acl-file policy.acl --auth no --max-connections-per-user 2 --log-to-file localu.log > qpiddu.port
     LOCAL_PORTU=`cat qpiddu.port`
+    ../qpidd --daemon --port 0 --no-module-dir --data-dir $DATA_DIRQ --load-module $ACL_LIB --acl-file policy.acl --auth no --max-queues-per-user 2      --log-to-file localq.log > qpiddq.port
+    LOCAL_PORTQ=`cat qpiddq.port`
 }
 
 stop_brokers() {
         $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORT
         $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTI
         $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTU
+        $QPIDD_EXEC --no-module-dir -q --port $LOCAL_PORTQ
 }
 
 test_loading_acl_from_absolute_path(){
@@ -59,20 +63,24 @@ if test -d ${PYTHON_DIR} ;  then
     rm -rf $DATA_DIR
     rm -rf $DATA_DIRI
     rm -rf $DATA_DIRU
+    rm -rf $DATA_DIRQ
     mkdir -p $DATA_DIR
     mkdir -p $DATA_DIRI
     mkdir -p $DATA_DIRU
+    mkdir -p $DATA_DIRQ
     cp $srcdir/policy.acl $DATA_DIR
     cp $srcdir/policy.acl $DATA_DIRI
     cp $srcdir/policy.acl $DATA_DIRU
+    cp $srcdir/policy.acl $DATA_DIRQ
     start_brokers
-    echo "Running acl tests using brokers on ports $LOCAL_PORT, $LOCAL_PORTI, and $LOCAL_PORTU"
-    $QPID_PYTHON_TEST -b localhost:$LOCAL_PORT -m acl -Dport-i=$LOCAL_PORTI -Dport-u=$LOCAL_PORTU || EXITCODE=1
+    echo "Running acl tests using brokers on ports $LOCAL_PORT, $LOCAL_PORTI, $LOCAL_PORTU, and $LOCAL_PORTQ"
+    $QPID_PYTHON_TEST -b localhost:$LOCAL_PORT -m acl -Dport-i=$LOCAL_PORTI -Dport-u=$LOCAL_PORTU -Dport-q=$LOCAL_PORTQ || EXITCODE=1
     stop_brokers || EXITCODE=1
     test_loading_acl_from_absolute_path || EXITCODE=1
     rm -rf $DATA_DIR
     rm -rf $DATA_DIRI
     rm -rf $DATA_DIRU
+    rm -rf $DATA_DIRQ
     exit $EXITCODE
 fi
 



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