summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael H. Schloming <rhs@apache.org>2010-01-25 13:12:51 +0000
committerRafael H. Schloming <rhs@apache.org>2010-01-25 13:12:51 +0000
commit44510813d26dca74622497b0217c730b779205b4 (patch)
tree9028252b4b1135dddeec55500d389097430f26a6
parentcdee35e16d30c13132a5c6b7ce5f84db2e5fdfd8 (diff)
downloadqpid-python-44510813d26dca74622497b0217c730b779205b4.tar.gz
verify that bindings are only specified for queues
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@902803 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--python/qpid/driver.py14
-rw-r--r--python/qpid/tests/messaging.py6
-rw-r--r--python/qpid/validator.py33
3 files changed, 46 insertions, 7 deletions
diff --git a/python/qpid/driver.py b/python/qpid/driver.py
index c25b0dd67e..7d203de588 100644
--- a/python/qpid/driver.py
+++ b/python/qpid/driver.py
@@ -28,7 +28,7 @@ from ops import *
from selector import Selector
from threading import Condition, Thread
from util import connect
-from validator import Map, Types, Values
+from validator import And, Context, Map, Types, Values
log = getLogger("qpid.messaging")
rawlog = getLogger("qpid.messaging.io.raw")
@@ -584,6 +584,13 @@ class Driver:
POLICIES = Values("always", "sender", "receiver", "never")
+ class Bindings:
+
+ def validate(self, o, ctx):
+ t = ctx.containers[1].get("type", "queue")
+ if t != "queue":
+ return "bindings are only permitted on nodes of type queue"
+
OPTS = Map({
"create": POLICIES,
"delete": POLICIES,
@@ -593,14 +600,15 @@ class Driver:
"durable": Types(bool),
"x-properties": Map({
"type": Types(basestring),
- "bindings": Types(list)
+ "bindings": And(Types(list), Bindings())
},
restricted=False)
})
})
def validate_options(self, lnk):
- err = Driver.OPTS.validate(lnk.options)
+ ctx = Context()
+ err = Driver.OPTS.validate(lnk.options, ctx)
if err:
lnk.target.error = ("error in options: %s" % err,)
lnk.target.closed = True
diff --git a/python/qpid/tests/messaging.py b/python/qpid/tests/messaging.py
index 7bcbc455af..ea4ae6a7fb 100644
--- a/python/qpid/tests/messaging.py
+++ b/python/qpid/tests/messaging.py
@@ -613,6 +613,12 @@ class AddressTests(Base):
self.badOption("{node-properties: {durable: []}}",
"node-properties: durable: [] is not a bool")
+ def testNonQueueBindings(self):
+ self.badOption("{node-properties: {type: topic, x-properties: "
+ "{bindings: []}}}",
+ "node-properties: x-properties: bindings: "
+ "bindings are only permitted on nodes of type queue")
+
def testCreateQueue(self):
snd = self.ssn.sender("test-create-queue; {create: always, delete: always, "
"node-properties: {type: queue, durable: False, "
diff --git a/python/qpid/validator.py b/python/qpid/validator.py
index 8bd1c98736..7bd62b68f8 100644
--- a/python/qpid/validator.py
+++ b/python/qpid/validator.py
@@ -17,12 +17,23 @@
# under the License.
#
+class Context:
+
+ def __init__(self):
+ self.containers = []
+
+ def push(self, o):
+ self.containers.append(o)
+
+ def pop(self):
+ return self.containers.pop()
+
class Values:
def __init__(self, *values):
self.values = values
- def validate(self, o):
+ def validate(self, o, ctx):
if not o in self.values:
return "%s not in %s" % (o, self.values)
@@ -34,7 +45,7 @@ class Types:
def __init__(self, *types):
self.types = types
- def validate(self, o):
+ def validate(self, o, ctx):
for t in self.types:
if isinstance(o, t):
return
@@ -49,20 +60,34 @@ class Map:
self.map = map
self.restricted = restricted
- def validate(self, o):
+ def validate(self, o, ctx):
errors = []
if not hasattr(o, "get"):
return "%s is not a map" % o
+ ctx.push(o)
for k, t in self.map.items():
v = o.get(k)
if v is not None:
- err = t.validate(v)
+ err = t.validate(v, ctx)
if err: errors.append("%s: %s" % (k, err))
if self.restricted:
for k in o:
if not k in self.map:
errors.append("%s: illegal key" % k)
+ ctx.pop()
+
if errors:
return ", ".join(errors)
+
+class And:
+
+ def __init__(self, *conditions):
+ self.conditions = conditions
+
+ def validate(self, o, ctx):
+ for c in self.conditions:
+ err = c.validate(o, ctx)
+ if err:
+ return err