diff options
author | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2013-02-28 16:14:30 +0000 |
commit | 9c73ef7a5ac10acd6a50d5d52bd721fc2faa5919 (patch) | |
tree | 2a890e1df09e5b896a9b4168a7b22648f559a1f2 /cpp/src/qpid/acl/AclResourceCounter.cpp | |
parent | 172d9b2a16cfb817bbe632d050acba7e31401cd2 (diff) | |
download | qpid-python-asyncstore.tar.gz |
Update from trunk r1375509 through r1450773asyncstore
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1451244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/acl/AclResourceCounter.cpp')
-rw-r--r-- | cpp/src/qpid/acl/AclResourceCounter.cpp | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/cpp/src/qpid/acl/AclResourceCounter.cpp b/cpp/src/qpid/acl/AclResourceCounter.cpp new file mode 100644 index 0000000000..66dfd0777e --- /dev/null +++ b/cpp/src/qpid/acl/AclResourceCounter.cpp @@ -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) {} + +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."); + + acl.reportQueueLimit(userId, queueName); + } + 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 |