| #!/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. |
| # |
| |
| |
| import qmf |
| import sys |
| import time |
| |
| |
| class Model: |
| # attr_reader :parent_class, :child_class |
| def __init__(self): |
| self.parent_class = qmf.SchemaObjectClass("org.apache.qpid.qmf", "parent") |
| self.parent_class.add_property(qmf.SchemaProperty("name", qmf.TYPE_SSTR, {"index":True})) |
| self.parent_class.add_property(qmf.SchemaProperty("state", qmf.TYPE_SSTR)) |
| |
| self.parent_class.add_property(qmf.SchemaProperty("uint64val", qmf.TYPE_UINT64)) |
| self.parent_class.add_property(qmf.SchemaProperty("uint32val", qmf.TYPE_UINT32)) |
| self.parent_class.add_property(qmf.SchemaProperty("uint16val", qmf.TYPE_UINT16)) |
| self.parent_class.add_property(qmf.SchemaProperty("uint8val", qmf.TYPE_UINT8)) |
| |
| self.parent_class.add_property(qmf.SchemaProperty("int64val", qmf.TYPE_INT64)) |
| self.parent_class.add_property(qmf.SchemaProperty("int32val", qmf.TYPE_INT32)) |
| self.parent_class.add_property(qmf.SchemaProperty("int16val", qmf.TYPE_INT16)) |
| self.parent_class.add_property(qmf.SchemaProperty("int8val", qmf.TYPE_INT8)) |
| |
| self.parent_class.add_property(qmf.SchemaProperty("sstrval", qmf.TYPE_SSTR)) |
| self.parent_class.add_property(qmf.SchemaProperty("lstrval", qmf.TYPE_LSTR)) |
| |
| self.parent_class.add_property(qmf.SchemaProperty("mapval", qmf.TYPE_MAP)) |
| self.parent_class.add_property(qmf.SchemaProperty("listval", qmf.TYPE_LIST)) |
| |
| |
| self.parent_class.add_statistic(qmf.SchemaStatistic("queryCount", qmf.TYPE_UINT32, {"unit":"query", "desc":"Query count"})) |
| |
| _method = qmf.SchemaMethod("echo", {"desc":"Check responsiveness of the agent object"}) |
| _method.add_argument(qmf.SchemaArgument("sequence", qmf.TYPE_UINT32, {"dir":qmf.DIR_IN_OUT})) |
| self.parent_class.add_method(_method) |
| |
| _method = qmf.SchemaMethod("set_numerics", {"desc":"Set the numeric values in the object"}) |
| _method.add_argument(qmf.SchemaArgument("test", qmf.TYPE_SSTR, {"dir":qmf.DIR_IN})) |
| self.parent_class.add_method(_method) |
| |
| _method = qmf.SchemaMethod("test_map_list", {"desc":"A method call that accepts map and list arguments."}) |
| _method.add_argument(qmf.SchemaArgument("inMap", qmf.TYPE_MAP, {"dir":qmf.DIR_IN})) |
| _method.add_argument(qmf.SchemaArgument("inList", qmf.TYPE_LIST, {"dir":qmf.DIR_IN})) |
| _method.add_argument(qmf.SchemaArgument("outMap", qmf.TYPE_MAP, {"dir":qmf.DIR_OUT})) |
| _method.add_argument(qmf.SchemaArgument("outList", qmf.TYPE_LIST, {"dir":qmf.DIR_OUT})) |
| self.parent_class.add_method(_method) |
| |
| _method = qmf.SchemaMethod("set_short_string", {"desc":"Set the short string value in the object"}) |
| _method.add_argument(qmf.SchemaArgument("value", qmf.TYPE_SSTR, {"dir":qmf.DIR_IN_OUT})) |
| self.parent_class.add_method(_method) |
| |
| _method = qmf.SchemaMethod("set_long_string", {"desc":"Set the long string value in the object"}) |
| _method.add_argument(qmf.SchemaArgument("value", qmf.TYPE_LSTR, {"dir":qmf.DIR_IN_OUT})) |
| self.parent_class.add_method(_method) |
| |
| _method = qmf.SchemaMethod("create_child", {"desc":"Create a new child object"}) |
| _method.add_argument(qmf.SchemaArgument("child_name", qmf.TYPE_LSTR, {"dir":qmf.DIR_IN})) |
| _method.add_argument(qmf.SchemaArgument("child_ref", qmf.TYPE_REF, {"dir":qmf.DIR_OUT})) |
| self.parent_class.add_method(_method) |
| |
| _method = qmf.SchemaMethod("probe_userid", {"desc":"Return the user-id for this method call"}) |
| _method.add_argument(qmf.SchemaArgument("userid", qmf.TYPE_SSTR, {"dir":qmf.DIR_OUT})) |
| self.parent_class.add_method(_method) |
| |
| self.child_class = qmf.SchemaObjectClass("org.apache.qpid.qmf", "child") |
| self.child_class.add_property(qmf.SchemaProperty("name", qmf.TYPE_SSTR, {"index":True})) |
| |
| self.event_class = qmf.SchemaEventClass("org.apache.qpid.qmf", "test_event", qmf.SEV_NOTICE) |
| self.event_class.add_argument(qmf.SchemaArgument("uint32val", qmf.TYPE_UINT32)) |
| self.event_class.add_argument(qmf.SchemaArgument("strval", qmf.TYPE_LSTR)) |
| self.event_class.add_argument(qmf.SchemaArgument("mapval", qmf.TYPE_MAP)) |
| self.event_class.add_argument(qmf.SchemaArgument("listval", qmf.TYPE_LIST)) |
| |
| def register(self, agent): |
| agent.register_class(self.parent_class) |
| agent.register_class(self.child_class) |
| agent.register_class(self.event_class) |
| |
| |
| |
| class App(qmf.AgentHandler): |
| ''' |
| Object that handles events received by the Agent. |
| ''' |
| def get_query(self, context, query, userId): |
| ''' |
| Respond to a Query request from a console. |
| ''' |
| #print "Query: user=%s context=%d class=%s" % (userId, context, query.class_name()) |
| #if query.object_id(): |
| # print query.object_id().object_num_low() |
| self._parent.inc_attr("queryCount") |
| if query.class_name() == 'parent': |
| self._agent.query_response(context, self._parent) |
| elif query.object_id() == self._parent_oid: |
| self._agent.query_response(context, self._parent) |
| self._agent.query_complete(context) |
| |
| |
| def method_call(self, context, name, object_id, args, userId): |
| ''' |
| Invoke a method call requested by the console. |
| ''' |
| #print "Method: name=%s user=%s context=%d object_id=%s args=%s" % (name, userId, context, object_id, args) |
| if name == "echo": |
| self._agent.method_response(context, 0, "OK", args) |
| |
| elif name == "test_map_list": |
| # build the output map from the input map, accessing each key, |
| # value to ensure they are encoded/decoded |
| outMap = {} |
| for key,value in args['inMap'].items(): |
| outMap[key] = value |
| |
| # same deal for the output list |
| outList = [] |
| for value in args['inList']: |
| outList.append(value) |
| |
| args['outMap'] = outMap |
| args['outList'] = outList |
| self._agent.method_response(context, 0, "OK", args) |
| |
| elif name == "set_numerics": |
| _retCode = 0 |
| _retText = "OK" |
| |
| if args['test'] == "big": |
| # |
| # note the alternate forms for setting object attributes: |
| # |
| self._parent.set_attr("uint64val", 0x9494949449494949) |
| self._parent.uint32val = 0xa5a55a5a |
| self._parent.set_attr("uint16val", 0xb66b) |
| self._parent["uint8val"] = 0xc7 |
| |
| self._parent.int64val = 1000000000000000000 |
| self._parent.set_attr("int32val", 1000000000) |
| self._parent["int16val"] = 10000 |
| self._parent.set_attr("int8val", 100) |
| |
| event = qmf.QmfEvent(self._model.event_class) |
| event.uint32val = self._parent.get_attr("uint32val") |
| event.strval = "Unused" |
| event.mapval = self._parent.get_attr("mapval") |
| event.listval = self._parent["listval"] |
| |
| self._agent.raise_event(event) |
| |
| ## Test the __getattr__ implementation: |
| ## @todo: remove once python_client implements this |
| ## form of property access |
| assert self._parent["uint8val"] == 0xc7 |
| assert self._parent.uint64val == 0x9494949449494949 |
| |
| # note the alternative argument access syntax: |
| elif args.test == "small": |
| self._parent.set_attr("uint64val", 4) |
| self._parent.set_attr("uint32val", 5) |
| self._parent.set_attr("uint16val", 6) |
| self._parent.set_attr("uint8val", 7) |
| |
| self._parent.set_attr("int64val", 8) |
| self._parent.set_attr("int32val", 9) |
| self._parent.set_attr("int16val", 10) |
| self._parent.set_attr("int8val", 11) |
| |
| event = qmf.QmfEvent(self._model.event_class) |
| event.uint32val = self._parent.uint32val |
| event.strval = "Unused" |
| self._agent.raise_event(event) |
| |
| elif args['test'] == "negative": |
| self._parent.set_attr("uint64val", 0) |
| self._parent.set_attr("uint32val", 0) |
| self._parent.set_attr("uint16val", 0) |
| self._parent.set_attr("uint8val", 0) |
| |
| self._parent.set_attr("int64val", -10000000000) |
| self._parent.set_attr("int32val", -100000) |
| self._parent.set_attr("int16val", -1000) |
| self._parent.set_attr("int8val", -100) |
| |
| event = qmf.QmfEvent(self._model.event_class) |
| event.uint32val = self._parent.uint32val |
| event.strval = "Unused" |
| self._agent.raise_event(event) |
| |
| else: |
| _retCode = 1 |
| _retText = "Invalid argument value for test" |
| |
| self._agent.method_response(context, _retCode, _retText, args) |
| |
| elif name == "set_short_string": |
| self._parent.set_attr('sstrval', args['value']) |
| event = qmf.QmfEvent(self._model.event_class) |
| event.uint32val = 0 |
| event.strval = self._parent.sstrval |
| self._agent.raise_event(event) |
| |
| self._agent.method_response(context, 0, "OK", args) |
| |
| elif name == "set_long_string": |
| self._parent.set_attr('lstrval', args['value']) |
| event = qmf.QmfEvent(self._model.event_class) |
| event.uint32val = 0 |
| event.strval = self._parent.lstrval |
| self._agent.raise_event(event) |
| |
| self._agent.method_response(context, 0, "OK", args) |
| |
| elif name == "create_child": |
| # |
| # Instantiate an object based on the Child Schema Class |
| # |
| _oid = self._agent.alloc_object_id(2) |
| args['child_ref'] = _oid |
| self._child = qmf.AgentObject(self._model.child_class) |
| self._child.set_attr("name", args["child_name"]) |
| self._child.set_object_id(_oid) |
| self._agent.method_response(context, 0, "OK", args) |
| |
| elif name == "probe_userid": |
| args['userid'] = userId |
| self._agent.method_response(context, 0, "OK", args) |
| |
| else: |
| self._agent.method_response(context, 1, "Unimplemented Method: %s" % name, args) |
| |
| |
| def main(self): |
| ''' |
| Agent application's main processing loop. |
| ''' |
| # Connect to the broker |
| self._settings = qmf.ConnectionSettings() |
| self._settings.sendUserId = True |
| if len(sys.argv) > 1: |
| self._settings.host = str(sys.argv[1]) |
| if len(sys.argv) > 2: |
| self._settings.port = int(sys.argv[2]) |
| self._connection = qmf.Connection(self._settings) |
| |
| # Instantiate an Agent to serve me queries and method calls |
| self._agent = qmf.Agent(self, "agent_test_label") |
| |
| # Dynamically define the parent and child schemas, then |
| # register them with the agent |
| self._model = Model() |
| self._model.register(self._agent) |
| |
| # Tell the agent about our connection to the broker |
| self._agent.set_connection(self._connection) |
| |
| # Instantiate and populate an instance of the Parent |
| # Schema Object |
| self._parent = qmf.AgentObject(self._model.parent_class) |
| |
| ## @todo how do we force a test failure? |
| # verify the properties() and statistics() object methods: |
| assert len(self._parent.properties()) == 14 |
| assert len(self._parent.statistics()) == 1 |
| |
| self._parent.set_attr("name", "Parent One") |
| self._parent.set_attr("state", "OPERATIONAL") |
| |
| self._parent.set_attr("uint64val", 0) |
| self._parent.set_attr("uint32val", 0) |
| self._parent.set_attr("uint16val", 0) |
| self._parent.set_attr("uint8val", 0) |
| |
| self._parent.set_attr("int64val", 0) |
| self._parent.set_attr("int32val", 0) |
| self._parent.set_attr("int16val", 0) |
| self._parent.set_attr("int8val", 0) |
| |
| # a list containing a list that contains a map (so there!) |
| self._parent.set_attr("listval", ['a', 1, 'b', -2, |
| ['c', True, 3.1415, |
| {"hi": 10, "lo": 5, "neg": -3}]]) |
| # a default map |
| self._parent.set_attr("mapval", {'aLong' : long(9999999999), |
| 'aInt' : int(54321), |
| 'aSigned' : -666, |
| 'aString' : "A String", |
| 'aFloat' : 3.1415, |
| 'aMap' : {'first' : 1, |
| 'second': 2}, |
| 'aList' : ['x', -1, 'y', 2]}) |
| |
| |
| |
| self._parent_oid = self._agent.alloc_object_id(1) |
| self._parent.set_object_id(self._parent_oid) |
| |
| # Now wait for events arriving on the connection |
| # to the broker... |
| while True: |
| time.sleep(1000) |
| |
| |
| |
| app = App() |
| app.main() |
| |