blob: 28ba47e1bb7cfd8c9ddbc18ee0e56007e2019f6f [file]
#!/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()