summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorCarl C. Trieloff <cctrieloff@apache.org>2008-01-02 15:56:20 +0000
committerCarl C. Trieloff <cctrieloff@apache.org>2008-01-02 15:56:20 +0000
commit3fe6853a7029e48f693c0853e51af33be5c79aec (patch)
tree6139a715591aabc91370350aa26f854639a2aa11 /python
parent8bc0b992a0e67259a7d9c525bbbbbc32fbc60a20 (diff)
downloadqpid-python-3fe6853a7029e48f693c0853e51af33be5c79aec.tar.gz
patch-715 (tross)
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@608135 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'python')
-rwxr-xr-xpython/mgmt-cli/main.py1
-rw-r--r--python/mgmt-cli/managementdata.py141
-rw-r--r--python/qpid/management.py65
3 files changed, 158 insertions, 49 deletions
diff --git a/python/mgmt-cli/main.py b/python/mgmt-cli/main.py
index 4d7c03d1f2..76e1f25c14 100755
--- a/python/mgmt-cli/main.py
+++ b/python/mgmt-cli/main.py
@@ -49,6 +49,7 @@ class Mcli (Cmd):
print " list <className> - Print list of objects of the specified class"
print " list <className> all - Print contents of all objects of specified class"
print " list <className> active - Print contents of all non-deleted objects of specified class"
+ print " list <list-of-IDs> - Print contents of one or more objects (infer className)"
print " list <className> <list-of-IDs> - Print contents of one or more objects"
print " list is space-separated, ranges may be specified (i.e. 1004-1010)"
print " call <ID> <methodName> [<args>] - Invoke a method on an object"
diff --git a/python/mgmt-cli/managementdata.py b/python/mgmt-cli/managementdata.py
index 2adb962b54..419cbd13c0 100644
--- a/python/mgmt-cli/managementdata.py
+++ b/python/mgmt-cli/managementdata.py
@@ -118,6 +118,7 @@ class ManagementData:
self.schema = {}
self.baseId = 0
self.disp = disp
+ self.lastUnit = None
self.methodSeq = 1
self.methodsPending = {}
self.broker.start ()
@@ -125,6 +126,44 @@ class ManagementData:
def close (self):
self.broker.stop ()
+ def refName (self, oid):
+ if oid == 0:
+ return "NULL"
+ return str (oid - self.baseId)
+
+ def valueDisplay (self, className, key, value):
+ for kind in range (2):
+ schema = self.schema[className][kind]
+ for item in schema:
+ if item[0] == key:
+ typecode = item[1]
+ unit = item[2]
+ if typecode >= 1 and typecode <= 5: # numerics
+ if unit == None or unit == self.lastUnit:
+ return str (value)
+ else:
+ self.lastUnit = unit
+ suffix = ""
+ if value != 1:
+ suffix = "s"
+ return str (value) + " " + unit + suffix
+ elif typecode == 6 or typecode == 7: # strings
+ return value
+ elif typecode == 8:
+ if value == 0:
+ return "--"
+ return self.disp.timestamp (value)
+ elif typecode == 9:
+ return str (value)
+ elif typecode == 10:
+ return self.refName (value)
+ elif typecode == 11:
+ if value == 0:
+ return "False"
+ else:
+ return "True"
+ return "*type-error*"
+
def getObjIndex (self, className, config):
""" Concatenate the values from index columns to form a unique object name """
result = ""
@@ -135,9 +174,7 @@ class ManagementData:
result = result + "."
for key,val in config:
if key == item[0]:
- if key.find ("Ref") != -1:
- val = val - self.baseId
- result = result + str (val)
+ result = result + self.valueDisplay (className, key, val)
return result
def classCompletions (self, prefix):
@@ -168,6 +205,14 @@ class ManagementData:
return "short-string"
elif typecode == 7:
return "long-string"
+ elif typecode == 8:
+ return "abs-time"
+ elif typecode == 9:
+ return "delta-time"
+ elif typecode == 10:
+ return "reference"
+ elif typecode == 11:
+ return "boolean"
else:
raise ValueError ("Invalid type code: %d" % typecode)
@@ -180,7 +225,7 @@ class ManagementData:
elif code == 3:
return "ReadOnly"
else:
- raise ValueErrir ("Invalid access code: %d" %code)
+ raise ValueError ("Invalid access code: %d" %code)
def notNone (self, text):
if text == None:
@@ -188,6 +233,12 @@ class ManagementData:
else:
return text
+ def isOid (self, id):
+ for char in str (id):
+ if not char.isdigit () and not char == '-':
+ return False
+ return True
+
def listOfIds (self, className, tokens):
""" Generate a tuple of object ids for a classname based on command tokens. """
list = []
@@ -202,13 +253,14 @@ class ManagementData:
else:
for token in tokens:
- if token.find ("-") != -1:
- ids = token.split("-", 2)
- for id in range (int (ids[0]), int (ids[1]) + 1):
- if self.getClassForId (long (id) + self.baseId) == className:
- list.append (id)
- else:
- list.append (token)
+ if self.isOid (token):
+ if token.find ("-") != -1:
+ ids = token.split("-", 2)
+ for id in range (int (ids[0]), int (ids[1]) + 1):
+ if self.getClassForId (long (id) + self.baseId) == className:
+ list.append (id)
+ else:
+ list.append (token)
list.sort ()
result = ()
@@ -258,7 +310,7 @@ class ManagementData:
if ts[2] > 0:
destroyTime = self.disp.timestamp (ts[2])
objIndex = self.getObjIndex (className, config)
- row = (objId - self.baseId, createTime, destroyTime, objIndex)
+ row = (self.refName (objId), createTime, destroyTime, objIndex)
rows.append (row)
self.disp.table ("Objects of type %s" % className,
("ID", "Created", "Destroyed", "Index"),
@@ -270,12 +322,26 @@ class ManagementData:
""" Generate a display of object data for a particular class """
self.lock.acquire ()
try:
- className = tokens[0]
- if className not in self.tables:
- print "Class not known: %s" % className
- raise ValueError ()
-
- userIds = self.listOfIds (className, tokens[1:])
+ self.lastUnit = None
+ if self.isOid (tokens[0]):
+ if tokens[0].find ("-") != -1:
+ rootId = int (tokens[0][0:tokens[0].find ("-")])
+ else:
+ rootId = int (tokens[0])
+
+ className = self.getClassForId (rootId + self.baseId)
+ remaining = tokens
+ if className == None:
+ print "Id not known: %d" % int (tokens[0])
+ raise ValueError ()
+ else:
+ className = tokens[0]
+ remaining = tokens[1:]
+ if className not in self.tables:
+ print "Class not known: %s" % className
+ raise ValueError ()
+
+ userIds = self.listOfIds (className, remaining)
if len (userIds) == 0:
print "No object IDs supplied"
raise ValueError ()
@@ -286,36 +352,37 @@ class ManagementData:
ids.append (long (id) + self.baseId)
rows = []
+ timestamp = None
config = self.tables[className][ids[0]][1]
for eIdx in range (len (config)):
key = config[eIdx][0]
if key != "id":
- isRef = key.find ("Ref") == len (key) - 3
row = ("config", key)
for id in ids:
- value = self.tables[className][id][1][eIdx][1]
- if isRef:
- value = value - self.baseId
- row = row + (value,)
+ if timestamp == None or \
+ timestamp < self.tables[className][id][0][0]:
+ timestamp = self.tables[className][id][0][0]
+ (key, value) = self.tables[className][id][1][eIdx]
+ row = row + (self.valueDisplay (className, key, value),)
rows.append (row)
inst = self.tables[className][ids[0]][2]
for eIdx in range (len (inst)):
key = inst[eIdx][0]
if key != "id":
- isRef = key.find ("Ref") == len (key) - 3
row = ("inst", key)
for id in ids:
- value = self.tables[className][id][2][eIdx][1]
- if isRef:
- value = value - self.baseId
- row = row + (value,)
+ (key, value) = self.tables[className][id][2][eIdx]
+ row = row + (self.valueDisplay (className, key, value),)
rows.append (row)
titleRow = ("Type", "Element")
for id in ids:
- titleRow = titleRow + (str (id - self.baseId),)
- self.disp.table ("Object of type %s:" % className, titleRow, rows)
+ titleRow = titleRow + (self.refName (id),)
+ caption = "Object of type %s:" % className
+ if timestamp != None:
+ caption = caption + " (last sample time: " + self.disp.timestamp (timestamp) + ")"
+ self.disp.table (caption, titleRow, rows)
except:
pass
@@ -418,6 +485,10 @@ class ManagementData:
if className == None:
raise ValueError ()
+ if methodName not in self.schema[className][2]:
+ print "Method '%s' not valid for class '%s'" % (methodName, className)
+ raise ValueError ()
+
schemaMethod = self.schema[className][2][methodName]
if len (args) != len (schemaMethod[1]):
print "Wrong number of method args: Need %d, Got %d" % (len (schemaMethod[1]), len (args))
@@ -431,17 +502,19 @@ class ManagementData:
self.methodsPending[self.methodSeq] = methodName
except:
methodOk = False
- print "Error in call syntax"
self.lock.release ()
if methodOk:
- self.broker.method (self.methodSeq, userOid + self.baseId, className,
- methodName, namedArgs)
+# try:
+ self.broker.method (self.methodSeq, userOid + self.baseId, className,
+ methodName, namedArgs)
+# except ValueError, e:
+# print "Error invoking method:", e
def do_list (self, data):
tokens = data.split ()
if len (tokens) == 0:
self.listClasses ()
- elif len (tokens) == 1:
+ elif len (tokens) == 1 and not self.isOid (tokens[0]):
self.listObjects (data)
else:
self.showObjects (tokens)
diff --git a/python/qpid/management.py b/python/qpid/management.py
index 1c8b3cd840..40de2a5298 100644
--- a/python/qpid/management.py
+++ b/python/qpid/management.py
@@ -77,6 +77,14 @@ class ManagementMetadata:
codec.encode_shortstr (value)
elif typecode == 7:
codec.encode_longstr (value)
+ elif typecode == 8: # ABSTIME
+ codec.encode_longlong (long (value))
+ elif typecode == 9: # DELTATIME
+ codec.encode_longlong (long (value))
+ elif typecode == 10: # REF
+ codec.encode_longlong (long (value))
+ elif typecode == 11: # BOOL
+ codec.encode_octet (int (value))
else:
raise ValueError ("Invalid type code: %d" % typecode)
@@ -95,6 +103,14 @@ class ManagementMetadata:
data = codec.decode_shortstr ()
elif typecode == 7:
data = codec.decode_longstr ()
+ elif typecode == 8: # ABSTIME
+ data = codec.decode_longlong ()
+ elif typecode == 9: # DELTATIME
+ data = codec.decode_longlong ()
+ elif typecode == 10: # REF
+ data = codec.decode_longlong ()
+ elif typecode == 11: # BOOL
+ data = codec.decode_octet ()
else:
raise ValueError ("Invalid type code: %d" % typecode)
return data
@@ -236,10 +252,7 @@ class ManagementMetadata:
elif cls == 'I':
self.broker.inst_cb[1] (self.broker.inst_cb[0], className, row, timestamps)
- def parse (self, codec):
- opcode = chr (codec.decode_octet ())
- cls = chr (codec.decode_octet ())
-
+ def parse (self, codec, opcode, cls):
if opcode == 'S':
self.parseSchema (cls, codec)
@@ -261,34 +274,53 @@ class ManagedBroker:
mExchange = "qpid.management"
dExchange = "amq.direct"
+ def setHeader (self, codec, opcode, cls = 0):
+ codec.encode_octet (ord ('A'))
+ codec.encode_octet (ord ('M'))
+ codec.encode_octet (ord ('0'))
+ codec.encode_octet (ord ('1'))
+ codec.encode_octet (opcode)
+ codec.encode_octet (cls)
+
def checkHeader (self, codec):
octet = chr (codec.decode_octet ())
if octet != 'A':
- return 0
+ return None
octet = chr (codec.decode_octet ())
if octet != 'M':
- return 0
+ return None
octet = chr (codec.decode_octet ())
if octet != '0':
- return 0
+ return None
octet = chr (codec.decode_octet ())
if octet != '1':
- return 0
- return 1
+ return None
+ opcode = chr (codec.decode_octet ())
+ cls = chr (codec.decode_octet ())
+ return (opcode, cls)
def publish_cb (self, msg):
codec = Codec (StringIO (msg.content.body), self.spec)
- if self.checkHeader (codec) == 0:
+ hdr = self.checkHeader (codec)
+ if hdr == None:
raise ValueError ("outer header invalid");
- self.metadata.parse (codec)
+ self.metadata.parse (codec, hdr[0], hdr[1])
msg.complete ()
def reply_cb (self, msg):
codec = Codec (StringIO (msg.content.body), self.spec)
- sequence = codec.decode_long ()
- status = codec.decode_long ()
+ hdr = self.checkHeader (codec)
+ if hdr == None:
+ msg.complete ()
+ return
+ if hdr[0] != 'R':
+ msg.complete ()
+ return
+
+ sequence = codec.decode_long ()
+ status = codec.decode_long ()
sText = codec.decode_shortstr ()
data = self.sequenceManager.release (sequence)
@@ -369,9 +401,10 @@ class ManagedBroker:
methodName, args=None, packageName="qpid"):
codec = Codec (StringIO (), self.spec);
sequence = self.sequenceManager.reserve ((userSequence, className, methodName))
+ self.setHeader (codec, ord ('M'))
codec.encode_long (sequence) # Method sequence id
codec.encode_longlong (objId) # ID of object
- codec.encode_shortstr (self.rqname) # name of reply queue
+ #codec.encode_shortstr (self.rqname) # name of reply queue
# Encode args according to schema
if (className,'M') not in self.metadata.schema:
@@ -402,6 +435,8 @@ class ManagedBroker:
msg["content_type"] = "application/octet-stream"
msg["routing_key"] = "method." + packageName + "." + className + "." + methodName
msg["reply_to"] = self.spec.struct ("reply_to")
+ msg["reply_to"]["exchange_name"] = "amq.direct"
+ msg["reply_to"]["routing_key"] = self.rqname
self.channel.message_transfer (destination="qpid.management", content=msg)
def isConnected (self):
@@ -414,7 +449,7 @@ class ManagedBroker:
self.client = Client (self.host, self.port, self.spec)
self.client.start ({"LOGIN": self.username, "PASSWORD": self.password})
self.channel = self.client.channel (1)
- response = self.channel.session_open (detached_lifetime=10)
+ response = self.channel.session_open (detached_lifetime=300)
self.qname = "mgmt-" + base64.urlsafe_b64encode (response.session_id)
self.rqname = "reply-" + base64.urlsafe_b64encode (response.session_id)