diff options
author | Alan Conway <aconway@apache.org> | 2007-11-23 13:37:42 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2007-11-23 13:37:42 +0000 |
commit | be0313393ec53394472b033c83ec8780fe4c5d2b (patch) | |
tree | 89cd4b31606fbe74356c2414cb67aabbae9b0177 | |
parent | 2e75ce2a7bc1a94c294def9f70789c49770c2470 (diff) | |
download | qpid-python-be0313393ec53394472b033c83ec8780fe4c5d2b.tar.gz |
QPID-689 from tross@redhat.com.
This patch introduces formal schema specification for management and
code generation for management classes.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@597662 13f79535-47bb-0310-9956-ffa450edef68
24 files changed, 1701 insertions, 1094 deletions
diff --git a/qpid/cpp/bootstrap b/qpid/cpp/bootstrap index 84f0fbd89b..c1fb753201 100755 --- a/qpid/cpp/bootstrap +++ b/qpid/cpp/bootstrap @@ -15,6 +15,10 @@ cat > src/rubygen.mk <<EOF \$(srcdir)/rubygen.mk: force \$(rgen_cmd) EOF +cat > src/managementgen.mk <<EOF +\$(srcdir)/managementgen.mk: force + \$(mgen_cmd) +EOF automake diff --git a/qpid/cpp/managementgen/generate.py b/qpid/cpp/managementgen/generate.py new file mode 100755 index 0000000000..1d0987e685 --- /dev/null +++ b/qpid/cpp/managementgen/generate.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python + +# +# 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. +# + +from xml.dom.minidom import parse, parseString, Node +from cStringIO import StringIO +from stat import * +from errno import * +import os +import os.path +import filecmp + +#===================================================================================== +# +#===================================================================================== +class Template: + def __init__ (self, filename, handler): + self.filename = filename + self.handler = handler + + def expandLine (self, line, stream, object): + cursor = 0 + while 1: + sub = line.find ("/*MGEN:", cursor) + if sub == -1: + stream.write (line[cursor:len (line)]) + return + + subend = line.find("*/", sub) + stream.write (line[cursor:sub]) + cursor = subend + 2 + + tag = line[sub:subend] + dotPos = tag.find (".") + if dotPos == -1: + raise ValueError ("Invalid tag: %s" % tag) + tagObject = tag[7:dotPos] + tagName = tag[dotPos + 1:len (tag)] + + self.handler (object, stream, tagObject, tagName) + + def expand (self, object): + fd = open (self.filename) + stream = StringIO () + + for line in fd: + self.expandLine (line, stream, object) + fd.close () + + return stream + +#===================================================================================== +# +#===================================================================================== +class Generator: + def createPath (self, path): + exists = True + try: + mode = os.stat (path)[ST_MODE] + except OSError, (err,text): + if err == ENOENT: + exists = False + else: + raise + if exists and not S_ISDIR (mode): + raise ValueError ("path is not directory: %s" % path) + if not exists: + pair = os.path.split (path) + self.createPath (pair[0]) + os.mkdir (path) + + def normalize (self, path): + newpath = os.path.normcase (os.path.normpath (path)) + self.createPath (newpath) + return newpath + "/" + + def __init__ (self, destDir, templateDir): + self.dest = self.normalize (destDir) + self.input = self.normalize (templateDir) + self.filelists = {} + self.filelists["h"] = [] + self.filelists["cpp"] = [] + self.filelists["mk"] = [] + self.templateFiles = [] + + def genDisclaimer (self, stream): + stream.write ("// This source file was created by a code generator.\n") + stream.write ("// Please do not edit.") + + def fileExt (self, path): + dot = path.rfind (".") + if dot == -1: + return "" + return path[dot + 1:] + + def writeIfChanged (self, stream, target, force=False): + ext = self.fileExt (target) + self.filelists[ext].append (target) + tempFile = self.dest + "gen.tmp" + fd = open (tempFile, "w") + fd.write (stream.getvalue ()) + fd.close () + + try: + if not force and filecmp.cmp (target, tempFile): + os.remove (tempFile) + return + except: + pass + + try: + os.remove (target) + except: + pass + + os.rename (tempFile, target) + print "Generated:", target + + def targetClassFile (self, _class, templateFile): + dot = templateFile.find(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:len (templateFile)] + path = self.dest + _class.getName ().capitalize () + extension + return path + + def targetMethodFile (self, method, templateFile): + """ Return the file name for a method file """ + dot = templateFile.rfind(".") + if dot == -1: + raise ValueError ("Invalid template file name %s" % templateFile) + extension = templateFile[dot:] + path = self.dest + "Args" + method.getFullName () + extension + return path + + def substHandler (self, object, stream, tagObject, tag): + if tagObject == "Root": + obj = "self" + else: + obj = "object" # MUST be the same as the 2nd formal parameter + + call = obj + ".gen" + tag + "(stream)" + eval (call) + + def makeClassFiles (self, templateFile, schema): + """ Generate an expanded template per schema class """ + classes = schema.getClasses () + template = Template (self.input + templateFile, self.substHandler) + self.templateFiles.append (templateFile) + for _class in classes: + target = self.targetClassFile (_class, templateFile) + stream = template.expand (_class) + self.writeIfChanged (stream, target) + + def makeMethodFiles (self, templateFile, schema): + """ Generate an expanded template per method-with-arguments """ + classes = schema.getClasses () + template = Template (self.input + templateFile, self.substHandler) + self.templateFiles.append (templateFile) + for _class in classes: + methods = _class.getMethods () + for method in methods: + if method.getArgCount () > 0: + target = self.targetMethodFile (method, templateFile) + stream = template.expand (method) + self.writeIfChanged (stream, target) + + def makeMakeFile (self, target): + stream = StringIO () + stream.write ("# Generated makefile fragment.\n\n") + stream.write ("mgen_generator=$(mgen_dir)/main.py \\\n") + stream.write (" $(mgen_dir)/generate.py \\\n") + stream.write (" $(mgen_dir)/schema.py \\\n") + stream.write (" $(top_srcdir)/../specs/management-types.xml \\\n") + stream.write (" $(top_srcdir)/../specs/management-schema.xml \\\n ") + first = 1 + for template in self.templateFiles: + if first == 1: + first = 0 + else: + stream.write (" \\\n ") + stream.write ("$(mgen_dir)/templates/" + template) + + stream.write ("\n\nmgen_broker_cpp=") + first = 1 + for file in self.filelists["cpp"]: + if first == 1: + first = 0 + else: + stream.write (" \\\n ") + stream.write (file.replace ("../src", ".")) + stream.write ("\n\n") + + stream.write ("# Header file install rules.\n") + stream.write ("qpid_managementdir = $(includedir)/qpid/management\n") + stream.write ("dist_qpid_management_HEADERS = ") + first = 1 + for file in self.filelists["h"]: + if first == 1: + first = 0 + else: + stream.write (" \\\n ") + stream.write (file.replace ("../src", ".")) + stream.write ("\n\n") + + stream.write ("if GENERATE\n") + stream.write ("$(srcdir)/managementgen.mk: $(mgen_generator)\n") + stream.write ("\t$(mgen_cmd)\n") + stream.write ("\n$(mgen_generator):\n") + stream.write ("endif\n") + + self.writeIfChanged (stream, target, force=True) diff --git a/qpid/cpp/managementgen/main.py b/qpid/cpp/managementgen/main.py new file mode 100755 index 0000000000..2f70639482 --- /dev/null +++ b/qpid/cpp/managementgen/main.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python + +# +# 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. +# + +from schema import PackageSchema, SchemaClass +from generate import Generator +from optparse import OptionParser + +# Set command line options +parser = OptionParser () +parser.add_option ("-o", "--outDir", dest="outdir", metavar="DIR", + help="Destination directory for generated files") +parser.add_option ("-t", "--typeFile", dest="typefile", metavar="FILE", + help="Schema type document (XML file)") +parser.add_option ("-s", "--schemaFile", dest="schemafile", metavar="FILE", + help="Schema defintion document (XML file)") +parser.add_option ("-i", "--templateDir", dest="templatedir", metavar="DIR", + help="Directory where template files can be found") +parser.add_option ("-m", "--makefile", dest="makefile", metavar="FILE", + help="Makefile fragment") + +(opts, args) = parser.parse_args () + +if opts.outdir == None or \ + opts.typefile == None or \ + opts.schemafile == None or \ + opts.templatedir == None or \ + opts.makefile == None: + parser.error ("Incorrect options, see --help for help") + +gen = Generator (opts.outdir, opts.templatedir) +schema = PackageSchema (opts.typefile, opts.schemafile) + +gen.makeClassFiles ("Class.h", schema) +gen.makeClassFiles ("Class.cpp", schema) +gen.makeMethodFiles ("Args.h", schema) +gen.makeMakeFile (opts.makefile) diff --git a/qpid/cpp/managementgen/schema.py b/qpid/cpp/managementgen/schema.py new file mode 100755 index 0000000000..c3db4eaf53 --- /dev/null +++ b/qpid/cpp/managementgen/schema.py @@ -0,0 +1,748 @@ +#!/usr/bin/env python + +# +# 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. +# + +from xml.dom.minidom import parse, parseString, Node +from cStringIO import StringIO + +#===================================================================================== +# +#===================================================================================== +class SchemaType: + def __init__ (self, node): + self.name = None + self.base = None + self.cpp = None + self.encode = None + self.decode = None + self.style = "normal" + self.accessor = None + self.init = "0" + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'base': + self.base = val + + elif key == 'cpp': + self.cpp = val + + elif key == 'encode': + self.encode = val + + elif key == 'decode': + self.decode = val + + elif key == 'style': + self.style = val + + elif key == 'accessor': + self.accessor = val + + elif key == 'init': + self.init = val + + else: + raise ValueError ("Unknown attribute in type '%s'" % key) + + if self.name == None or self.base == None or self.cpp == None or \ + self.encode == None or self.decode == None: + raise ValueError ("Missing required attribute(s) in type") + + def getName (self): + return self.name + + def genAccessor (self, stream, varName, changeFlag = None): + if self.accessor == "direct": + stream.write (" inline void set_" + varName + " (" + self.cpp + " val){\n"); + stream.write (" " + varName + " = val;\n"); + if self.style == "wm": + stream.write (" if (" + varName + "Low > val)\n") + stream.write (" " + varName + "Low = val;\n"); + stream.write (" if (" + varName + "High < val)\n") + stream.write (" " + varName + "High = val;\n"); + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + elif self.accessor == "counter": + stream.write (" inline void inc_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" " + varName + " += by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "High < " + varName + ")\n") + stream.write (" " + varName + "High = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + stream.write (" inline void dec_" + varName + " (" + self.cpp + " by = 1){\n"); + stream.write (" " + varName + " -= by;\n") + if self.style == "wm": + stream.write (" if (" + varName + "Low > " + varName + ")\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + if changeFlag != None: + stream.write (" " + changeFlag + " = true;\n") + stream.write (" }\n"); + + def genHiLoStatResets (self, stream, varName): + if self.style == "wm": + stream.write (" " + varName + "High = " + varName + ";\n") + stream.write (" " + varName + "Low = " + varName + ";\n") + + def genWrite (self, stream, varName): + stream.write (" " + self.encode.replace ("@", "buf").replace ("#", varName) + ";\n") + if self.style == "wm": + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "High") + ";\n") + stream.write (" " + self.encode.replace ("@", "buf") \ + .replace ("#", varName + "Low") + ";\n") + + def getReadCode (self, varName, bufName): + result = self.decode.replace ("@", bufName).replace ("#", varName) + return result + + def getWriteCode (self, varName, bufName): + result = self.encode.replace ("@", bufName).replace ("#", varName) + return result + +#===================================================================================== +# +#===================================================================================== +class TypeSpec: + def __init__ (self, file): + self.types = {} + dom = parse (file) + document = dom.documentElement + if document.tagName != 'schema-types': + raise ValueError ("Expected 'schema-types' in type file") + + for child in document.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'type': + stype = SchemaType (child) + self.types[stype.getName ()] = stype + else: + raise ValueError ("Unknown type tag '%s'" % child.nodeName) + + def getType (self, name): + return self.types[name] + + +#===================================================================================== +# +#===================================================================================== +class Type: + def __init__ (self, name, typespec): + self.type = typespec.getType (name) + +#===================================================================================== +# +#===================================================================================== +class SchemaConfig: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.access = "RO" + self.isIndex = 0 + self.isParentRef = 0 + self.unit = None + self.min = None + self.max = None + self.maxLen = None + self.desc = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'access': + self.access = val + + elif key == 'index': + if val != 'y': + raise ValueError ("Expected 'y' in index attribute") + self.isIndex = 1 + + elif key == 'parentRef': + if val != 'y': + raise ValueError ("Expected 'y' in parentRef attribute") + self.isParentRef = 1 + + elif key == 'unit': + self.unit = val + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in configElement '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in configElement") + if self.type == None: + raise ValueError ("Missing 'type' attribute in configElement") + + def getName (self): + return self.name + + def isConstructorArg (self): + if self.access == "RC" and self.isParentRef == 0: + return 1 + return 0 + + def genDeclaration (self, stream): + stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") + + def genFormalParam (self, stream): + stream.write (self.type.type.cpp + " _" + self.name) + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "configChanged") + + def genSchema (self, stream): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + self.name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + stream.write (" ft.setInt (ACCESS, ACCESS_" + self.access + ");\n") + stream.write (" ft.setInt (INDEX, " + str (self.isIndex) + ");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if self.min != None: + stream.write (" ft.setInt (MIN, " + self.min + ");\n") + if self.max != None: + stream.write (" ft.setInt (MAX, " + self.max + ");\n") + if self.maxLen != None: + stream.write (" ft.setInt (MAXLEN, " + self.maxLen + ");\n") + if self.desc != None: + stream.write (" ft.setString (DESC, \"" + self.desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genWrite (self, stream): + self.type.type.genWrite (stream, self.name) + + +#===================================================================================== +# +#===================================================================================== +class SchemaInst: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.desc = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in instElement '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in instElement") + if self.type == None: + raise ValueError ("Missing 'type' attribute in instElement") + + def getName (self): + return self.name + + def genDeclaration (self, stream): + stream.write (" " + self.type.type.cpp + " " + self.name + ";\n") + if self.type.type.style == 'wm': + stream.write (" " + self.type.type.cpp + " " + self.name + "High;\n") + stream.write (" " + self.type.type.cpp + " " + self.name + "Low;\n") + + def genAccessor (self, stream): + self.type.type.genAccessor (stream, self.name, "instChanged") + + def genHiLoStatResets (self, stream): + self.type.type.genHiLoStatResets (stream, self.name) + + def genSchemaText (self, stream, name, desc): + stream.write (" ft = FieldTable ();\n") + stream.write (" ft.setString (NAME, \"" + name + "\");\n") + stream.write (" ft.setInt (TYPE, TYPE_" + self.type.type.base +");\n") + if self.unit != None: + stream.write (" ft.setString (UNIT, \"" + self.unit + "\");\n") + if desc != None: + stream.write (" ft.setString (DESC, \"" + desc + "\");\n") + stream.write (" buf.put (ft);\n\n") + + def genSchema (self, stream): + self.genSchemaText (stream, self.name, self.desc) + if self.type.type.style == "wm": + descHigh = self.desc + descLow = self.desc + if self.desc != None: + descHigh = descHigh + " (High)" + descLow = descLow + " (Low)" + self.genSchemaText (stream, self.name + "High", descHigh) + self.genSchemaText (stream, self.name + "Low", descLow) + + def genWrite (self, stream): + self.type.type.genWrite (stream, self.name) + + def genInitialize (self, stream): + val = self.type.type.init + stream.write (" " + self.name + " = " + val + ";\n") + if self.type.type.style == "wm": + stream.write (" " + self.name + "High = " + val + ";\n") + stream.write (" " + self.name + "Low = " + val + ";\n") + + +#===================================================================================== +# +#===================================================================================== +class SchemaArg: + def __init__ (self, node, typespec): + self.name = None + self.type = None + self.unit = None + self.dir = "I" + self.min = None + self.max = None + self.maxLen = None + self.desc = None + self.default = None + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'type': + self.type = Type (val, typespec) + + elif key == 'unit': + self.unit = val + + elif key == 'dir': + self.dir = val.upper () + + elif key == 'min': + self.min = val + + elif key == 'max': + self.max = val + + elif key == 'maxlen': + self.maxLen = val + + elif key == 'desc': + self.desc = val + + elif key == 'default': + self.default = val + + else: + raise ValueError ("Unknown attribute in arg '%s'" % key) + + if self.name == None: + raise ValueError ("Missing 'name' attribute in arg") + if self.type == None: + raise ValueError ("Missing 'type' attribute in arg") + + def getName (self): + return self.name + + def getDir (self): + return self.dir + + +#===================================================================================== +# +#===================================================================================== +class SchemaMethod: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in method '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown method tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return self.parent.getName().capitalize() + self.name[0:1].upper() +\ + self.name[1:] + + def getArgCount (self): + return len (self.args) + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def genNameUpper (self, stream): + stream.write (self.getFullName ().upper ()) + + def genNameCamel (self, stream): + stream.write (self.getFullName ()) + + def genArguments (self, stream): + for arg in self.args: + ctype = arg.type.type.cpp + dirTag = arg.dir.lower() + "_" + stream.write (" " + ctype + " " + dirTag + arg.getName () + ";\n") + +#===================================================================================== +# +#===================================================================================== +class SchemaEvent: + def __init__ (self, parent, node, typespec): + self.parent = parent + self.name = None + self.desc = None + self.args = [] + + attrs = node.attributes + for idx in range (attrs.length): + key = attrs.item(idx).nodeName + val = attrs.item(idx).nodeValue + if key == 'name': + self.name = val + + elif key == 'desc': + self.desc = val + + else: + raise ValueError ("Unknown attribute in event '%s'" % key) + + for child in node.childNodes: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'arg': + arg = SchemaArg (child, typespec) + self.args.append (arg) + else: + raise ValueError ("Unknown event tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getFullName (self): + return self.parent.getName ().capitalize() + self.name.capitalize () + + def getArgCount (self): + return len (self.args) + +#===================================================================================== +# +#===================================================================================== +class SchemaClass: + def __init__ (self, node, typespec): + self.configElements = [] + self.instElements = [] + self.methods = [] + self.events = [] + + attrs = node.attributes + self.name = attrs['name'].nodeValue + + children = node.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'configElement': + sub = SchemaConfig (child, typespec) + self.configElements.append (sub) + + elif child.nodeName == 'instElement': + sub = SchemaInst (child, typespec) + self.instElements.append (sub) + + elif child.nodeName == 'method': + sub = SchemaMethod (self, child, typespec) + self.methods.append (sub) + + elif child.nodeName == 'event': + sub = SchemaEvent (self, child, typespec) + self.events.append (sub) + + else: + raise ValueError ("Unknown class tag '%s'" % child.nodeName) + + def getName (self): + return self.name + + def getMethods (self): + return self.methods + + def getEvents (self): + return self.events + + #=================================================================================== + # Code Generation Functions. The names of these functions (minus the leading "gen") + # match the substitution keywords in the template files. + #=================================================================================== + def genAccessorMethods (self, stream): + for config in self.configElements: + if config.access != "RC": + config.genAccessor (stream) + for inst in self.instElements: + inst.genAccessor (stream) + + def genArgDeclaration (self, stream): + argsFound = 0 + for method in self.methods: + argsFound = argsFound + len (method.args) + for event in self.events: + argsFound = argsFound + len (event.args) + if argsFound > 0: + stream.write ("FieldTable arg;"); + + def genConfigCount (self, stream): + stream.write ("%d" % len (self.configElements)) + + def genConfigDeclarations (self, stream): + for element in self.configElements: + element.genDeclaration (stream) + + def genConfigElementSchema (self, stream): + for config in self.configElements: + config.genSchema (stream) + + def genConstructorArgs (self, stream): + # Constructor args are config elements with read-create access + result = "" + first = 1 + for element in self.configElements: + if element.isConstructorArg (): + if first == 1: + first = 0 + else: + stream.write (", ") + element.genFormalParam (stream) + + def genConstructorInits (self, stream): + for element in self.configElements: + if element.isConstructorArg (): + stream.write ("," + element.getName () + "(_" + element.getName () + ")") + + def genDoMethodArgs (self, stream): + methodCount = 0 + inArgCount = 0 + for method in self.methods: + methodCount = methodCount + 1 + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + inArgCount = inArgCount + 1 + + if methodCount == 0: + stream.write ("string, Buffer&, Buffer& outBuf") + else: + if inArgCount == 0: + stream.write ("string methodName, Buffer&, Buffer& outBuf") + else: + stream.write ("string methodName, Buffer& inBuf, Buffer& outBuf") + + def genEventCount (self, stream): + stream.write ("%d" % len (self.events)) + + def genEventSchema (self, stream): + pass ########################################################################### + + def genHiLoStatResets (self, stream): + for inst in self.instElements: + inst.genHiLoStatResets (stream) + + def genInitializeElements (self, stream): + for inst in self.instElements: + inst.genInitialize (stream) + + def genInstChangedStub (self, stream): + if len (self.instElements) == 0: + stream.write (" // Stub for getInstChanged. There are no inst elements\n") + stream.write (" bool getInstChanged (void) { return false; }\n") + + def genInstCount (self, stream): + count = 0 + for inst in self.instElements: + count = count + 1 + if inst.type.type.style == "wm": + count = count + 2 + stream.write ("%d" % count) + + def genInstDeclarations (self, stream): + for element in self.instElements: + element.genDeclaration (stream) + + def genInstElementSchema (self, stream): + for inst in self.instElements: + inst.genSchema (stream) + + def genMethodArgIncludes (self, stream): + for method in self.methods: + if method.getArgCount () > 0: + stream.write ("#include \"qpid/management/Args" +\ + method.getFullName () + ".h\"\n") + + def genMethodCount (self, stream): + stream.write ("%d" % len (self.methods)) + + def genMethodHandlers (self, stream): + for method in self.methods: + stream.write ("\n if (methodName == \"" + method.getName () + "\")\n {\n") + if method.getArgCount () == 0: + stream.write (" ArgsNone ioArgs;\n") + else: + stream.write (" Args" + method.getFullName () + " ioArgs;\n") + for arg in method.args: + if arg.getDir () == "I" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getReadCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "inBuf") + ";\n") + + stream.write (" status = coreObject->ManagementMethod (METHOD_" +\ + method.getName().upper() + ", ioArgs);\n") + stream.write (" outBuf.putLong (status);\n") + stream.write (" outBuf.putShortString (Manageable::StatusText (status));\n") + for arg in method.args: + if arg.getDir () == "O" or arg.getDir () == "IO": + stream.write (" " +\ + arg.type.type.getWriteCode ("ioArgs." +\ + arg.dir.lower () + "_" +\ + arg.name, "outBuf") + ";\n") + stream.write (" return;\n }\n") + + + def genMethodIdDeclarations (self, stream): + number = 1 + for method in self.methods: + stream.write (" static const uint32_t METHOD_" + method.getName().upper() +\ + " = %d;\n" % number) + number = number + 1 + + def genMethodSchema (self, stream): + pass ########################################################################### + + def genNameCap (self, stream): + stream.write (self.name.capitalize ()) + + def genNameLower (self, stream): + stream.write (self.name.lower ()) + + def genNameUpper (self, stream): + stream.write (self.name.upper ()) + + def genParentArg (self, stream): + for config in self.configElements: + if config.isParentRef == 1: + stream.write (" _parent") + return + + def genParentRefAssignment (self, stream): + for config in self.configElements: + if config.isParentRef == 1: + stream.write (config.getName () + \ + " = _parent->GetManagementObject ()->getObjectId ();") + return + + def genWriteConfig (self, stream): + for config in self.configElements: + config.genWrite (stream); + + def genWriteInst (self, stream): + for inst in self.instElements: + inst.genWrite (stream); + + +#===================================================================================== +# +#===================================================================================== +class PackageSchema: + def __init__ (self, typefile, schemafile): + + self.classes = [] + self.typespec = TypeSpec (typefile) + + dom = parse (schemafile) + document = dom.documentElement + if document.tagName != 'schema': + raise ValueError ("Expected 'schema' node") + attrs = document.attributes + self.packageName = attrs['package'].nodeValue + + children = document.childNodes + for child in children: + if child.nodeType == Node.ELEMENT_NODE: + if child.nodeName == 'class': + cls = SchemaClass (child, self.typespec) + self.classes.append (cls) + else: + raise ValueError ("Unknown schema tag '%s'" % child.nodeName) + + def getPackageName (self): + return self.packageName + + def getClasses (self): + return self.classes diff --git a/qpid/cpp/src/qpid/management/ArgsBrokerEcho.h b/qpid/cpp/managementgen/templates/Args.h index ad9d7e0813..4a6413ddc9 100644 --- a/qpid/cpp/src/qpid/management/ArgsBrokerEcho.h +++ b/qpid/cpp/managementgen/templates/Args.h @@ -1,5 +1,5 @@ -#ifndef _ArgsBrokerEcho_ -#define _ArgsBrokerEcho_ +#ifndef _ARGS_/*MGEN:Method.NameUpper*/_ +#define _ARGS_/*MGEN:Method.NameUpper*/_ // // Licensed to the Apache Software Foundation (ASF) under one @@ -20,19 +20,20 @@ // under the License. // -#include "Args.h" +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/Args.h" #include <string> namespace qpid { namespace management { -class ArgsBrokerEcho : public Args +class Args/*MGEN:Method.NameCamel*/ : public Args { public: - uint32_t io_sequence; - std::string io_body; +/*MGEN:Method.Arguments*/ }; }} -#endif /*!_ArgsBrokerEcho_*/ +#endif /*!_ARGS_/*MGEN:Method.NameUpper*/_*/ diff --git a/qpid/cpp/managementgen/templates/Class.cpp b/qpid/cpp/managementgen/templates/Class.cpp new file mode 100644 index 0000000000..70077d495c --- /dev/null +++ b/qpid/cpp/managementgen/templates/Class.cpp @@ -0,0 +1,108 @@ +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/log/Statement.h" +#include "qpid/framing/FieldTable.h" +#include "qpid/management/Manageable.h" +#include "/*MGEN:Class.NameCap*/.h" +/*MGEN:Class.MethodArgIncludes*/ + +using namespace qpid::management; +using namespace qpid::sys; +using namespace qpid::framing; +using std::string; + +bool /*MGEN:Class.NameCap*/::schemaNeeded = true; + +/*MGEN:Class.NameCap*/::/*MGEN:Class.NameCap*/ (Manageable* _core, Manageable*/*MGEN:Class.ParentArg*/, + /*MGEN:Class.ConstructorArgs*/) : + ManagementObject(_core, "/*MGEN:Class.NameLower*/") + /*MGEN:Class.ConstructorInits*/ +{ + /*MGEN:Class.ParentRefAssignment*/ +/*MGEN:Class.InitializeElements*/ +} + +/*MGEN:Class.NameCap*/::~/*MGEN:Class.NameCap*/ () {} + +namespace { + const string NAME("name"); + const string TYPE("type"); + const string ACCESS("access"); + const string INDEX("index"); + const string UNIT("unit"); + const string MIN("min"); + const string MAX("max"); + const string MAXLEN("maxlen"); + const string DESC("desc"); +} + +void /*MGEN:Class.NameCap*/::writeSchema (Buffer& buf) +{ + FieldTable ft; + /*MGEN:Class.ArgDeclaration*/ + + schemaNeeded = false; + + // Schema class header: + buf.putShortString (className); // Class Name + buf.putShort (/*MGEN:Class.ConfigCount*/); // Config Element Count + buf.putShort (/*MGEN:Class.InstCount*/); // Inst Element Count + buf.putShort (/*MGEN:Class.MethodCount*/); // Method Count + buf.putShort (/*MGEN:Class.EventCount*/); // Event Count + + // Config Elements +/*MGEN:Class.ConfigElementSchema*/ + // Inst Elements +/*MGEN:Class.InstElementSchema*/ + // Methods +/*MGEN:Class.MethodSchema*/ + // Events +/*MGEN:Class.EventSchema*/ +} + +void /*MGEN:Class.NameCap*/::writeConfig (Buffer& buf) +{ + configChanged = false; + + writeTimestamps (buf); +/*MGEN:Class.WriteConfig*/ +} + +void /*MGEN:Class.NameCap*/::writeInstrumentation (Buffer& buf) +{ + instChanged = false; + + writeTimestamps (buf); +/*MGEN:Class.WriteInst*/ + + // Maintenance of hi-lo statistics +/*MGEN:Class.HiLoStatResets*/ +} + +void /*MGEN:Class.NameCap*/::doMethod (/*MGEN:Class.DoMethodArgs*/) +{ + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; +/*MGEN:Class.MethodHandlers*/ + outBuf.putLong (status); + outBuf.putShortString (Manageable::StatusText (status)); +} + diff --git a/qpid/cpp/managementgen/templates/Class.h b/qpid/cpp/managementgen/templates/Class.h new file mode 100644 index 0000000000..cff915412e --- /dev/null +++ b/qpid/cpp/managementgen/templates/Class.h @@ -0,0 +1,69 @@ +#ifndef _MANAGEMENT_/*MGEN:Class.NameUpper*/_ +#define _MANAGEMENT_/*MGEN:Class.NameUpper*/_ + +// +// 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. +// + +/*MGEN:Root.Disclaimer*/ + +#include "qpid/management/ManagementObject.h" + +namespace qpid { +namespace management { + +class /*MGEN:Class.NameCap*/ : public ManagementObject +{ + private: + + static bool schemaNeeded; + + // Configuration Elements +/*MGEN:Class.ConfigDeclarations*/ + // Instrumentation Elements +/*MGEN:Class.InstDeclarations*/ + // Private Methods + std::string getObjectName (void) { return "/*MGEN:Class.NameLower*/"; } + void writeSchema (qpid::framing::Buffer& buf); + void writeConfig (qpid::framing::Buffer& buf); + void writeInstrumentation (qpid::framing::Buffer& buf); + bool getSchemaNeeded (void) { return schemaNeeded; } + void setSchemaNeeded (void) { schemaNeeded = true; } + void doMethod (std::string methodName, + qpid::framing::Buffer& inBuf, + qpid::framing::Buffer& outBuf); + +/*MGEN:Class.InstChangedStub*/ + public: + + typedef boost::shared_ptr</*MGEN:Class.NameCap*/> shared_ptr; + + /*MGEN:Class.NameCap*/ (Manageable* coreObject, Manageable* parentObject, + /*MGEN:Class.ConstructorArgs*/); + ~/*MGEN:Class.NameCap*/ (void); + + // Method IDs +/*MGEN:Class.MethodIdDeclarations*/ + // Accessor Methods +/*MGEN:Class.AccessorMethods*/ +}; + +}} + + +#endif /*!_MANAGEMENT_/*MGEN:Class.NameUpper*/_*/ diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am index 5c75fc7ce6..b3c6b8a13d 100644 --- a/qpid/cpp/src/Makefile.am +++ b/qpid/cpp/src/Makefile.am @@ -20,11 +20,19 @@ if GENERATE rgen_dir=$(top_srcdir)/rubygen rgen_cmd=ruby -I $(rgen_dir) $(rgen_dir)/generate $(srcdir)/gen $(specs) all $(srcdir)/rubygen.mk +# Management generator. +mgen_dir=$(top_srcdir)/managementgen +mgen_cmd=$(mgen_dir)/main.py -o $(srcdir)/gen/qpid/management \ + -t $(top_srcdir)/../specs/management-types.xml \ + -s $(top_srcdir)/../specs/management-schema.xml \ + -i $(mgen_dir)/templates -m $(srcdir)/managementgen.mk + endif # GENERATE include $(srcdir)/rubygen.mk +include $(srcdir)/managementgen.mk -DISTCLEANFILES=rubygen.mk +DISTCLEANFILES=rubygen.mk managementgen.mk # Code generated by C++ noinst_PROGRAMS=generate_MaxMethodBodySize_h @@ -137,6 +145,7 @@ libqpidcommon_la_SOURCES = \ libqpidbroker_la_LIBADD = libqpidcommon.la -lboost_iostreams libqpidbroker_la_SOURCES = \ + $(mgen_broker_cpp) \ qpid/broker/Broker.cpp \ qpid/broker/BrokerAdapter.cpp \ qpid/broker/BrokerSingleton.cpp \ @@ -189,12 +198,10 @@ libqpidbroker_la_SOURCES = \ qpid/broker/TxBuffer.cpp \ qpid/broker/TxPublish.cpp \ qpid/broker/Vhost.cpp \ - qpid/management/Broker.cpp \ + qpid/management/Manageable.cpp \ qpid/management/ManagementAgent.cpp \ qpid/management/ManagementExchange.cpp \ - qpid/management/ManagementObject.cpp \ - qpid/management/Queue.cpp \ - qpid/management/Vhost.cpp + qpid/management/ManagementObject.cpp libqpidclient_la_LIBADD = libqpidcommon.la libqpidclient_la_SOURCES = \ @@ -383,15 +390,11 @@ nobase_include_HEADERS = \ qpid/log/Options.h \ qpid/log/Selector.h \ qpid/log/Statement.h \ - qpid/management/ArgsBrokerEcho.h \ qpid/management/Args.h \ - qpid/management/Broker.h \ qpid/management/Manageable.h \ qpid/management/ManagementAgent.h \ qpid/management/ManagementExchange.h \ qpid/management/ManagementObject.h \ - qpid/management/Queue.h \ - qpid/management/Vhost.h \ qpid/sys/Acceptor.h \ qpid/sys/AsynchIO.h \ qpid/sys/AtomicCount.h \ diff --git a/qpid/cpp/src/qpid/broker/Broker.cpp b/qpid/cpp/src/qpid/broker/Broker.cpp index d61100d255..4e22cb7352 100644 --- a/qpid/cpp/src/qpid/broker/Broker.cpp +++ b/qpid/cpp/src/qpid/broker/Broker.cpp @@ -19,6 +19,7 @@ * */ +#include "config.h" #include "Broker.h" #include "Connection.h" #include "DirectExchange.h" @@ -124,7 +125,19 @@ Broker::Broker(const Broker::Options& conf) : managementAgent = ManagementAgent::getAgent (); managementAgent->setInterval (conf.mgmtPubInterval); - mgmtObject = management::Broker::shared_ptr (new management::Broker (this, conf)); + mgmtObject = management::Broker::shared_ptr (new management::Broker (this, 0, 0, conf.port)); + mgmtObject->set_workerThreads (conf.workerThreads); + mgmtObject->set_maxConns (conf.maxConnections); + mgmtObject->set_connBacklog (conf.connectionBacklog); + mgmtObject->set_stagingThreshold (conf.stagingThreshold); + mgmtObject->set_storeLib (conf.store); + mgmtObject->set_asyncStore (conf.storeAsync); + mgmtObject->set_mgmtPubInterval (conf.mgmtPubInterval); + mgmtObject->set_initialDiskPageSize (0); + mgmtObject->set_initialPagesPerQueue (0); + mgmtObject->set_clusterName (""); + mgmtObject->set_version (PACKAGE_VERSION); + managementAgent->addObject (mgmtObject); // Since there is currently no support for virtual hosts, a placeholder object @@ -248,11 +261,27 @@ ManagementObject::shared_ptr Broker::GetManagementObject(void) const return dynamic_pointer_cast<ManagementObject> (mgmtObject); } -Manageable::status_t Broker::ManagementMethod (uint32_t /*methodId*/, +Manageable::status_t Broker::ManagementMethod (uint32_t methodId, Args& /*_args*/) { - QPID_LOG (debug, "Broker::ManagementMethod"); - return Manageable::STATUS_OK; + Manageable::status_t status = Manageable::STATUS_UNKNOWN_METHOD; + + QPID_LOG (debug, "Broker::ManagementMethod [id=" << methodId << "]"); + + switch (methodId) + { + case management::Broker::METHOD_ECHO : + status = Manageable::STATUS_OK; + break; + + case management::Broker::METHOD_JOINCLUSTER : + case management::Broker::METHOD_LEAVECLUSTER : + case management::Broker::METHOD_CRASH : + status = Manageable::STATUS_NOT_IMPLEMENTED; + break; + } + + return status; } }} // namespace qpid::broker diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp index 41a5767457..376b9367d0 100644 --- a/qpid/cpp/src/qpid/broker/Queue.cpp +++ b/qpid/cpp/src/qpid/broker/Queue.cpp @@ -58,7 +58,7 @@ Queue::Queue(const string& _name, bool _autodelete, if (parent != 0) { mgmtObject = management::Queue::shared_ptr - (new management::Queue (this, parent, _name, _store != 0, _autodelete)); + (new management::Queue (this, parent, _name, _store != 0, _autodelete, 0)); ManagementAgent::shared_ptr agent = ManagementAgent::getAgent (); agent->addObject (mgmtObject); @@ -92,11 +92,21 @@ void Queue::deliver(intrusive_ptr<Message>& msg){ if (!enqueue(0, msg)){ push(msg); msg->enqueueComplete(); - if (mgmtObject != 0) - mgmtObject->enqueue (msg->contentSize ()); + if (mgmtObject != 0) { + mgmtObject->inc_msgTotalEnqueues (); + mgmtObject->inc_byteTotalEnqueues (msg->contentSize ()); + mgmtObject->inc_msgDepth (); + mgmtObject->inc_byteDepth (msg->contentSize ()); + } }else { - if (mgmtObject != 0) - mgmtObject->enqueue (msg->contentSize (), management::MSG_MASK_PERSIST); + if (mgmtObject != 0) { + mgmtObject->inc_msgTotalEnqueues (); + mgmtObject->inc_byteTotalEnqueues (msg->contentSize ()); + mgmtObject->inc_msgDepth (); + mgmtObject->inc_byteDepth (msg->contentSize ()); + mgmtObject->inc_msgPersistEnqueues (); + mgmtObject->inc_bytePersistEnqueues (msg->contentSize ()); + } push(msg); } QPID_LOG(debug, "Message " << msg << " enqueued on " << name << "[" << this << "]"); @@ -108,8 +118,15 @@ void Queue::deliver(intrusive_ptr<Message>& msg){ void Queue::recover(intrusive_ptr<Message>& msg){ push(msg); msg->enqueueComplete(); // mark the message as enqueued - if (mgmtObject != 0) - mgmtObject->enqueue (msg->contentSize (), management::MSG_MASK_PERSIST); + if (mgmtObject != 0) { + mgmtObject->inc_msgTotalEnqueues (); + mgmtObject->inc_byteTotalEnqueues (msg->contentSize ()); + mgmtObject->inc_msgPersistEnqueues (); + mgmtObject->inc_bytePersistEnqueues (msg->contentSize ()); + mgmtObject->inc_msgDepth (); + mgmtObject->inc_byteDepth (msg->contentSize ()); + } + if (store && !msg->isContentLoaded()) { //content has not been loaded, need to ensure that lazy loading mode is set: //TODO: find a nicer way to do this @@ -118,15 +135,19 @@ void Queue::recover(intrusive_ptr<Message>& msg){ } void Queue::process(intrusive_ptr<Message>& msg){ - - uint32_t mask = management::MSG_MASK_TX; - - if (msg->isPersistent ()) - mask |= management::MSG_MASK_PERSIST; - push(msg); - if (mgmtObject != 0) - mgmtObject->enqueue (msg->contentSize (), mask); + if (mgmtObject != 0) { + mgmtObject->inc_msgTotalEnqueues (); + mgmtObject->inc_byteTotalEnqueues (msg->contentSize ()); + mgmtObject->inc_msgTxnEnqueues (); + mgmtObject->inc_byteTxnEnqueues (msg->contentSize ()); + mgmtObject->inc_msgDepth (); + mgmtObject->inc_byteDepth (msg->contentSize ()); + if (msg->isPersistent ()) { + mgmtObject->inc_msgPersistEnqueues (); + mgmtObject->inc_bytePersistEnqueues (msg->contentSize ()); + } + } serializer.execute(dispatchCallback); } @@ -309,7 +330,7 @@ void Queue::consume(Consumer::ptr c, bool requestExclusive){ } if (mgmtObject != 0){ - mgmtObject->incConsumers (); + mgmtObject->inc_consumers (); } } @@ -321,7 +342,7 @@ void Queue::cancel(Consumer::ptr c){ cancel(c, browsers); } if (mgmtObject != 0){ - mgmtObject->decConsumers (); + mgmtObject->dec_consumers (); } if(exclusive == c) exclusive.reset(); } @@ -341,12 +362,14 @@ QueuedMessage Queue::dequeue(){ msg = messages.front(); pop(); if (mgmtObject != 0){ - uint32_t mask = 0; - - if (msg.payload->isPersistent ()) - mask |= management::MSG_MASK_PERSIST; - - mgmtObject->dequeue (msg.payload->contentSize (), mask); + mgmtObject->inc_msgTotalDequeues (); + //mgmtObject->inc_byteTotalDequeues (msg->contentSize ()); + mgmtObject->dec_msgDepth (); + //mgmtObject->dec_byteDepth (msg->contentSize ()); + if (0){//msg->isPersistent ()) { + mgmtObject->inc_msgPersistDequeues (); + //mgmtObject->inc_bytePersistDequeues (msg->contentSize ()); + } } } return msg; diff --git a/qpid/cpp/src/qpid/broker/Vhost.cpp b/qpid/cpp/src/qpid/broker/Vhost.cpp index bf0521904f..635f345a86 100644 --- a/qpid/cpp/src/qpid/broker/Vhost.cpp +++ b/qpid/cpp/src/qpid/broker/Vhost.cpp @@ -28,7 +28,7 @@ Vhost::Vhost (management::Manageable* parentBroker) if (parentBroker != 0) { mgmtObject = management::Vhost::shared_ptr - (new management::Vhost (this, parentBroker)); + (new management::Vhost (this, parentBroker, "/")); ManagementAgent::shared_ptr agent = ManagementAgent::getAgent (); agent->addObject (mgmtObject); diff --git a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h index 524cfa1fec..96bd396330 100644 --- a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h +++ b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h @@ -62,7 +62,8 @@ class AMQHeaderBody : public AMQBody } void print(std::ostream& out) const { const boost::optional<T>& p=this->OptProps<T>::props; - Base::print(out << *p); + if (p) out << *p; + Base::print(out); } }; diff --git a/qpid/cpp/src/qpid/management/Args.h b/qpid/cpp/src/qpid/management/Args.h index 75d0b4dd70..da1fb033b9 100644 --- a/qpid/cpp/src/qpid/management/Args.h +++ b/qpid/cpp/src/qpid/management/Args.h @@ -34,6 +34,11 @@ class Args inline Args::~Args (void) {} +class ArgsNone : public Args +{ +}; + }} + #endif /*!_Args_*/ diff --git a/qpid/cpp/src/qpid/management/Broker.cpp b/qpid/cpp/src/qpid/management/Broker.cpp deleted file mode 100644 index 2c27512669..0000000000 --- a/qpid/cpp/src/qpid/management/Broker.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * - * 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 "config.h" -#include "qpid/broker/Broker.h" -#include "qpid/framing/FieldTable.h" -#include "Broker.h" -#include "ArgsBrokerEcho.h" - -using namespace qpid::management; -using namespace qpid::sys; -using namespace qpid::framing; - -bool Broker::schemaNeeded = true; - -Broker::Broker (Manageable* _core, const Options& _conf) : - ManagementObject (_core, "broker") -{ - broker::Broker::Options& conf = (broker::Broker::Options&) _conf; - - sysId = "sysId"; - port = conf.port; - workerThreads = conf.workerThreads; - maxConns = conf.maxConnections; - connBacklog = conf.connectionBacklog; - stagingThreshold = conf.stagingThreshold; - storeLib = conf.store; - asyncStore = conf.storeAsync; - mgmtPubInterval = conf.mgmtPubInterval; - initialDiskPageSize = 0; - initialPagesPerQueue = 0; - clusterName = ""; - version = PACKAGE_VERSION; -} - -Broker::~Broker () {} - -void Broker::writeSchema (Buffer& buf) -{ - FieldTable ft; - FieldTable arg; - - schemaNeeded = false; - - // Schema class header: - buf.putShortString (className); // Class Name - buf.putShort (13); // Config Element Count - buf.putShort (0); // Inst Element Count - buf.putShort (1); // Method Count - buf.putShort (0); // Event Count - - // Config Elements - ft = FieldTable (); - ft.setString ("name", "systemRef"); - ft.setInt ("type", TYPE_U64); - ft.setInt ("access", ACCESS_RC); - ft.setInt ("index", 1); - ft.setString ("desc", "System ID"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "port"); - ft.setInt ("type", TYPE_U16); - ft.setInt ("access", ACCESS_RC); - ft.setInt ("index", 1); - ft.setString ("desc", "TCP Port for AMQP Service"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "workerThreads"); - ft.setInt ("type", TYPE_U16); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Thread pool size"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "maxConns"); - ft.setInt ("type", TYPE_U16); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Maximum allowed connections"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "connBacklog"); - ft.setInt ("type", TYPE_U16); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Connection backlog limit for listening socket"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "stagingThreshold"); - ft.setInt ("type", TYPE_U32); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Broker stages messages over this size to disk"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "storeLib"); - ft.setInt ("type", TYPE_SSTR); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Name of persistent storage library"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "asyncStore"); - ft.setInt ("type", TYPE_U8); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Use async persistent store"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "mgmtPubInterval"); - ft.setInt ("type", TYPE_U16); - ft.setInt ("access", ACCESS_RW); - ft.setInt ("index", 0); - ft.setInt ("min", 1); - ft.setString ("unit", "second"); - ft.setString ("desc", "Interval for management broadcasts"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "initialDiskPageSize"); - ft.setInt ("type", TYPE_U32); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Number of disk pages allocated for storage"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "initialPagesPerQueue"); - ft.setInt ("type", TYPE_U32); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Number of disk pages allocated per queue"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "clusterName"); - ft.setInt ("type", TYPE_SSTR); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Name of cluster this server is a member of, zero-length for standalone server"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "version"); - ft.setInt ("type", TYPE_SSTR); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Running software version"); - buf.put (ft); - - // Inst Elements - - return; // TODO - Remove - - // Methods - ft = FieldTable (); - ft.setString ("name", "echo"); - ft.setInt ("args", 2); - - arg = FieldTable (); - arg.setString ("name", "sequence"); - arg.setInt ("type", TYPE_U32); - arg.setInt ("dir", DIR_IO); - ft.setTable ("arg", arg); - - arg = FieldTable (); - arg.setString ("name", "body"); - arg.setInt ("type", TYPE_LSTR); - arg.setInt ("dir", DIR_IO); - ft.setTable ("arg", arg); - - buf.put (ft); - - // Events -} - -void Broker::writeConfig (Buffer& buf) -{ - configChanged = false; - - writeTimestamps (buf); - buf.putLongLong (0); - buf.putShort (port); - buf.putShort (workerThreads); - buf.putShort (maxConns); - buf.putShort (connBacklog); - buf.putLong (stagingThreshold); - buf.putShortString (storeLib); - buf.putOctet (asyncStore ? 1 : 0); - buf.putShort (mgmtPubInterval); - buf.putLong (initialDiskPageSize); - buf.putLong (initialPagesPerQueue); - buf.putShortString (clusterName); - buf.putShortString (version); -} - -void Broker::doMethod (string methodName, - Buffer& inBuf, - Buffer& outBuf) -{ - if (methodName.compare ("echo") == 0) - { - ArgsBrokerEcho args; - uint32_t result; - - args.io_sequence = inBuf.getLong (); - inBuf.getLongString (args.io_body); - - result = coreObject->ManagementMethod (1, args); - - outBuf.putLong (result); - outBuf.putShortString ("OK"); - outBuf.putLong (args.io_sequence); - outBuf.putLongString (args.io_body); - } - - // TODO - Remove this method prior to beta - else if (methodName.compare ("crash") == 0) - { - assert (0); - } - else - { - outBuf.putLong (1); - outBuf.putShortString ("Unknown Method"); - } -} - diff --git a/qpid/cpp/src/qpid/management/Broker.h b/qpid/cpp/src/qpid/management/Broker.h deleted file mode 100644 index 2a8ef153d1..0000000000 --- a/qpid/cpp/src/qpid/management/Broker.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef _ManagementBroker_ -#define _ManagementBroker_ - -/* - * - * 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 "ManagementObject.h" -#include "qpid/Options.h" -#include "boost/shared_ptr.hpp" - -namespace qpid { -namespace management { - -class Broker : public ManagementObject -{ - public: - - typedef boost::shared_ptr<Broker> shared_ptr; - - Broker (Manageable* coreObject, const Options& conf); - ~Broker (void); - - private: - - static bool schemaNeeded; - - std::string sysId; - uint16_t port; - uint16_t workerThreads; - uint16_t maxConns; - uint16_t connBacklog; - uint32_t stagingThreshold; - std::string storeLib; - bool asyncStore; - uint16_t mgmtPubInterval; - uint32_t initialDiskPageSize; - uint32_t initialPagesPerQueue; - std::string clusterName; - std::string version; - - void writeSchema (qpid::framing::Buffer& buf); - void writeConfig (qpid::framing::Buffer& buf); - void writeInstrumentation (qpid::framing::Buffer& /*buf*/) {} - bool getSchemaNeeded (void) { return schemaNeeded; } - void setSchemaNeeded (void) { schemaNeeded = true; } - void doMethod (std::string methodName, - qpid::framing::Buffer& inBuf, - qpid::framing::Buffer& outBuf); - - inline bool getInstChanged (void) { return false; } -}; - -}} - - -#endif /*!_ManagementBroker_*/ diff --git a/qpid/cpp/src/qpid/management/Manageable.cpp b/qpid/cpp/src/qpid/management/Manageable.cpp new file mode 100644 index 0000000000..c5adb22694 --- /dev/null +++ b/qpid/cpp/src/qpid/management/Manageable.cpp @@ -0,0 +1,36 @@ +// +// 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 "Manageable.h" + +using namespace qpid::management; + +std::string Manageable::StatusText (status_t status) +{ + switch (status) + { + case STATUS_OK : return "OK"; + case STATUS_UNKNOWN_OBJECT : return "UnknownObject"; + case STATUS_UNKNOWN_METHOD : return "UnknownMethod"; + case STATUS_NOT_IMPLEMENTED : return "NotImplemented"; + } + + return "??"; +} + diff --git a/qpid/cpp/src/qpid/management/Manageable.h b/qpid/cpp/src/qpid/management/Manageable.h index 7c9b49be9a..155b71da54 100644 --- a/qpid/cpp/src/qpid/management/Manageable.h +++ b/qpid/cpp/src/qpid/management/Manageable.h @@ -22,10 +22,7 @@ #include "ManagementObject.h" #include "Args.h" -#include "qpid/sys/Time.h" -#include <qpid/framing/Buffer.h> -#include <boost/shared_ptr.hpp> -#include <map> +#include <string> namespace qpid { namespace management { @@ -39,10 +36,12 @@ class Manageable // status_t is a type used to pass completion status from the method handler. // typedef uint32_t status_t; + static std::string StatusText (status_t status); static const status_t STATUS_OK = 0; static const status_t STATUS_UNKNOWN_OBJECT = 1; static const status_t STATUS_UNKNOWN_METHOD = 2; + static const status_t STATUS_NOT_IMPLEMENTED = 3; // Every "Manageable" object must hold a reference to exactly one // management object. This object is always of a class derived from diff --git a/qpid/cpp/src/qpid/management/ManagementAgent.cpp b/qpid/cpp/src/qpid/management/ManagementAgent.cpp index 7aad7e7ce1..fa51a6b82a 100644 --- a/qpid/cpp/src/qpid/management/ManagementAgent.cpp +++ b/qpid/cpp/src/qpid/management/ManagementAgent.cpp @@ -271,8 +271,8 @@ void ManagementAgent::dispatchCommand (Deliverable& deliverable, ManagementObjectMap::iterator iter = managementObjects.find (objId); if (iter == managementObjects.end ()) { - outBuffer.putLong (2); - outBuffer.putShortString ("Invalid Object Id"); + outBuffer.putLong (Manageable::STATUS_UNKNOWN_OBJECT); + outBuffer.putShortString (Manageable::StatusText (Manageable::STATUS_UNKNOWN_OBJECT)); } else { diff --git a/qpid/cpp/src/qpid/management/Queue.cpp b/qpid/cpp/src/qpid/management/Queue.cpp deleted file mode 100644 index b30ff2a6a7..0000000000 --- a/qpid/cpp/src/qpid/management/Queue.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - * - * 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/log/Statement.h" -#include "qpid/framing/FieldTable.h" -#include "Manageable.h" -#include "Queue.h" - -using namespace qpid::management; -using namespace qpid::sys; -using namespace qpid::framing; - -bool Queue::schemaNeeded = true; - -Queue::Queue (Manageable* _core, Manageable* _parent, - const std::string& _name, - bool _durable, bool _autoDelete) : - ManagementObject(_core, "queue"), name(_name), - durable(_durable), autoDelete(_autoDelete) -{ - vhostRef = _parent->GetManagementObject ()->getObjectId (); - - msgTotalEnqueues = 0; - msgTotalDequeues = 0; - msgTxEnqueues = 0; - msgTxDequeues = 0; - msgPersistEnqueues = 0; - msgPersistDequeues = 0; - - msgDepth = 0; - msgDepthLow = 0; - msgDepthHigh = 0; - - byteTotalEnqueues = 0; - byteTotalDequeues = 0; - byteTxEnqueues = 0; - byteTxDequeues = 0; - bytePersistEnqueues = 0; - bytePersistDequeues = 0; - - byteDepth = 0; - byteDepthLow = 0; - byteDepthHigh = 0; - - enqueueTxStarts = 0; - enqueueTxCommits = 0; - enqueueTxRejects = 0; - dequeueTxStarts = 0; - dequeueTxCommits = 0; - dequeueTxRejects = 0; - - enqueueTxCount = 0; - enqueueTxCountLow = 0; - enqueueTxCountHigh = 0; - - dequeueTxCount = 0; - dequeueTxCountLow = 0; - dequeueTxCountHigh = 0; - - consumers = 0; - consumersLow = 0; - consumersHigh = 0; -} - -Queue::~Queue () {} - -void Queue::writeSchema (Buffer& buf) -{ - FieldTable ft; - - schemaNeeded = false; - - // Schema class header: - buf.putShortString (className); // Class Name - buf.putShort (4); // Config Element Count - buf.putShort (33); // Inst Element Count - buf.putShort (0); // Method Count - buf.putShort (0); // Event Count - - // Config Elements - ft = FieldTable (); - ft.setString ("name", "vhostRef"); - ft.setInt ("type", TYPE_U64); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 1); - ft.setString ("desc", "Virtual Host Ref"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "name"); - ft.setInt ("type", TYPE_SSTR); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 1); - ft.setString ("desc", "Queue Name"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "durable"); - ft.setInt ("type", TYPE_U8); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "Durable"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "autoDelete"); - ft.setInt ("type", TYPE_U8); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 0); - ft.setString ("desc", "AutoDelete"); - buf.put (ft); - - // Inst Elements - ft = FieldTable (); - ft.setString ("name", "msgTotalEnqueues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total messages enqueued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgTotalDequeues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total messages dequeued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgTxnEnqueues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Transactional messages enqueued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgTxnDequeues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Transactional messages dequeued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgPersistEnqueues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Persistent messages enqueued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgPersistDequeues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Persistent messages dequeued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgDepth"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Current size of queue in messages"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgDepthLow"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Low-water queue size, this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "msgDepthHigh"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "High-water queue size, this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "byteTotalEnqueues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total messages enqueued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "byteTotalDequeues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total messages dequeued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "byteTxnEnqueues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Transactional messages enqueued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "byteTxnDequeues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Transactional messages dequeued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "bytePersistEnqueues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Persistent messages enqueued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "bytePersistDequeues"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Persistent messages dequeued"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "byteDepth"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Current size of queue in bytes"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "byteDepthLow"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Low-water mark this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "byteDepthHigh"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "High-water mark this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "enqueueTxnStarts"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total enqueue transactions started "); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "enqueueTxnCommits"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total enqueue transactions committed"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "enqueueTxnRejects"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total enqueue transactions rejected"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "enqueueTxnCount"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Current pending enqueue transactions"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "enqueueTxnCountLow"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Low water mark this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "enqueueTxnCountHigh"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "High water mark this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "dequeueTxnStarts"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total dequeue transactions started "); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "dequeueTxnCommits"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total dequeue transactions committed"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "dequeueTxnRejects"); - ft.setInt ("type", TYPE_U64); - ft.setString ("desc", "Total dequeue transactions rejected"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "dequeueTxnCount"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Current pending dequeue transactions"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "dequeueTxnCountLow"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Transaction low water mark this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "dequeueTxnCountHigh"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Transaction high water mark this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "consumers"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Current consumers on queue"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "consumersLow"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Consumer low water mark this interval"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "consumersHigh"); - ft.setInt ("type", TYPE_U32); - ft.setString ("desc", "Consumer high water mark this interval"); - buf.put (ft); -} - -void Queue::writeConfig (Buffer& buf) -{ - configChanged = false; - - writeTimestamps (buf); - buf.putLongLong (vhostRef); - buf.putShortString (name); - buf.putOctet (durable ? 1 : 0); - buf.putOctet (autoDelete ? 1 : 0); -} - -void Queue::writeInstrumentation (Buffer& buf) -{ - instChanged = false; - - writeTimestamps (buf); - buf.putLongLong (msgTotalEnqueues); - buf.putLongLong (msgTotalDequeues); - buf.putLongLong (msgTxEnqueues); - buf.putLongLong (msgTxDequeues); - buf.putLongLong (msgPersistEnqueues); - buf.putLongLong (msgPersistDequeues); - buf.putLong (msgDepth); - buf.putLong (msgDepthLow); - buf.putLong (msgDepthHigh); - buf.putLongLong (byteTotalEnqueues); - buf.putLongLong (byteTotalDequeues); - buf.putLongLong (byteTxEnqueues); - buf.putLongLong (byteTxDequeues); - buf.putLongLong (bytePersistEnqueues); - buf.putLongLong (bytePersistDequeues); - buf.putLong (byteDepth); - buf.putLong (byteDepthLow); - buf.putLong (byteDepthHigh); - buf.putLongLong (enqueueTxStarts); - buf.putLongLong (enqueueTxCommits); - buf.putLongLong (enqueueTxRejects); - buf.putLong (enqueueTxCount); - buf.putLong (enqueueTxCountLow); - buf.putLong (enqueueTxCountHigh); - buf.putLongLong (dequeueTxStarts); - buf.putLongLong (dequeueTxCommits); - buf.putLongLong (dequeueTxRejects); - buf.putLong (dequeueTxCount); - buf.putLong (dequeueTxCountLow); - buf.putLong (dequeueTxCountHigh); - buf.putLong (consumers); - buf.putLong (consumersLow); - buf.putLong (consumersHigh); - - msgDepthLow = msgDepth; - msgDepthHigh = msgDepth; - byteDepthLow = byteDepth; - byteDepthHigh = byteDepth; - enqueueTxCountLow = enqueueTxCount; - enqueueTxCountHigh = enqueueTxCount; - dequeueTxCountLow = dequeueTxCount; - dequeueTxCountHigh = dequeueTxCount; - consumersLow = consumers; - consumersHigh = consumers; -} diff --git a/qpid/cpp/src/qpid/management/Queue.h b/qpid/cpp/src/qpid/management/Queue.h deleted file mode 100644 index 2ed43e5576..0000000000 --- a/qpid/cpp/src/qpid/management/Queue.h +++ /dev/null @@ -1,182 +0,0 @@ -#ifndef _ManagementQueue_ -#define _ManagementQueue_ - -/* - * - * 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 "ManagementObject.h" - -namespace qpid { -namespace management { - -const uint32_t MSG_MASK_TX = 1; // Transactional message -const uint32_t MSG_MASK_PERSIST = 2; // Persistent message - -class Queue : public ManagementObject -{ - private: - - static bool schemaNeeded; - - uint64_t vhostRef; - std::string name; - bool durable; - bool autoDelete; - - uint64_t msgTotalEnqueues; // Total messages enqueued - uint64_t msgTotalDequeues; // Total messages dequeued - uint64_t msgTxEnqueues; // Transactional messages enqueued - uint64_t msgTxDequeues; // Transactional messages dequeued - uint64_t msgPersistEnqueues; // Persistent messages enqueued - uint64_t msgPersistDequeues; // Persistent messages dequeued - - uint32_t msgDepth; // Current size of queue in messages - uint32_t msgDepthLow; // Low-water queue size, this interval - uint32_t msgDepthHigh; // High-water queue size, this interval - - uint64_t byteTotalEnqueues; // Total messages enqueued - uint64_t byteTotalDequeues; // Total messages dequeued - uint64_t byteTxEnqueues; // Transactional messages enqueued - uint64_t byteTxDequeues; // Transactional messages dequeued - uint64_t bytePersistEnqueues; // Persistent messages enqueued - uint64_t bytePersistDequeues; // Persistent messages dequeued - - uint32_t byteDepth; // Current size of queue in bytes - uint32_t byteDepthLow; // Low-water mark this interval - uint32_t byteDepthHigh; // High-water mark this interval - - uint64_t enqueueTxStarts; // Total enqueue transactions started - uint64_t enqueueTxCommits; // Total enqueue transactions committed - uint64_t enqueueTxRejects; // Total enqueue transactions rejected - - uint32_t enqueueTxCount; // Current pending enqueue transactions - uint32_t enqueueTxCountLow; // Low water mark this interval - uint32_t enqueueTxCountHigh; // High water mark this interval - - uint64_t dequeueTxStarts; // Total dequeue transactions started - uint64_t dequeueTxCommits; // Total dequeue transactions committed - uint64_t dequeueTxRejects; // Total dequeue transactions rejected - - uint32_t dequeueTxCount; // Current pending dequeue transactions - uint32_t dequeueTxCountLow; // Low water mark this interval - uint32_t dequeueTxCountHigh; // High water mark this interval - - uint32_t consumers; // Current consumers on queue - uint32_t consumersLow; // Low water mark this interval - uint32_t consumersHigh; // High water mark this interval - - void writeSchema (qpid::framing::Buffer& buf); - void writeConfig (qpid::framing::Buffer& buf); - void writeInstrumentation (qpid::framing::Buffer& buf); - bool getSchemaNeeded (void) { return schemaNeeded; } - void setSchemaNeeded (void) { schemaNeeded = true; } - void doMethod (std::string /*methodName*/, - qpid::framing::Buffer& /*inBuf*/, - qpid::framing::Buffer& /*outBuf*/) {} - - inline void adjustQueueHiLo (void){ - if (msgDepth > msgDepthHigh) msgDepthHigh = msgDepth; - if (msgDepth < msgDepthLow) msgDepthLow = msgDepth; - - if (byteDepth > byteDepthHigh) byteDepthHigh = byteDepth; - if (byteDepth < byteDepthLow) byteDepthLow = byteDepth; - instChanged = true; - } - - inline void adjustTxHiLo (void){ - if (enqueueTxCount > enqueueTxCountHigh) enqueueTxCountHigh = enqueueTxCount; - if (enqueueTxCount < enqueueTxCountLow) enqueueTxCountLow = enqueueTxCount; - if (dequeueTxCount > dequeueTxCountHigh) dequeueTxCountHigh = dequeueTxCount; - if (dequeueTxCount < dequeueTxCountLow) dequeueTxCountLow = dequeueTxCount; - instChanged = true; - } - - inline void adjustConsumerHiLo (void){ - if (consumers > consumersHigh) consumersHigh = consumers; - if (consumers < consumersLow) consumersLow = consumers; - instChanged = true; - } - - public: - - typedef boost::shared_ptr<Queue> shared_ptr; - - Queue (Manageable* coreObject, Manageable* parentObject, - const std::string& name, bool durable, bool autoDelete); - ~Queue (void); - - // The following mask contents are used to describe enqueued or dequeued - // messages when counting statistics. - - inline void enqueue (uint64_t bytes, uint32_t attrMask = 0){ - msgTotalEnqueues++; - byteTotalEnqueues += bytes; - - if (attrMask & MSG_MASK_TX){ - msgTxEnqueues++; - byteTxEnqueues += bytes; - } - - if (attrMask & MSG_MASK_PERSIST){ - msgPersistEnqueues++; - bytePersistEnqueues += bytes; - } - - msgDepth++; - byteDepth += bytes; - adjustQueueHiLo (); - } - - inline void dequeue (uint64_t bytes, uint32_t attrMask = 0){ - msgTotalDequeues++; - byteTotalDequeues += bytes; - - if (attrMask & MSG_MASK_TX){ - msgTxDequeues++; - byteTxDequeues += bytes; - } - - if (attrMask & MSG_MASK_PERSIST){ - msgPersistDequeues++; - bytePersistDequeues += bytes; - } - - msgDepth--; - byteDepth -= bytes; - adjustQueueHiLo (); - } - - inline void incConsumers (void){ - consumers++; - adjustConsumerHiLo (); - } - - inline void decConsumers (void){ - consumers--; - adjustConsumerHiLo (); - } -}; - -}} - - - -#endif /*!_ManagementQueue_*/ diff --git a/qpid/cpp/src/qpid/management/Vhost.cpp b/qpid/cpp/src/qpid/management/Vhost.cpp deleted file mode 100644 index c4fb84e8f2..0000000000 --- a/qpid/cpp/src/qpid/management/Vhost.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * 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 "Manageable.h" -#include "Vhost.h" -#include "qpid/framing/FieldTable.h" - -using namespace qpid::management; -using namespace qpid::sys; -using namespace qpid::framing; - -bool Vhost::schemaNeeded = true; - -Vhost::Vhost (Manageable* _core, Manageable* _parent) : - ManagementObject (_core, "vhost"), name("/") -{ - brokerRef = _parent->GetManagementObject ()->getObjectId (); -} - -Vhost::~Vhost () {} - -void Vhost::writeSchema (Buffer& buf) -{ - FieldTable ft; - - schemaNeeded = false; - - // Schema class header: - buf.putShortString (className); // Class Name - buf.putShort (2); // Config Element Count - buf.putShort (0); // Inst Element Count - buf.putShort (0); // Method Count - buf.putShort (0); // Event Count - - // Config Elements - ft = FieldTable (); - ft.setString ("name", "brokerRef"); - ft.setInt ("type", TYPE_U64); - ft.setInt ("access", ACCESS_RC); - ft.setInt ("index", 1); - ft.setString ("desc", "Broker Reference"); - buf.put (ft); - - ft = FieldTable (); - ft.setString ("name", "name"); - ft.setInt ("type", TYPE_SSTR); - ft.setInt ("access", ACCESS_RO); - ft.setInt ("index", 1); - ft.setString ("desc", "Name of virtual host"); - buf.put (ft); -} - -void Vhost::writeConfig (Buffer& buf) -{ - configChanged = false; - - writeTimestamps (buf); - buf.putLongLong (brokerRef); - buf.putShortString (name); -} - diff --git a/qpid/cpp/src/qpid/management/Vhost.h b/qpid/cpp/src/qpid/management/Vhost.h deleted file mode 100644 index 286514d7d7..0000000000 --- a/qpid/cpp/src/qpid/management/Vhost.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef _ManagementVhost_ -#define _ManagementVhost_ - -/* - * - * 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 "Manageable.h" -#include "ManagementObject.h" -#include "boost/shared_ptr.hpp" - -namespace qpid { -namespace management { - -class Vhost : public ManagementObject -{ - public: - - typedef boost::shared_ptr<Vhost> shared_ptr; - - Vhost (Manageable* coreObject, Manageable* parentObject); - ~Vhost (void); - - private: - - static bool schemaNeeded; - - uint64_t brokerRef; - std::string name; - - void writeSchema (qpid::framing::Buffer& buf); - void writeConfig (qpid::framing::Buffer& buf); - void writeInstrumentation (qpid::framing::Buffer& /*buf*/) {} - bool getSchemaNeeded (void) { return schemaNeeded; } - void setSchemaNeeded (void) { schemaNeeded = true; } - void doMethod (std::string /*methodName*/, - qpid::framing::Buffer& /*inBuf*/, - qpid::framing::Buffer& /*outBuf*/) {} - - inline bool getInstChanged (void) { return false; } -}; - -}} - - -#endif /*!_ManagementVhost_*/ diff --git a/qpid/specs/management-schema.xml b/qpid/specs/management-schema.xml new file mode 100644 index 0000000000..2c6109c33a --- /dev/null +++ b/qpid/specs/management-schema.xml @@ -0,0 +1,293 @@ +<schema package="qpid"> + +<!-- + 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. +--> + + <!-- Type information: + + Numeric types with "_wm" suffix are watermarked numbers. These are compound + values containing a current value, and a low and high water mark for the reporting + interval. The low and high water marks are set to the current value at the + beginning of each interval and track the minimum and maximum values of the statistic + over the interval respectively. + + Access rights for configuration elements: + + RO => Read Only + RC => Read/Create, can be set at create time only, read-only thereafter + RW => Read/Write + + If access rights are omitted for a configElement, they are assumed to be RO. + + --> + + <!-- Questions: Does C++ broker round-robin dests on queues? --> + + <!-- + =============================================================== + System + =============================================================== + --> + <class name="system"> + <configElement name="sysId" index="y" type="sstr" access="RC"/> + + <!-- RT config/instrumentation TBD --> + + </class> + + <!-- + =============================================================== + Broker + =============================================================== + --> + <class name="broker"> + <configElement name="systemRef" type="objId" access="RC" index="y" desc="System ID"/> + <configElement name="port" type="uint16" access="RC" index="y" desc="TCP Port for AMQP Service"/> + <configElement name="workerThreads" type="uint16" access="RO" desc="Thread pool size"/> + <configElement name="maxConns" type="uint16" access="RO" desc="Maximum allowed connections"/> + <configElement name="connBacklog" type="uint16" access="RO" desc="Connection backlog limit for listening socket"/> + <configElement name="stagingThreshold" type="uint32" access="RO" desc="Broker stages messages over this size to disk"/> + <configElement name="storeLib" type="sstr" access="RO" desc="Name of persistent storage library"/> + <configElement name="asyncStore" type="bool" access="RO" desc="Use async persistent store"/> + <configElement name="mgmtPubInterval" type="uint16" min="1" access="RW" unit="second" desc="Interval for management broadcasts"/> + <configElement name="initialDiskPageSize" type="uint32" access="RO" desc="Number of disk pages allocated for storage"/> + <configElement name="initialPagesPerQueue" type="uint32" access="RO" desc="Number of disk pages allocated per queue"/> + <configElement name="clusterName" type="sstr" access="RO" + desc="Name of cluster this server is a member of, zero-length for standalone server"/> + <configElement name="version" type="sstr" access="RO" desc="Running software version"/> + + + + <method name="joinCluster"> + <arg name="clusterName" dir="I" type="sstr"/> + </method> + + <method name="leaveCluster"/> + + <method name="echo"> + <arg name="sequence" dir="IO" type="uint32" default="0"/> + <arg name="body" dir="IO" type="lstr" default=""/> + </method> + <method name="crash" desc="Temporary test method to crash the broker"/> + </class> + + <!-- + =============================================================== + Virtual Host + =============================================================== + --> + <class name="vhost"> + <configElement name="brokerRef" type="objId" access="RC" index="y" parentRef="y"/> + <configElement name="name" type="sstr" access="RC" index="y"/> + </class> + + <!-- + =============================================================== + Queue + =============================================================== + --> + <class name="queue"> + <configElement name="vhostRef" type="objId" access="RC" index="y" parentRef="y"/> + <configElement name="name" type="sstr" access="RC" index="y"/> + + <configElement name="durable" type="bool" access="RC"/> + <configElement name="autoDelete" type="bool" access="RC"/> + <configElement name="exclusive" type="bool" access="RC"/> + <configElement name="pageMemoryLimit" type="uint32" access="RO"/> + + <!-- Persistent Journal Support --> + <instElement name="journalLocation" type="sstr" desc="Logical directory on disk"/> + <instElement name="journalBaseFileName" type="sstr" desc="Base filename prefix for journal"/> + <instElement name="journalInitialFileCount" type="uint32" desc="Number of files initially allocated to this journal"/> + <instElement name="journalCurrentFileCount" type="uint32" desc="Number of files currently allocated to this journal"/> + <instElement name="journalDataFileSize" type="uint32" unit="byte" desc="Size of each journal data file"/> + <instElement name="journalFreeFileCount" type="hilo32" desc="Number of files free on this journal. Includes free files trapped in holes."/> + <instElement name="journalAvailableFileCount" type="hilo32" desc="Number of files available to be written. Excluding holes"/> + <instElement name="journalRecordDepth" type="hilo32" unit="record" desc="Number of enqueued records (durable messages)"/> + <instElement name="journalRecordEnqueues" type="count64" unit="record" desc="Total enqueued records on journal"/> + <instElement name="journalRecordDequeues" type="count64" unit="record" desc="Total dequeued records on journal"/> + <instElement name="journalWriteWaitFailures" type="count64" unit="record" desc="AIO Wait failures on write"/> + <instElement name="journalWriteBusyFailures" type="count64" unit="record" desc="AIO Busy failures on write"/> + <instElement name="journalReadRecordCount" type="count64" unit="record" desc="Records read from the journal"/> + <instElement name="journalReadBusyFailures" type="count64" unit="record" desc="AIO Busy failures on read"/> + <instElement name="journalWritePageCacheDepth" type="hilo32" unit="page" desc="Current depth of write-page-cache"/> + <instElement name="journalWritePageSize" type="uint32" unit="byte" desc="Page size in write-page-cache"/> + <instElement name="journalReadPageCacheDepth" type="hilo32" unit="page" desc="Current depth of read-page-cache"/> + <instElement name="journalReadPageSize" type="uint32" unit="byte" desc="Page size in read-page-cache"/> + + <instElement name="msgTotalEnqueues" type="count64" unit="message" desc="Total messages enqueued"/> + <instElement name="msgTotalDequeues" type="count64" unit="message" desc="Total messages dequeued"/> + <instElement name="msgTxnEnqueues" type="count64" unit="message" desc="Transactional messages enqueued"/> + <instElement name="msgTxnDequeues" type="count64" unit="message" desc="Transactional messages dequeued"/> + <instElement name="msgPersistEnqueues" type="count64" unit="message" desc="Persistent messages enqueued"/> + <instElement name="msgPersistDequeues" type="count64" unit="message" desc="Persistent messages dequeued"/> + <instElement name="msgDepth" type="hilo32" unit="message" desc="Current size of queue in messages"/> + <instElement name="byteTotalEnqueues" type="count64" unit="octet" desc="Total messages enqueued"/> + <instElement name="byteTotalDequeues" type="count64" unit="octet" desc="Total messages dequeued"/> + <instElement name="byteTxnEnqueues" type="count64" unit="octet" desc="Transactional messages enqueued"/> + <instElement name="byteTxnDequeues" type="count64" unit="octet" desc="Transactional messages dequeued"/> + <instElement name="bytePersistEnqueues" type="count64" unit="octet" desc="Persistent messages enqueued"/> + <instElement name="bytePersistDequeues" type="count64" unit="octet" desc="Persistent messages dequeued"/> + <instElement name="byteDepth" type="hilo32" unit="octet" desc="Current size of queue in bytes"/> + <instElement name="enqueueTxnStarts" type="count64" unit="transaction" desc="Total enqueue transactions started "/> + <instElement name="enqueueTxnCommits" type="count64" unit="transaction" desc="Total enqueue transactions committed"/> + <instElement name="enqueueTxnRejects" type="count64" unit="transaction" desc="Total enqueue transactions rejected"/> + <instElement name="enqueueTxnCount" type="hilo32" unit="transaction" desc="Current pending enqueue transactions"/> + <instElement name="dequeueTxnStarts" type="count64" unit="transaction" desc="Total dequeue transactions started"/> + <instElement name="dequeueTxnCommits" type="count64" unit="transaction" desc="Total dequeue transactions committed"/> + <instElement name="dequeueTxnRejects" type="count64" unit="transaction" desc="Total dequeue transactions rejected"/> + <instElement name="dequeueTxnCount" type="hilo32" unit="transaction" desc="Current pending dequeue transactions"/> + <instElement name="consumers" type="hilo32" unit="consumer" desc="Current consumers on queue"/> + <instElement name="bindings" type="hilo32" unit="binding" desc="Current bindings"/> + <instElement name="unackedMessages" type="hilo32" unit="message" desc="Messages consumed but not yet acked"/> + + <method name="purge" desc="Discard all messages on queue"/> + <method name="increaseJournalSize" desc="Increase number of disk pages allocated for this queue"> + <arg name="pages" type="uint32" dir="I" desc="New total page allocation"/> + </method> + + </class> + + <!-- + =============================================================== + Exchange + =============================================================== + --> + <class name="exchange"> + <configElement name="vhostRef" type="objId" access="RC" index="y" parentRef="y"/> + <configElement name="name" type="sstr" access="RC" index="y"/> + <configElement name="type" type="sstr" access="RC"/> + + <instElement name="producers" type="hilo32" desc="Current producers on exchange"/> + <instElement name="bindings" type="hilo32" desc="Current bindings"/> + <instElement name="msgReceives" type="count64" desc="Total messages received"/> + <instElement name="msgDrops" type="count64" desc="Total messages dropped (no matching key)"/> + <instElement name="msgRoutes" type="count64" desc="Total routed messages"/> + <instElement name="byteReceives" type="count64" desc="Total bytes received"/> + <instElement name="byteDrops" type="count64" desc="Total bytes dropped (no matching key)"/> + <instElement name="byteRoutes" type="count64" desc="Total routed bytes"/> + </class> + + <!-- + =============================================================== + Binding + =============================================================== + --> + <class name="binding"> + <configElement name="queueRef" type="objId" access="RC" index="y"/> + <configElement name="exchangeRef" type="objId" access="RC" index="y"/> + <configElement name="bindingKey" type="sstr" access="RC"/> +<!--<configElement name="arguments" type="fieldTable" access="RC"/> --> + + <instElement name="msgMatched" type="count64"/> + </class> + + <!-- + =============================================================== + Client + =============================================================== + --> + <class name="client"> + <configElement name="vhostRef" type="objId" access="RC" index="y" parentRef="y"/> + <configElement name="ipAddr" type="uint32" access="RC" index="y"/> + <configElement name="port" type="uint16" access="RC" index="y"/> + + <instElement name="authIdentity" type="sstr"/> + <instElement name="msgsProduced" type="count64"/> + <instElement name="msgsConsumed" type="count64"/> + <instElement name="bytesProduced" type="count64"/> + <instElement name="bytesConsumed" type="count64"/> + + <method name="close"/> + <method name="detach"/> + </class> + + <!-- + =============================================================== + Session + =============================================================== + --> + <class name="session"> + <configElement name="vhostRef" type="objId" access="RC" index="y" parentRef="y"/> + <configElement name="name" type="sstr" access="RC" index="y"/> + <configElement name="clientRef" type="sstr" access="RO"/> + <configElement name="detachedLifespan" type="uint32" access="RO"/> + + <instElement name="attached" type="bool"/> + <instElement name="remainingLifespan" type="count32"/> + <instElement name="framesOutstanding" type="count32"/> + + <method name="solicitAck"/> + <method name="detach"/> + <method name="resetLifespan"/> + <method name="close"/> + </class> + + <!-- + =============================================================== + Destination + =============================================================== + --> + <class name="destination"> + <configElement name="sessionRef" type="objId" access="RC" index="y" parentRef="y"/> + <configElement name="name" type="sstr" access="RC" index="y"/> + + <instElement name="flowMode" type="uint8"/> + <instElement name="maxMsgCredits" type="uint32"/> + <instElement name="maxByteCredits" type="uint32"/> + <instElement name="msgCredits" type="uint32"/> + <instElement name="byteCredits" type="uint32"/> + + <method name="throttle" desc="Apply extra rate limiting to destination: 0 = Normal, 10 = Maximum"> + <arg name="strength" type="uint8" dir="I" min="0" max="10"/> + </method> + <method name="stop"/> + <method name="start"/> + </class> + + <!-- + =============================================================== + Producer + =============================================================== + --> + <class name="producer"> + <configElement name="destinationRef" access="RC" type="objId" index="y"/> + <configElement name="exchangeRef" access="RC" type="objId" index="y"/> + + <instElement name="msgsProduced" type="count64"/> + <instElement name="bytesProduced" type="count64"/> + </class> + + <!-- + =============================================================== + Consumer + =============================================================== + --> + <class name="consumer"> + <configElement name="destinationRef" access="RC" type="objId" index="y"/> + <configElement name="queueRef" access="RC" type="objId" index="y"/> + + <instElement name="msgsConsumed" type="count64"/> + <instElement name="bytesConsumed" type="count64"/> + <instElement name="unackedMessages" type="hilo32" desc="Messages consumed but not yet acked"/> + + <method name="close"/> + </class> +</schema> + diff --git a/qpid/specs/management-types.xml b/qpid/specs/management-types.xml new file mode 100644 index 0000000000..9f251f032b --- /dev/null +++ b/qpid/specs/management-types.xml @@ -0,0 +1,48 @@ +<schema-types> + +<!-- + 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. +--> + +<type name="objId" base="U64" cpp="uint64_t" encode="@.putLongLong (#)" decode="# = @.getLongLong ()" accessor="direct" init="0"/> +<type name="uint8" base="U8" cpp="uint8_t" encode="@.putOctet (#)" decode="# = @.getOctet ()" accessor="direct" init="0"/> +<type name="uint16" base="U16" cpp="uint16_t" encode="@.putShort (#)" decode="# = @.getShort ()" accessor="direct" init="0"/> +<type name="uint32" base="U32" cpp="uint32_t" encode="@.putLong (#)" decode="# = @.getLong ()" accessor="direct" init="0"/> +<type name="uint64" base="U64" cpp="uint64_t" encode="@.putLongLong (#)" decode="# = @.getLongLong ()" accessor="direct" init="0"/> +<type name="bool" base="U8" cpp="bool" encode="@.putOctet (#?1:0)" decode="# = @.getOctet ()==1" accessor="direct" init="0"/> +<type name="sstr" base="SSTR" cpp="std::string" encode="@.putShortString (#)" decode="@.getShortString (#)" accessor="direct" init='""'/> +<type name="lstr" base="LSTR" cpp="std::string" encode="@.putLongString (#)" decode="@.getLongString (#)" accessor="direct" init='""'/> + +<type name="hilo8" base="U8" cpp="uint8_t" encode="@.putOctet (#)" decode="# = @.getOctet ()" style="wm" accessor="counter" init="0"/> +<type name="hilo16" base="U16" cpp="uint16_t" encode="@.putShort (#)" decode="# = @.getShort ()" style="wm" accessor="counter" init="0"/> +<type name="hilo32" base="U32" cpp="uint32_t" encode="@.putLong (#)" decode="# = @.getLong ()" style="wm" accessor="counter" init="0"/> +<type name="hilo64" base="U64" cpp="uint64_t" encode="@.putLongLong (#)" decode="# = @.getLongLong ()" style="wm" accessor="counter" init="0"/> + +<type name="count8" base="U8" cpp="uint8_t" encode="@.putOctet (#)" decode="# = @.getOctet ()" accessor="counter" init="0"/> +<type name="count16" base="U16" cpp="uint16_t" encode="@.putShort (#)" decode="# = @.getShort ()" accessor="counter" init="0"/> +<type name="count32" base="U32" cpp="uint32_t" encode="@.putLong (#)" decode="# = @.getLong ()" accessor="counter" init="0"/> +<type name="count64" base="U64" cpp="uint64_t" encode="@.putLongLong (#)" decode="# = @.getLongLong ()" accessor="counter" init="0"/> + +<!-- Some Proposed Syntax for User-Defined Types: +<enum name="enumeratedType" base="U8"> + <item name="value-name1" value="1"/> + <item name="value-name2" value="2"/> +</enum> +--> + +</schema-types> |