ACL Enhancement to support queue limit policies
---
Key: QPID-2108
URL: https://issues.apache.org/jira/browse/QPID-2108
Project: Qpid
Issue Type: Improvement
Components: C++ Broker
Affects Versions: 0.5
Reporter: Tim Platten
It is a requirement for us to be able to enforce queue limit policies using the
ACL authorisation mechanism. I therefore propose the following enhancement:
Add three new properties to the create queue rule: limitpolicy, maxqueuesize
and maxqueuecount. The policy test can be implemented using existing code, but
the numeric limits require a less-than-or-equal test. I.e. if a value for
maxqueuesize is specified in the ACL file, an exception will be thrown if a
value greater than this is specified in declareQueue. A value less than or
equal would be acceptable. If maxqueuecount and/or maxqueuesize were omitted
from the rule or specified as zero, the corresponding check would interpret the
value as unlimited.
Proposed code changes follow (prefixed with change-bar |).
AclModule.h
.
.
.
enum Property {PROP_NAME, PROP_DURABLE, PROP_OWNER, PROP_ROUTINGKEY,
PROP_PASSIVE, PROP_AUTODELETE, PROP_EXCLUSIVE, PROP_TYPE,
PROP_ALTERNATE, PROP_QUEUENAME, PROP_SCHEMAPACKAGE,
| PROP_SCHEMACLASS, PROP_LIMITPOLICY, PROP_MAXQUEUESIZE,
PROP_MAXQUEUECOUNT};
.
.
.
static inline Property getProperty(const std::string str) {
if (str.compare(name) == 0) return PROP_NAME;
if (str.compare(durable) == 0) return PROP_DURABLE;
if (str.compare(owner) == 0) return PROP_OWNER;
if (str.compare(routingkey) == 0) return PROP_ROUTINGKEY;
if (str.compare(passive) == 0) return PROP_PASSIVE;
if (str.compare(autodelete) == 0) return PROP_AUTODELETE;
if (str.compare(exclusive) == 0) return PROP_EXCLUSIVE;
if (str.compare(type) == 0) return PROP_TYPE;
if (str.compare(alternate) == 0) return PROP_ALTERNATE;
if (str.compare(queuename) == 0) return PROP_QUEUENAME;
if (str.compare(schemapackage) == 0) return PROP_SCHEMAPACKAGE;
if (str.compare(schemaclass) == 0) return PROP_SCHEMACLASS;
| if (str.compare(limitpolicy) == 0) return PROP_LIMITPOLICY;
| if (str.compare(maxqueuesize) == 0) return PROP_MAXQUEUESIZE;
| if (str.compare(maxqueuecount) == 0) return PROP_MAXQUEUECOUNT;
throw str;
}
static inline std::string getPropertyStr(const Property p) {
switch (p) {
case PROP_NAME: return name;
case PROP_DURABLE: return durable;
case PROP_OWNER: return owner;
case PROP_ROUTINGKEY: return routingkey;
case PROP_PASSIVE: return passive;
case PROP_AUTODELETE: return autodelete;
case PROP_EXCLUSIVE: return exclusive;
case PROP_TYPE: return type;
case PROP_ALTERNATE: return alternate;
case PROP_QUEUENAME: return queuename;
case PROP_SCHEMAPACKAGE: return schemapackage;
case PROP_SCHEMACLASS: return schemaclass;
| case PROP_LIMITPOLICY: return limitpolicy;
| case PROP_MAXQUEUESIZE: return maxqueuesize;
| case PROP_MAXQUEUECOUNT: return maxqueuecount;
default: assert(false); // should never get here
}
return ;
}
.
.
.
// == Queues ==
propSetPtr p4(new propSet);
| p4-insert(PROP_ALTERNATE);
| p4-insert(PROP_PASSIVE);
| p4-insert(PROP_DURABLE);
| p4-insert(PROP_EXCLUSIVE);
| p4-insert(PROP_AUTODELETE);
| p4-insert(PROP_LIMITPOLICY);
| p4-insert(PROP_MAXQUEUESIZE);
| p4-insert(PROP_MAXQUEUECOUNT);
Note that currently (Qpid 0.5) this code appears to be incorrectly
dereferencing p3 instead of p4.
SessionAdapter.cpp
.
.
.
void SessionAdapter::QueueHandlerImpl::declare(const string name, const
string alternateExchange,
bool passive, bool durable, bool
exclusive,
bool autoDelete, const
qpid::framing::FieldTable arguments)
{
AclModule* acl = getBroker().getAcl();
if (acl) {
std::mapacl::Property, std::string params;
params.insert(make_pair(acl::PROP_ALTERNATE, alternateExchange));
params.insert(make_pair(acl::PROP_PASSIVE, std::string(passive ? true
: false) ));
params.insert(make_pair(acl::PROP_DURABLE, std::string(durable ? true
: false)));
params.insert(make_pair(acl::PROP_EXCLUSIVE, std::string(exclusive ?
true : false)));
params.insert(make_pair(acl::PROP_AUTODELETE, std::string(autoDelete ?
true : false)));
| params.insert(make_pair(acl::PROP_LIMITPOLICY,
arguments.getAsString(qpid.policy_type)));
| params.insert(make_pair(acl::PROP_MAXQUEUECOUNT,
boost::lexical_caststring(arguments.getAsInt(qpid.max_count;
|