summaryrefslogtreecommitdiff
path: root/qpid/cpp/bindings
diff options
context:
space:
mode:
authorAidan Skinner <aidan@apache.org>2009-09-09 13:05:43 +0000
committerAidan Skinner <aidan@apache.org>2009-09-09 13:05:43 +0000
commitc1ebe66bfab328c5192a35c21ea290b5c45f40f5 (patch)
tree6e61e50d92442f29287a82c22b54de6beac43b2c /qpid/cpp/bindings
parent7b28732091473d93ce7546c70fa1d2dbd685161a (diff)
downloadqpid-python-c1ebe66bfab328c5192a35c21ea290b5c45f40f5.tar.gz
Merge from trunk
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-network-refactor@812936 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/bindings')
-rw-r--r--qpid/cpp/bindings/qmf/Makefile.am10
-rw-r--r--qpid/cpp/bindings/qmf/python/Makefile.am9
-rw-r--r--qpid/cpp/bindings/qmf/python/python.i120
-rw-r--r--qpid/cpp/bindings/qmf/python/qmf.py854
-rw-r--r--qpid/cpp/bindings/qmf/qmfengine.i30
-rw-r--r--qpid/cpp/bindings/qmf/ruby/Makefile.am4
-rw-r--r--qpid/cpp/bindings/qmf/ruby/qmf.rb1131
-rw-r--r--qpid/cpp/bindings/qmf/ruby/ruby.i42
-rw-r--r--qpid/cpp/bindings/qmf/tests/Makefile.am8
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/agent_ruby.rb111
-rw-r--r--qpid/cpp/bindings/qmf/tests/python_agent.py192
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/python_console.py99
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/ruby_console.rb61
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/run_interop_tests64
14 files changed, 2277 insertions, 458 deletions
diff --git a/qpid/cpp/bindings/qmf/Makefile.am b/qpid/cpp/bindings/qmf/Makefile.am
index 68312a4208..eebb4b94de 100644
--- a/qpid/cpp/bindings/qmf/Makefile.am
+++ b/qpid/cpp/bindings/qmf/Makefile.am
@@ -20,6 +20,14 @@
if HAVE_SWIG
EXTRA_DIST = qmfengine.i
-SUBDIRS = ruby tests
+SUBDIRS = tests
+
+if HAVE_RUBY_DEVEL
+SUBDIRS += ruby
+endif
+
+if HAVE_PYTHON_DEVEL
+SUBDIRS += python
+endif
endif
diff --git a/qpid/cpp/bindings/qmf/python/Makefile.am b/qpid/cpp/bindings/qmf/python/Makefile.am
index 7b3f4d3be7..f51d26bfad 100644
--- a/qpid/cpp/bindings/qmf/python/Makefile.am
+++ b/qpid/cpp/bindings/qmf/python/Makefile.am
@@ -35,11 +35,12 @@ pylibdir = $(PYTHON_LIB)
lib_LTLIBRARIES = _qmfengine.la
-_qmfengine_la_LDFLAGS = -avoid-version -module -shrext "$(PYTHON_SO)"
-_qmfengine_la_LIBADD = $(PYTHON_LIBS) -L$(top_builddir)/src/.libs -lqpidclient $(top_builddir)/src/libqmfcommon.la
+#_qmfengine_la_LDFLAGS = -avoid-version -module -shrext "$(PYTHON_SO)"
+#_qmfengine_la_LDFLAGS = -avoid-version -module -shrext ".so"
+_qmfengine_la_LDFLAGS = -avoid-version -module -shared
+_qmfengine_la_LIBADD = $(PYTHON_LIBS) -L$(top_builddir)/src/.libs -lqpidclient $(top_builddir)/src/libqmfagent.la
_qmfengine_la_CXXFLAGS = $(INCLUDES) -I$(srcdir)/qmf -I$(PYTHON_INC)
-_qmfengine_la_SOURCES = \
- qmfengine.cpp
+nodist__qmfengine_la_SOURCES = qmfengine.cpp
CLEANFILES = $(generated_file_list)
diff --git a/qpid/cpp/bindings/qmf/python/python.i b/qpid/cpp/bindings/qmf/python/python.i
index ea14efd4dd..5e25d155f9 100644
--- a/qpid/cpp/bindings/qmf/python/python.i
+++ b/qpid/cpp/bindings/qmf/python/python.i
@@ -19,17 +19,125 @@
%module qmfengine
-// These are probably wrong.. just to get it to compile for now.
-%typemap (in) void *
-{
- $1 = (void *) $input;
+
+/* unsigned32 Convert from Python --> C */
+%typemap(in) uint32_t {
+ if (PyInt_Check($input)) {
+ $1 = (uint32_t) PyInt_AsUnsignedLongMask($input);
+ } else if (PyLong_Check($input)) {
+ $1 = (uint32_t) PyLong_AsUnsignedLong($input);
+ } else {
+ SWIG_exception_fail(SWIG_ValueError, "unknown integer type");
+ }
+}
+
+/* unsinged32 Convert from C --> Python */
+%typemap(out) uint32_t {
+ $result = PyInt_FromLong((long)$1);
+}
+
+
+/* unsigned16 Convert from Python --> C */
+%typemap(in) uint16_t {
+ if (PyInt_Check($input)) {
+ $1 = (uint16_t) PyInt_AsUnsignedLongMask($input);
+ } else if (PyLong_Check($input)) {
+ $1 = (uint16_t) PyLong_AsUnsignedLong($input);
+ } else {
+ SWIG_exception_fail(SWIG_ValueError, "unknown integer type");
+ }
+}
+
+/* unsigned16 Convert from C --> Python */
+%typemap(out) uint16_t {
+ $result = PyInt_FromLong((long)$1);
+}
+
+
+/* signed32 Convert from Python --> C */
+%typemap(in) int32_t {
+ if (PyInt_Check($input)) {
+ $1 = (int32_t) PyInt_AsLong($input);
+ } else if (PyLong_Check($input)) {
+ $1 = (int32_t) PyLong_AsLong($input);
+ } else {
+ SWIG_exception_fail(SWIG_ValueError, "unknown integer type");
+ }
+}
+
+/* signed32 Convert from C --> Python */
+%typemap(out) int32_t {
+ $result = PyInt_FromLong((long)$1);
+}
+
+
+/* unsigned64 Convert from Python --> C */
+%typemap(in) uint64_t {
+%#ifdef HAVE_LONG_LONG
+ if (PyLong_Check($input)) {
+ $1 = (uint64_t)PyLong_AsUnsignedLongLong($input);
+ } else if (PyInt_Check($input)) {
+ $1 = (uint64_t)PyInt_AsUnsignedLongLongMask($input);
+ } else
+%#endif
+ {
+ SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - uint64_t input too large");
+ }
+}
+
+/* unsigned64 Convert from C --> Python */
+%typemap(out) uint64_t {
+%#ifdef HAVE_LONG_LONG
+ $result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)$1);
+%#else
+ SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - uint64_t output too large");
+%#endif
+}
+
+/* signed64 Convert from Python --> C */
+%typemap(in) int64_t {
+%#ifdef HAVE_LONG_LONG
+ if (PyLong_Check($input)) {
+ $1 = (int64_t)PyLong_AsLongLong($input);
+ } else if (PyInt_Check($input)) {
+ $1 = (int64_t)PyInt_AsLong($input);
+ } else
+%#endif
+ {
+ SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - int64_t input too large");
+ }
+}
+
+/* signed64 Convert from C --> Python */
+%typemap(out) int64_t {
+%#ifdef HAVE_LONG_LONG
+ $result = PyLong_FromLongLong((PY_LONG_LONG)$1);
+%#else
+ SWIG_exception_fail(SWIG_ValueError, "unsupported integer size - int64_t output too large");
+%#endif
}
-%typemap (out) void *
-{
+
+/* Convert from Python --> C */
+%typemap(in) void * {
+ $1 = (void *)$input;
+}
+
+/* Convert from C --> Python */
+%typemap(out) void * {
$result = (PyObject *) $1;
+ Py_INCREF($result);
+}
+
+%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT64) uint64_t {
+ $1 = PyLong_Check($input) ? 1 : 0;
}
+%typemap (typecheck, precedence=SWIG_TYPECHECK_UINT32) uint32_t {
+ $1 = PyInt_Check($input) ? 1 : 0;
+}
+
+
%include "../qmfengine.i"
diff --git a/qpid/cpp/bindings/qmf/python/qmf.py b/qpid/cpp/bindings/qmf/python/qmf.py
new file mode 100644
index 0000000000..265f204852
--- /dev/null
+++ b/qpid/cpp/bindings/qmf/python/qmf.py
@@ -0,0 +1,854 @@
+#
+# 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 sys
+import socket
+import os
+from threading import Thread
+from threading import RLock
+import qmfengine
+from qmfengine import (ACCESS_READ_CREATE, ACCESS_READ_ONLY, ACCESS_READ_WRITE)
+from qmfengine import (CLASS_EVENT, CLASS_OBJECT)
+from qmfengine import (DIR_IN, DIR_IN_OUT, DIR_OUT)
+from qmfengine import (TYPE_ABSTIME, TYPE_ARRAY, TYPE_BOOL, TYPE_DELTATIME,
+ TYPE_DOUBLE, TYPE_FLOAT, TYPE_INT16, TYPE_INT32, TYPE_INT64,
+ TYPE_INT8, TYPE_LIST, TYPE_LSTR, TYPE_MAP, TYPE_OBJECT,
+ TYPE_REF, TYPE_SSTR, TYPE_UINT16, TYPE_UINT32, TYPE_UINT64,
+ TYPE_UINT8, TYPE_UUID)
+
+
+ ##==============================================================================
+ ## CONNECTION
+ ##==============================================================================
+
+class ConnectionSettings:
+ #attr_reader :impl
+ def __init__(self, url=None):
+ if url:
+ self.impl = qmfengine.ConnectionSettings(url)
+ else:
+ self.impl = qmfengine.ConnectionSettings()
+
+
+ def set_attr(self, key, val):
+ if type(val) == str:
+ _v = qmfengine.Value(TYPE_LSTR)
+ _v.setString(val)
+ elif type(val) == bool:
+ _v = qmfengine.Value(TYPE_BOOL)
+ _v.setBool(val)
+ elif type(val) == int:
+ _v = qmfengine.Value(TYPE_UINT32)
+ _v.setUint(val)
+ else:
+ raise ArgumentError("Value for attribute '%s' has unsupported type: %s" % ( key, type(val)))
+
+ self.impl.setAttr(key, _v)
+
+
+
+class ConnectionHandler:
+ def conn_event_connected(self): None
+ def conn_event_disconnected(self, error): None
+ def sess_event_session_closed(self, context, error): None
+ def sess_event_recv(self, context, message): None
+
+
+
+class Connection(Thread):
+ def __init__(self, settings):
+ Thread.__init__(self)
+ self._lock = RLock()
+ self.impl = qmfengine.ResilientConnection(settings.impl)
+ self._sockEngine, self._sock = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
+ self.impl.setNotifyFd(self._sockEngine.fileno())
+ self._new_conn_handlers = []
+ self._conn_handlers = []
+ self.start()
+
+
+ def add_conn_handler(self, handler):
+ self._lock.acquire()
+ try:
+ self._new_conn_handlers.append(handler)
+ finally:
+ self._lock.release()
+ self._sockEngine.send("x")
+
+
+ def run(self):
+ eventImpl = qmfengine.ResilientConnectionEvent()
+ connected = False
+ new_handlers = []
+ bt_count = 0
+
+ while True:
+ # print "Waiting for socket data"
+ self._sock.recv(1)
+
+ self._lock.acquire()
+ try:
+ new_handlers = self._new_conn_handlers
+ self._new_conn_handlers = []
+ finally:
+ self._lock.release()
+
+ for nh in new_handlers:
+ self._conn_handlers.append(nh)
+ if connected:
+ nh.conn_event_connected()
+
+ new_handlers = []
+
+ valid = self.impl.getEvent(eventImpl)
+ while valid:
+ try:
+ if eventImpl.kind == qmfengine.ResilientConnectionEvent.CONNECTED:
+ connected = True
+ for h in self._conn_handlers:
+ h.conn_event_connected()
+
+ elif eventImpl.kind == qmfengine.ResilientConnectionEvent.DISCONNECTED:
+ connected = False
+ for h in self._conn_handlers:
+ h.conn_event_disconnected(eventImpl.errorText)
+
+ elif eventImpl.kind == qmfengine.ResilientConnectionEvent.SESSION_CLOSED:
+ eventImpl.sessionContext.handler.sess_event_session_closed(eventImpl.sessionContext, eventImpl.errorText)
+
+ elif eventImpl.kind == qmfengine.ResilientConnectionEvent.RECV:
+ eventImpl.sessionContext.handler.sess_event_recv(eventImpl.sessionContext, eventImpl.message)
+
+ except:
+ import traceback
+ print "Event Exception:", sys.exc_info()
+ if bt_count < 2:
+ traceback.print_exc()
+ traceback.print_stack()
+ bt_count += 1
+
+ self.impl.popEvent()
+ valid = self.impl.getEvent(eventImpl)
+
+
+
+class Session:
+ def __init__(self, conn, label, handler):
+ self._conn = conn
+ self._label = label
+ self.handler = handler
+ self.handle = qmfengine.SessionHandle()
+ result = self._conn.impl.createSession(label, self, self.handle)
+
+
+ def __del__(self):
+ self._conn.impl.destroySession(self.handle)
+
+
+
+ ##==============================================================================
+ ## OBJECTS
+ ##==============================================================================
+
+class QmfObject:
+ # attr_reader :impl, :object_class
+ def __init__(self, cls):
+ self.object_class = cls
+ self.impl = qmfengine.Object(self.object_class.impl)
+
+
+ def __del__(self):
+ self.impl.destroy()
+
+
+ def object_id(self):
+ return ObjectId(self.impl.getObjectId())
+
+
+ def set_object_id(self, oid):
+ self.impl.setObjectId(oid.impl)
+
+
+ def get_attr(self, name):
+ val = self._value(name)
+ vType = val.getType()
+ if vType == TYPE_UINT8: return val.asUint()
+ elif vType == TYPE_UINT16: return val.asUint()
+ elif vType == TYPE_UINT32: return val.asUint()
+ elif vType == TYPE_UINT64: return val.asUint64()
+ elif vType == TYPE_SSTR: return val.asString()
+ elif vType == TYPE_LSTR: return val.asString()
+ elif vType == TYPE_ABSTIME: return val.asInt64()
+ elif vType == TYPE_DELTATIME: return val.asUint64()
+ elif vType == TYPE_REF: return val.asObjectId()
+ elif vType == TYPE_BOOL: return val.asBool()
+ elif vType == TYPE_FLOAT: return val.asFloat()
+ elif vType == TYPE_DOUBLE: return val.asDouble()
+ elif vType == TYPE_UUID: return val.asUuid()
+ elif vType == TYPE_INT8: return val.asInt()
+ elif vType == TYPE_INT16: return val.asInt()
+ elif vType == TYPE_INT32: return val.asInt()
+ elif vType == TYPE_INT64: return val.asInt64()
+ else:
+ # when TYPE_MAP
+ # when TYPE_OBJECT
+ # when TYPE_LIST
+ # when TYPE_ARRAY
+ print "Unsupported type for get_attr?", val.getType()
+ return None
+
+
+ def set_attr(self, name, v):
+ val = self._value(name)
+ vType = val.getType()
+ if vType == TYPE_UINT8: return val.setUint(v)
+ elif vType == TYPE_UINT16: return val.setUint(v)
+ elif vType == TYPE_UINT32: return val.setUint(v)
+ elif vType == TYPE_UINT64: return val.setUint64(v)
+ elif vType == TYPE_SSTR:
+ if v: return val.setString(v)
+ else: return val.setString('')
+ elif vType == TYPE_LSTR:
+ if v: return val.setString(v)
+ else: return val.setString('')
+ elif vType == TYPE_ABSTIME: return val.setInt64(v)
+ elif vType == TYPE_DELTATIME: return val.setUint64(v)
+ elif vType == TYPE_REF: return val.setObjectId(v.impl)
+ elif vType == TYPE_BOOL: return val.setBool(v)
+ elif vType == TYPE_FLOAT: return val.setFloat(v)
+ elif vType == TYPE_DOUBLE: return val.setDouble(v)
+ elif vType == TYPE_UUID: return val.setUuid(v)
+ elif vType == TYPE_INT8: return val.setInt(v)
+ elif vType == TYPE_INT16: return val.setInt(v)
+ elif vType == TYPE_INT32: return val.setInt(v)
+ elif vType == TYPE_INT64: return val.setInt64(v)
+ else:
+ # when TYPE_MAP
+ # when TYPE_OBJECT
+ # when TYPE_LIST
+ # when TYPE_ARRAY
+ print "Unsupported type for get_attr?", val.getType()
+ return None
+
+
+ def __getitem__(self, name):
+ return self.get_attr(name)
+
+
+ def __setitem__(self, name, value):
+ self.set_attr(name, value)
+
+
+ def inc_attr(self, name, by=1):
+ self.set_attr(name, self.get_attr(name) + by)
+
+
+ def dec_attr(self, name, by=1):
+ self.set_attr(name, self.get_attr(name) - by)
+
+
+ def _value(self, name):
+ val = self.impl.getValue(name)
+ if not val:
+ raise ArgumentError("Attribute '%s' not defined for class %s" % (name, self.object_class.impl.getName()))
+ return val
+
+
+
+class ConsoleObject(QmfObject):
+ # attr_reader :current_time, :create_time, :delete_time
+ def __init__(self, cls):
+ QmfObject.__init__(self, cls)
+
+
+ def update(self): pass
+ def mergeUpdate(self, newObject): pass
+ def is_deleted(self):
+ return self.delete_time > 0
+ def index(self): pass
+ def method_missing(self, name, *args): pass
+
+
+
+class ObjectId:
+ def __init__(self, impl=None):
+ if impl:
+ self.impl = impl
+ else:
+ self.impl = qmfengine.ObjectId()
+
+
+ def object_num_high(self):
+ return self.impl.getObjectNumHi()
+
+
+ def object_num_low(self):
+ return self.impl.getObjectNumLo()
+
+
+ def __eq__(self, other):
+ if self.__class__ != other.__class__: return False
+ return (self.impl.getObjectNumHi() == other.impl.getObjectNumHi() and
+ self.impl.getObjectNumLo() == other.impl.getObjectNumLo())
+
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+
+
+class Arguments:
+ def __init__(self, map):
+ self.map = map
+ self._by_hash = {}
+ key_count = self.map.keyCount()
+ a = 0
+ while a < key_count:
+ self._by_hash[self.map.key(a)] = self.by_key(self.map.key(a))
+ a += 1
+
+
+ def __getitem__(self, key):
+ return self._by_hash[key]
+
+
+ def __setitem__(self, key, value):
+ self._by_hash[key] = value
+ self.set(key, value)
+
+
+ def __iter__(self):
+ return _by_hash.__iter__
+
+
+ def by_key(self, key):
+ val = self.map.byKey(key)
+ vType = val.getType()
+ if vType == TYPE_UINT8: return val.asUint()
+ elif vType == TYPE_UINT16: return val.asUint()
+ elif vType == TYPE_UINT32: return val.asUint()
+ elif vType == TYPE_UINT64: return val.asUint64()
+ elif vType == TYPE_SSTR: return val.asString()
+ elif vType == TYPE_LSTR: return val.asString()
+ elif vType == TYPE_ABSTIME: return val.asInt64()
+ elif vType == TYPE_DELTATIME: return val.asUint64()
+ elif vType == TYPE_REF: return val.asObjectId()
+ elif vType == TYPE_BOOL: return val.asBool()
+ elif vType == TYPE_FLOAT: return val.asFloat()
+ elif vType == TYPE_DOUBLE: return val.asDouble()
+ elif vType == TYPE_UUID: return val.asUuid()
+ elif vType == TYPE_INT8: return val.asInt()
+ elif vType == TYPE_INT16: return val.asInt()
+ elif vType == TYPE_INT32: return val.asInt()
+ elif vType == TYPE_INT64: return val.asInt64()
+ else:
+ # when TYPE_MAP
+ # when TYPE_OBJECT
+ # when TYPE_LIST
+ # when TYPE_ARRAY
+ print "Unsupported Type for Get?", val.getType()
+ return None
+
+
+ def set(self, key, value):
+ val = self.map.byKey(key)
+ vType = val.getType()
+ if vType == TYPE_UINT8: return val.setUint(value)
+ elif vType == TYPE_UINT16: return val.setUint(value)
+ elif vType == TYPE_UINT32: return val.setUint(value)
+ elif vType == TYPE_UINT64: return val.setUint64(value)
+ elif vType == TYPE_SSTR:
+ if value:
+ return val.setString(value)
+ else:
+ return val.setString('')
+ elif vType == TYPE_LSTR:
+ if value:
+ return val.setString(value)
+ else:
+ return val.setString('')
+ elif vType == TYPE_ABSTIME: return val.setInt64(value)
+ elif vType == TYPE_DELTATIME: return val.setUint64(value)
+ elif vType == TYPE_REF: return val.setObjectId(value.impl)
+ elif vType == TYPE_BOOL: return val.setBool(value)
+ elif vType == TYPE_FLOAT: return val.setFloat(value)
+ elif vType == TYPE_DOUBLE: return val.setDouble(value)
+ elif vType == TYPE_UUID: return val.setUuid(value)
+ elif vType == TYPE_INT8: return val.setInt(value)
+ elif vType == TYPE_INT16: return val.setInt(value)
+ elif vType == TYPE_INT32: return val.setInt(value)
+ elif vType == TYPE_INT64: return val.setInt64(value)
+ else:
+ # when TYPE_MAP
+ # when TYPE_OBJECT
+ # when TYPE_LIST
+ # when TYPE_ARRAY
+ print "Unsupported Type for Set?", val.getType()
+ return None
+
+
+
+class Query:
+ def __init__(self, i=None):
+ if i:
+ self.impl = i
+ else:
+ self.impl = qmfengine.Query()
+
+
+ def package_name(self): return self.impl.getPackage()
+ def class_name(self): return self.impl.getClass()
+ def object_id(self):
+ _objid = self.impl.getObjectId()
+ if _objid:
+ return ObjectId(_objid)
+ else:
+ return None
+ OPER_AND = qmfengine.Query.OPER_AND
+ OPER_OR = qmfengine.Query.OPER_OR
+
+
+
+ ##==============================================================================
+ ## SCHEMA
+ ##==============================================================================
+
+
+
+class SchemaArgument:
+ #attr_reader :impl
+ def __init__(self, name, typecode, kwargs={}):
+ self.impl = qmfengine.SchemaArgument(name, typecode)
+ if kwargs.has_key("dir"): self.impl.setDirection(kwargs["dir"])
+ if kwargs.has_key("unit"): self.impl.setUnit(kwargs["unit"])
+ if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"])
+
+
+
+class SchemaMethod:
+ # attr_reader :impl
+ def __init__(self, name, kwargs={}):
+ self.impl = qmfengine.SchemaMethod(name)
+ if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"])
+ self._arguments = []
+
+
+ def add_argument(self, arg):
+ self._arguments.append(arg)
+ self.impl.addArgument(arg.impl)
+
+
+class SchemaProperty:
+ #attr_reader :impl
+ def __init__(self, name, typecode, kwargs={}):
+ self.impl = qmfengine.SchemaProperty(name, typecode)
+ if kwargs.has_key("access"): self.impl.setAccess(kwargs["access"])
+ if kwargs.has_key("index"): self.impl.setIndex(kwargs["index"])
+ if kwargs.has_key("optional"): self.impl.setOptional(kwargs["optional"])
+ if kwargs.has_key("unit"): self.impl.setUnit(kwargs["unit"])
+ if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"])
+
+
+ def name(self):
+ return self.impl.getName()
+
+
+
+class SchemaStatistic:
+ # attr_reader :impl
+ def __init__(self, name, typecode, kwargs={}):
+ self.impl = qmfengine.SchemaStatistic(name, typecode)
+ if kwargs.has_key("unit"): self.impl.setUnit(kwargs["unit"])
+ if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"])
+
+
+
+class SchemaClassKey:
+ #attr_reader :impl
+ def __init__(self, i):
+ self.impl = i
+
+
+ def get_package(self):
+ self.impl.getPackageName()
+
+
+ def get_class(self):
+ self.impl.getClassName()
+
+
+
+class SchemaObjectClass:
+ # attr_reader :impl
+ def __init__(self, package, name, kwargs={}):
+ self.impl = qmfengine.SchemaObjectClass(package, name)
+ self._properties = []
+ self._statistics = []
+ self._methods = []
+
+
+ def add_property(self, prop):
+ self._properties.append(prop)
+ self.impl.addProperty(prop.impl)
+
+
+ def add_statistic(self, stat):
+ self._statistics.append(stat)
+ self.impl.addStatistic(stat.impl)
+
+
+ def add_method(self, meth):
+ self._methods.append(meth)
+ self.impl.addMethod(meth.impl)
+
+
+ def name(self):
+ return self.impl.getName()
+
+
+ def properties(self):
+ return self._properties
+
+
+class SchemaEventClass:
+ # attr_reader :impl
+ def __init__(self, package, name, kwargs={}):
+ self.impl = qmfengine.SchemaEventClass(package, name)
+ if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"])
+ self._arguments = []
+
+
+ def add_argument(self, arg):
+ self._arguments.append(arg)
+ self.impl.addArgument(arg.impl)
+
+
+
+ ##==============================================================================
+ ## CONSOLE
+ ##==============================================================================
+
+
+
+class ConsoleHandler:
+ def agent_added(self, agent): pass
+ def agent_deleted(self, agent): pass
+ def new_package(self, package): pass
+ def new_class(self, class_key): pass
+ def object_update(self, obj, hasProps, hasStats): pass
+ def event_received(self, event): pass
+ def agent_heartbeat(self, agent, timestamp): pass
+ def method_response(self, resp): pass
+ def broker_info(self, broker): pass
+
+
+
+class Console:
+ # attr_reader :impl
+ def initialize(handler=None, kwargs={}):
+ self._handler = handler
+ self.impl = qmfengine.ConsoleEngine()
+ self._event = qmfengine.ConsoleEvent()
+ self._broker_list = []
+
+
+ def add_connection(self, conn):
+ broker = Broker(self, conn)
+ self._broker_list.append(broker)
+ return broker
+
+
+ def del_connection(self, broker): pass
+
+
+ def get_packages(self): pass
+
+
+ def get_classes(self, package): pass
+
+
+ def get_schema(self, class_key): pass
+
+
+ def bind_package(self, package): pass
+
+
+ def bind_class(self, kwargs = {}): pass
+
+
+ def get_agents(self, broker=None): pass
+
+
+ def get_objects(self, query, kwargs = {}): pass
+
+
+ def start_sync(self, query): pass
+
+
+ def touch_sync(self, sync): pass
+
+
+ def end_sync(self, sync): pass
+
+
+ def do_console_events(self):
+ count = 0
+ valid = self.impl.getEvent(self._event)
+ while valid:
+ count += 1
+ print "Console Event:", self._event.kind
+ if self._event.kind == qmfengine.ConsoleEvent.AGENT_ADDED:
+ pass
+ elif self._event.kind == qmfengine.ConsoleEvent.AGENT_DELETED:
+ pass
+ elif self._event.kind == qmfengine.ConsoleEvent.NEW_PACKAGE:
+ pass
+ elif self._event.kind == qmfengine.ConsoleEvent.NEW_CLASS:
+ pass
+ elif self._event.kind == qmfengine.ConsoleEvent.OBJECT_UPDATE:
+ pass
+ elif self._event.kind == qmfengine.ConsoleEvent.EVENT_RECEIVED:
+ pass
+ elif self._event.kind == qmfengine.ConsoleEvent.AGENT_HEARTBEAT:
+ pass
+ elif self._event.kind == qmfengine.ConsoleEvent.METHOD_RESPONSE:
+ pass
+
+ self.impl.popEvent()
+ valid = self.impl.getEvent(self._event)
+ return count
+
+
+
+class Broker(ConnectionHandler):
+ # attr_reader :impl
+ def __init__(self, console, conn):
+ self._console = console
+ self._conn = conn
+ self._session = None
+ self._event = qmfengine.BrokerEvent()
+ self._xmtMessage = qmfengine.Message()
+ self.impl = qmfengine.BrokerProxy(self._console.impl)
+ self._console.impl.addConnection(self.impl, self)
+ self._conn.add_conn_handler(self)
+
+
+ def do_broker_events(self):
+ count = 0
+ valid = self.impl.getEvent(self._event)
+ while valid:
+ count += 1
+ print "Broker Event: ", self._event.kind
+ if self._event.kind == qmfengine.BrokerEvent.BROKER_INFO:
+ pass
+ elif self._event.kind == qmfengine.BrokerEvent.DECLARE_QUEUE:
+ self._conn.impl.declareQueue(self._session.handle, self._event.name)
+ elif self._event.kind == qmfengine.BrokerEvent.DELETE_QUEUE:
+ self._conn.impl.deleteQueue(self._session.handle, self._event.name)
+ elif self._event.kind == qmfengine.BrokerEvent.BIND:
+ self._conn.impl.bind(self._session.handle, self._event.exchange, self._event.name, self._event.bindingKey)
+ elif self._event.kind == qmfengine.BrokerEvent.UNBIND:
+ self._conn.impl.unbind(self._session.handle, self._event.exchange, self._event.name, self._event.bindingKey)
+ elif self._event.kind == qmfengine.BrokerEvent.SETUP_COMPLETE:
+ self.impl.startProtocol()
+
+ self.impl.popEvent()
+ valid = self.impl.getEvent(self._event)
+
+ return count
+
+
+ def do_broker_messages(self):
+ count = 0
+ valid = self.impl.getXmtMessage(self._xmtMessage)
+ while valid:
+ count += 1
+ self._conn.impl.sendMessage(self._session.handle, self._xmtMessage)
+ self.impl.popXmt()
+ valid = self.impl.getXmtMessage(self._xmtMessage)
+
+ return count
+
+
+ def do_events(self):
+ while True:
+ ccnt = self._console.do_console_events()
+ bcnt = do_broker_events()
+ mcnt = do_broker_messages()
+ if ccnt == 0 and bcnt == 0 and mcnt == 0:
+ break;
+
+
+ def conn_event_connected(self):
+ print "Console Connection Established..."
+ self._session = Session(self._conn, "qmfc-%s.%d" % (socket.gethostname(), os.getpid()), self)
+ self.impl.sessionOpened(self._session.handle)
+ self.do_events()
+
+
+ def conn_event_disconnected(self, error):
+ print "Console Connection Lost"
+ pass
+
+
+ def sess_event_session_closed(self, context, error):
+ print "Console Session Lost"
+ self.impl.sessionClosed()
+
+
+ def sess_event_recv(self, context, message):
+ self.impl.handleRcvMessage(message)
+ self.do_events()
+
+
+
+ ##==============================================================================
+ ## AGENT
+ ##==============================================================================
+
+
+
+class AgentHandler:
+ def get_query(self, context, query, userId): None
+ def method_call(self, context, name, object_id, args, userId): None
+
+
+
+class Agent(ConnectionHandler):
+ def __init__(self, handler, label=""):
+ if label == "":
+ self._agentLabel = "rb-%s.%d" % (socket.gethostname(), os.getpid())
+ else:
+ self._agentLabel = label
+ self._conn = None
+ self._handler = handler
+ self.impl = qmfengine.AgentEngine(self._agentLabel)
+ self._event = qmfengine.AgentEvent()
+ self._xmtMessage = qmfengine.Message()
+
+
+ def set_connection(self, conn):
+ self._conn = conn
+ self._conn.add_conn_handler(self)
+
+
+ def register_class(self, cls):
+ self.impl.registerClass(cls.impl)
+
+
+ def alloc_object_id(self, low = 0, high = 0):
+ return ObjectId(self.impl.allocObjectId(low, high))
+
+
+ def query_response(self, context, obj):
+ self.impl.queryResponse(context, obj.impl)
+
+
+ def query_complete(self, context):
+ self.impl.queryComplete(context)
+
+
+ def method_response(self, context, status, text, arguments):
+ self.impl.methodResponse(context, status, text, arguments.map)
+
+
+ def do_agent_events(self):
+ count = 0
+ valid = self.impl.getEvent(self._event)
+ while valid:
+ count += 1
+ if self._event.kind == qmfengine.AgentEvent.GET_QUERY:
+ self._handler.get_query(self._event.sequence,
+ Query(self._event.query),
+ self._event.authUserId)
+
+ elif self._event.kind == qmfengine.AgentEvent.START_SYNC:
+ pass
+ elif self._event.kind == qmfengine.AgentEvent.END_SYNC:
+ pass
+ elif self._event.kind == qmfengine.AgentEvent.METHOD_CALL:
+ args = Arguments(self._event.arguments)
+ self._handler.method_call(self._event.sequence, self._event.name,
+ ObjectId(self._event.objectId),
+ args, self._event.authUserId)
+
+ elif self._event.kind == qmfengine.AgentEvent.DECLARE_QUEUE:
+ self._conn.impl.declareQueue(self._session.handle, self._event.name)
+
+ elif self._event.kind == qmfengine.AgentEvent.DELETE_QUEUE:
+ self._conn.impl.deleteQueue(self._session.handle, self._event.name)
+
+ elif self._event.kind == qmfengine.AgentEvent.BIND:
+ self._conn.impl.bind(self._session.handle, self._event.exchange,
+ self._event.name, self._event.bindingKey)
+
+ elif self._event.kind == qmfengine.AgentEvent.UNBIND:
+ self._conn.impl.unbind(self._session.handle, self._event.exchange,
+ self._event.name, self._event.bindingKey)
+
+ elif self._event.kind == qmfengine.AgentEvent.SETUP_COMPLETE:
+ self.impl.startProtocol()
+
+ self.impl.popEvent()
+ valid = self.impl.getEvent(self._event)
+ return count
+
+
+ def do_agent_messages(self):
+ count = 0
+ valid = self.impl.getXmtMessage(self._xmtMessage)
+ while valid:
+ count += 1
+ self._conn.impl.sendMessage(self._session.handle, self._xmtMessage)
+ self.impl.popXmt()
+ valid = self.impl.getXmtMessage(self._xmtMessage)
+ return count
+
+
+ def do_events(self):
+ while True:
+ ecnt = self.do_agent_events()
+ mcnt = self.do_agent_messages()
+ if ecnt == 0 and mcnt == 0:
+ break
+
+
+ def conn_event_connected(self):
+ print "Agent Connection Established..."
+ self._session = Session(self._conn,
+ "qmfa-%s.%d" % (socket.gethostname(), os.getpid()),
+ self)
+ self.impl.newSession()
+ self.do_events()
+
+
+ def conn_event_disconnected(self, error):
+ print "Agent Connection Lost"
+ pass
+
+
+ def sess_event_session_closed(self, context, error):
+ print "Agent Session Lost"
+ pass
+
+
+ def sess_event_recv(self, context, message):
+ self.impl.handleRcvMessage(message)
+ self.do_events()
+
+
diff --git a/qpid/cpp/bindings/qmf/qmfengine.i b/qpid/cpp/bindings/qmf/qmfengine.i
index 3c67d92031..d3500c9b8f 100644
--- a/qpid/cpp/bindings/qmf/qmfengine.i
+++ b/qpid/cpp/bindings/qmf/qmfengine.i
@@ -19,24 +19,24 @@
%{
-#include "Agent.h"
-#include <ResilientConnection.h>
+#include "qmf/AgentEngine.h"
+#include "qmf/ConsoleEngine.h"
+#include "qmf/ResilientConnection.h"
%}
-
-%include <Query.h>
-%include <Message.h>
-%include <Agent.h>
-%include <ResilientConnection.h>
-%include <Typecode.h>
-%include <Schema.h>
-%include <Value.h>
-%include <ObjectId.h>
-%include <Object.h>
-
-%include <qpid/client/ClientImportExport.h>
-%include <qpid/client/ConnectionSettings.h>
+%include <qmf/QmfImportExport.h>
+%include <qmf/Query.h>
+%include <qmf/Message.h>
+%include <qmf/AgentEngine.h>
+%include <qmf/ConsoleEngine.h>
+%include <qmf/ConnectionSettings.h>
+%include <qmf/ResilientConnection.h>
+%include <qmf/Typecode.h>
+%include <qmf/Schema.h>
+%include <qmf/Value.h>
+%include <qmf/ObjectId.h>
+%include <qmf/Object.h>
%inline {
diff --git a/qpid/cpp/bindings/qmf/ruby/Makefile.am b/qpid/cpp/bindings/qmf/ruby/Makefile.am
index 532fdb6875..0537dd1cd8 100644
--- a/qpid/cpp/bindings/qmf/ruby/Makefile.am
+++ b/qpid/cpp/bindings/qmf/ruby/Makefile.am
@@ -19,7 +19,7 @@
if HAVE_RUBY_DEVEL
-INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src/qmf -I$(top_srcdir)/src -I$(top_builddir)/src
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src
EXTRA_DIST = ruby.i
BUILT_SOURCES = qmfengine.cpp
@@ -36,7 +36,7 @@ rubylibarchdir = $(RUBY_LIB_ARCH)
rubylibarch_LTLIBRARIES = qmfengine.la
qmfengine_la_LDFLAGS = -avoid-version -module -shrext ".$(RUBY_DLEXT)"
-qmfengine_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidclient $(top_builddir)/src/libqmfcommon.la
+qmfengine_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidclient $(top_builddir)/src/libqmfagent.la
qmfengine_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH)
nodist_qmfengine_la_SOURCES = qmfengine.cpp
diff --git a/qpid/cpp/bindings/qmf/ruby/qmf.rb b/qpid/cpp/bindings/qmf/ruby/qmf.rb
index 7ee447c675..21fbf6c157 100644
--- a/qpid/cpp/bindings/qmf/ruby/qmf.rb
+++ b/qpid/cpp/bindings/qmf/ruby/qmf.rb
@@ -20,517 +20,846 @@
require 'qmfengine'
require 'thread'
require 'socket'
+require 'monitor'
module Qmf
- # Pull all the TYPE_* constants into Qmf namespace. Maybe there's an easier way?
- Qmfengine.constants.each do |c|
- if c.index('TYPE_') == 0 or c.index('ACCESS_') == 0 or c.index('DIR_') == 0
- const_set(c, Qmfengine.const_get(c))
- end
+ # Pull all the TYPE_* constants into Qmf namespace. Maybe there's an easier way?
+ Qmfengine.constants.each do |c|
+ if c.index('TYPE_') == 0 or c.index('ACCESS_') == 0 or c.index('DIR_') == 0 or c.index('CLASS_') == 0
+ const_set(c, Qmfengine.const_get(c))
end
+ end
+
+ ##==============================================================================
+ ## CONNECTION
+ ##==============================================================================
- class ConnectionSettings < Qmfengine::ConnectionSettings
+ class ConnectionSettings
+ attr_reader :impl
+
+ def initialize(url = nil)
+ if url
+ @impl = Qmfengine::ConnectionSettings.new(url)
+ else
+ @impl = Qmfengine::ConnectionSettings.new()
+ end
end
- class ConnectionEvent
- def conn_event_connected(); end
- def conn_event_disconnected(error); end
- def conn_event_session_closed(context, error); end
- def conn_event_recv(context, message); end
+ def set_attr(key, val)
+ if val.class == String
+ v = Qmfengine::Value.new(TYPE_LSTR)
+ v.setString(val)
+ elsif val.class == TrueClass or val.class == FalseClass
+ v = Qmfengine::Value.new(TYPE_BOOL)
+ v.setBool(val)
+ elsif val.class == Fixnum
+ v = Qmfengine::Value.new(TYPE_UINT32)
+ v.setUint(val)
+ else
+ raise ArgumentError, "Value for attribute '#{key}' has unsupported type: #{val.class}"
+ end
+
+ @impl.setAttr(key, v)
end
+ end
- class Query
- attr_reader :impl
- def initialize(i)
- @impl = i
- end
+ class ConnectionHandler
+ def conn_event_connected(); end
+ def conn_event_disconnected(error); end
+ def sess_event_session_closed(context, error); end
+ def sess_event_recv(context, message); end
+ end
- def package_name
- @impl.getPackage
- end
+ class Connection
+ include MonitorMixin
- def class_name
- @impl.getClass
- end
+ attr_reader :impl
- def object_id
- objid = @impl.getObjectId
- if objid.class == NilClass
- return nil
- end
- return ObjectId.new(objid)
+ def initialize(settings)
+ super()
+ @impl = Qmfengine::ResilientConnection.new(settings.impl)
+ @sockEngine, @sock = Socket::socketpair(Socket::PF_UNIX, Socket::SOCK_STREAM, 0)
+ @impl.setNotifyFd(@sockEngine.fileno)
+ @new_conn_handlers = []
+ @conn_handlers = []
+
+ @thread = Thread.new do
+ run
end
end
- class AgentHandler
- def get_query(context, query, userId); end
- def method_call(context, name, object_id, args, userId); end
+ def add_conn_handler(handler)
+ synchronize do
+ @new_conn_handlers << handler
+ end
+ @sockEngine.write("x")
end
- class Connection
- attr_reader :impl
+ def run()
+ eventImpl = Qmfengine::ResilientConnectionEvent.new
+ connected = nil
+ new_handlers = nil
+ bt_count = 0
- def initialize(settings, event_handler = nil, delay_min = 1, delay_max = 128, delay_factor = 2)
- @impl = Qmfengine::ResilientConnection.new(settings, delay_min, delay_max, delay_factor)
- @sockEngine, @sock = Socket::socketpair(Socket::PF_UNIX, Socket::SOCK_STREAM, 0)
- @impl.setNotifyFd(@sockEngine.fileno)
- @new_conn_handlers = Array.new
- @conn_handlers = Array.new
- @sess_handlers = Array.new
+ while :true
+ @sock.read(1)
- @thread = Thread.new do
- run
+ synchronize do
+ new_handlers = @new_conn_handlers
+ @new_conn_handlers = []
end
- end
-
- def add_conn_handler(handler)
- @new_conn_handlers.push(handler)
- @sockEngine.write("x")
- end
- def add_sess_handler(handler)
- @sess_handlers.push(handler)
- end
-
- def run()
- event = Qmfengine::ResilientConnectionEvent.new
- connected = nil
- while :true
- @sock.read(1)
+ new_handlers.each do |nh|
+ @conn_handlers << nh
+ nh.conn_event_connected() if connected
+ end
+ new_handlers = nil
- @new_conn_handlers.each do |nh|
- @conn_handlers.push(nh)
- nh.conn_event_connected() if connected
- end
- @new_conn_handlers = Array.new
-
- valid = @impl.getEvent(event)
- while valid
- begin
- case event.kind
- when Qmfengine::ResilientConnectionEvent::CONNECTED
- connected = :true
- @conn_handlers.each { |h| h.conn_event_connected() }
- when Qmfengine::ResilientConnectionEvent::DISCONNECTED
- connected = nil
- @conn_handlers.each { |h| h.conn_event_disconnected(event.errorText) }
- when Qmfengine::ResilientConnectionEvent::SESSION_CLOSED
- event.sessionContext.handler.sess_event_session_closed(event.sessionContext, event.errorText)
- when Qmfengine::ResilientConnectionEvent::RECV
- event.sessionContext.handler.sess_event_recv(event.sessionContext, event.message)
- end
- rescue Exception => ex
- puts "Event Exception: #{ex}"
+ valid = @impl.getEvent(eventImpl)
+ while valid
+ begin
+ case eventImpl.kind
+ when Qmfengine::ResilientConnectionEvent::CONNECTED
+ connected = :true
+ @conn_handlers.each { |h| h.conn_event_connected() }
+ when Qmfengine::ResilientConnectionEvent::DISCONNECTED
+ connected = nil
+ @conn_handlers.each { |h| h.conn_event_disconnected(eventImpl.errorText) }
+ when Qmfengine::ResilientConnectionEvent::SESSION_CLOSED
+ eventImpl.sessionContext.handler.sess_event_session_closed(eventImpl.sessionContext, eventImpl.errorText)
+ when Qmfengine::ResilientConnectionEvent::RECV
+ eventImpl.sessionContext.handler.sess_event_recv(eventImpl.sessionContext, eventImpl.message)
+ end
+ rescue Exception => ex
+ puts "Event Exception: #{ex}"
+ if bt_count < 2
puts ex.backtrace
+ bt_count += 1
end
- @impl.popEvent
- valid = @impl.getEvent(event)
end
+ @impl.popEvent
+ valid = @impl.getEvent(eventImpl)
end
end
end
+ end
- class Session
- attr_reader :handle, :handler
+ class Session
+ attr_reader :handle, :handler
- def initialize(conn, label, handler)
- @conn = conn
- @label = label
- @handler = handler
- @handle = Qmfengine::SessionHandle.new
- @conn.add_sess_handler(@handler)
- result = @conn.impl.createSession(label, self, @handle)
- end
+ def initialize(conn, label, handler)
+ @conn = conn
+ @label = label
+ @handler = handler
+ @handle = Qmfengine::SessionHandle.new
+ result = @conn.impl.createSession(label, self, @handle)
end
- class ObjectId
- attr_reader :impl
- def initialize(impl=nil)
- if impl
- @impl = impl
- else
- @impl = Qmfengine::ObjectId.new
- end
- end
- def object_num_high
- return @impl.getObjectNumHi
- end
- def object_num_low
- return @impl.getObjectNumLo
- end
+ def destroy()
+ @conn.impl.destroySession(@handle)
end
+ end
- class Arguments
- attr_reader :map
- def initialize(map)
- @map = map
- @by_hash = {}
- key_count = @map.keyCount
- a = 0
- while a < key_count
- @by_hash[@map.key(a)] = by_key(@map.key(a))
- a += 1
- end
- end
+ ##==============================================================================
+ ## OBJECTS
+ ##==============================================================================
- def [] (key)
- return @by_hash[key]
- end
+ class QmfObject
+ attr_reader :impl, :object_class
+ def initialize(cls)
+ @object_class = cls
+ @impl = Qmfengine::Object.new(@object_class.impl)
+ end
- def []= (key, value)
- @by_hash[key] = value
- set(key, value)
- end
+ def destroy
+ @impl.destroy
+ end
- def each
- @by_hash.each { |k, v| yield(k, v) }
- end
+ def object_id
+ return ObjectId.new(@impl.getObjectId)
+ end
- def by_key(key)
- val = @map.byKey(key)
- case val.getType
- when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.asUint
- when TYPE_UINT64 then val.asUint64
- when TYPE_SSTR, TYPE_LSTR then val.asString
- when TYPE_ABSTIME then val.asInt64
- when TYPE_DELTATIME then val.asUint64
- when TYPE_REF then val.asObjectId
- when TYPE_BOOL then val.asBool
- when TYPE_FLOAT then val.asFloat
- when TYPE_DOUBLE then val.asDouble
- when TYPE_UUID then val.asUuid
- when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.asInt
- when TYPE_INT64 then val.asInt64
- when TYPE_MAP
- when TYPE_OBJECT
- when TYPE_LIST
- when TYPE_ARRAY
- end
- end
+ def set_object_id(oid)
+ @impl.setObjectId(oid.impl)
+ end
- def set(key, value)
- val = @map.byKey(key)
- case val.getType
- when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.setUint(value)
- when TYPE_UINT64 then val.setUint64(value)
- when TYPE_SSTR, TYPE_LSTR then value ? val.setString(value) : val.setString('')
- when TYPE_ABSTIME then val.setInt64(value)
- when TYPE_DELTATIME then val.setUint64(value)
- when TYPE_REF then val.setObjectId(value.impl)
- when TYPE_BOOL then value ? val.setBool(value) : val.setBool(0)
- when TYPE_FLOAT then val.setFloat(value)
- when TYPE_DOUBLE then val.setDouble(value)
- when TYPE_UUID then val.setUuid(value)
- when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.setInt(value)
- when TYPE_INT64 then val.setInt64(value)
- when TYPE_MAP
- when TYPE_OBJECT
- when TYPE_LIST
- when TYPE_ARRAY
- end
+ def get_attr(name)
+ val = value(name)
+ case val.getType
+ when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.asUint
+ when TYPE_UINT64 then val.asUint64
+ when TYPE_SSTR, TYPE_LSTR then val.asString
+ when TYPE_ABSTIME then val.asInt64
+ when TYPE_DELTATIME then val.asUint64
+ when TYPE_REF then val.asObjectId
+ when TYPE_BOOL then val.asBool
+ when TYPE_FLOAT then val.asFloat
+ when TYPE_DOUBLE then val.asDouble
+ when TYPE_UUID then val.asUuid
+ when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.asInt
+ when TYPE_INT64 then val.asInt64
+ when TYPE_MAP
+ when TYPE_OBJECT
+ when TYPE_LIST
+ when TYPE_ARRAY
end
end
- class Agent
- def initialize(handler, label="")
- if label == ""
- @agentLabel = "rb-%s.%d" % [Socket.gethostname, Process::pid]
- else
- @agentLabel = label
- end
- @conn = nil
- @handler = handler
- @impl = Qmfengine::Agent.new(@agentLabel)
- @event = Qmfengine::AgentEvent.new
- @xmtMessage = Qmfengine::Message.new
+ def set_attr(name, v)
+ val = value(name)
+ case val.getType
+ when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.setUint(v)
+ when TYPE_UINT64 then val.setUint64(v)
+ when TYPE_SSTR, TYPE_LSTR then v ? val.setString(v) : val.setString('')
+ when TYPE_ABSTIME then val.setInt64(v)
+ when TYPE_DELTATIME then val.setUint64(v)
+ when TYPE_REF then val.setObjectId(v.impl)
+ when TYPE_BOOL then v ? val.setBool(v) : val.setBool(0)
+ when TYPE_FLOAT then val.setFloat(v)
+ when TYPE_DOUBLE then val.setDouble(v)
+ when TYPE_UUID then val.setUuid(v)
+ when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.setInt(v)
+ when TYPE_INT64 then val.setInt64(v)
+ when TYPE_MAP
+ when TYPE_OBJECT
+ when TYPE_LIST
+ when TYPE_ARRAY
end
+ end
- def set_connection(conn)
- @conn = conn
- @conn.add_conn_handler(self)
- end
+ def [](name)
+ get_attr(name)
+ end
- def register_class(cls)
- @impl.registerClass(cls.impl)
- end
+ def []=(name, value)
+ set_attr(name, value)
+ end
- def alloc_object_id(low = 0, high = 0)
- ObjectId.new(@impl.allocObjectId(low, high))
- end
+ def inc_attr(name, by=1)
+ set_attr(name, get_attr(name) + by)
+ end
- def query_response(context, object)
- @impl.queryResponse(context, object.impl)
- end
+ def dec_attr(name, by=1)
+ set_attr(name, get_attr(name) - by)
+ end
- def query_complete(context)
- @impl.queryComplete(context)
+ private
+ def value(name)
+ val = @impl.getValue(name.to_s)
+ if val.nil?
+ raise ArgumentError, "Attribute '#{name}' not defined for class #{@object_class.impl.getName}"
end
+ return val
+ end
+ end
- def method_response(context, status, text, arguments)
- @impl.methodResponse(context, status, text, arguments.map)
- end
+ class ConsoleObject < QmfObject
+ attr_reader :current_time, :create_time, :delete_time
- def do_agent_events()
- count = 0
- valid = @impl.getEvent(@event)
- while valid
- count += 1
- case @event.kind
- when Qmfengine::AgentEvent::GET_QUERY
- @handler.get_query(@event.sequence, Query.new(@event.query), @event.authUserId)
- when Qmfengine::AgentEvent::START_SYNC
- when Qmfengine::AgentEvent::END_SYNC
- when Qmfengine::AgentEvent::METHOD_CALL
- args = Arguments.new(@event.arguments)
- @handler.method_call(@event.sequence, @event.name, ObjectId.new(@event.objectId),
- args, @event.authUserId)
- when Qmfengine::AgentEvent::DECLARE_QUEUE
- @conn.impl.declareQueue(@session.handle, @event.name)
- when Qmfengine::AgentEvent::DELETE_QUEUE
- @conn.impl.deleteQueue(@session.handle, @event.name)
- when Qmfengine::AgentEvent::BIND
- @conn.impl.bind(@session.handle, @event.exchange, @event.name, @event.bindingKey)
- when Qmfengine::AgentEvent::UNBIND
- @conn.impl.unbind(@session.handle, @event.exchange, @event.name, @event.bindingKey)
- when Qmfengine::AgentEvent::SETUP_COMPLETE
- @impl.startProtocol()
- end
- @impl.popEvent
- valid = @impl.getEvent(@event)
- end
- return count
- end
+ def initialize(cls)
+ super(cls)
+ end
- def do_agent_messages()
- count = 0
- valid = @impl.getXmtMessage(@xmtMessage)
- while valid
- count += 1
- @conn.impl.sendMessage(@session.handle, @xmtMessage)
- @impl.popXmt
- valid = @impl.getXmtMessage(@xmtMessage)
- end
- return count
- end
+ def update()
+ end
- def do_events()
- begin
- ecnt = do_agent_events
- mcnt = do_agent_messages
- end until ecnt == 0 and mcnt == 0
- end
+ def mergeUpdate(newObject)
+ end
- def conn_event_connected()
- puts "Agent Connection Established..."
- @session = Session.new(@conn, "qmfa-%s.%d" % [Socket.gethostname, Process::pid], self)
- @impl.newSession
- do_events
- end
+ def deleted?()
+ @delete_time > 0
+ end
- def conn_event_disconnected(error)
- puts "Agent Connection Lost"
- end
+ def index()
+ end
- def sess_event_session_closed(context, error)
- puts "Agent Session Lost"
- end
+ def method_missing(name, *args)
+ end
+ end
- def sess_event_recv(context, message)
- @impl.handleRcvMessage(message)
- do_events
+ class ObjectId
+ attr_reader :impl
+ def initialize(impl=nil)
+ if impl
+ @impl = impl
+ else
+ @impl = Qmfengine::ObjectId.new
end
end
- class SchemaArgument
- attr_reader :impl
- def initialize(name, typecode, kwargs={})
- @impl = Qmfengine::SchemaArgument.new(name, typecode)
- @impl.setDirection(kwargs[:dir]) if kwargs.include?(:dir)
- @impl.setUnit(kwargs[:unit]) if kwargs.include?(:unit)
- @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
- end
+ def object_num_high
+ return @impl.getObjectNumHi
end
- class SchemaMethod
- attr_reader :impl
- def initialize(name, kwargs={})
- @impl = Qmfengine::SchemaMethod.new(name)
- @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
- @arguments = []
- end
+ def object_num_low
+ return @impl.getObjectNumLo
+ end
- def add_argument(arg)
- @arguments << arg
- @impl.addArgument(arg.impl)
+ def ==(other)
+ return (@impl.getObjectNumHi == other.impl.getObjectNumHi) &&
+ (@impl.getObjectNumLo == other.impl.getObjectNumLo)
+ end
+ end
+
+ class Arguments
+ attr_reader :map
+ def initialize(map)
+ @map = map
+ @by_hash = {}
+ key_count = @map.keyCount
+ a = 0
+ while a < key_count
+ @by_hash[@map.key(a)] = by_key(@map.key(a))
+ a += 1
end
end
- class SchemaProperty
- attr_reader :impl
- def initialize(name, typecode, kwargs={})
- @impl = Qmfengine::SchemaProperty.new(name, typecode)
- @impl.setAccess(kwargs[:access]) if kwargs.include?(:access)
- @impl.setIndex(kwargs[:index]) if kwargs.include?(:index)
- @impl.setOptional(kwargs[:optional]) if kwargs.include?(:optional)
- @impl.setUnit(kwargs[:unit]) if kwargs.include?(:unit)
- @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
+ def [] (key)
+ return @by_hash[key]
+ end
+
+ def []= (key, value)
+ @by_hash[key] = value
+ set(key, value)
+ end
+
+ def each
+ @by_hash.each { |k, v| yield(k, v) }
+ end
+
+ def by_key(key)
+ val = @map.byKey(key)
+ case val.getType
+ when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.asUint
+ when TYPE_UINT64 then val.asUint64
+ when TYPE_SSTR, TYPE_LSTR then val.asString
+ when TYPE_ABSTIME then val.asInt64
+ when TYPE_DELTATIME then val.asUint64
+ when TYPE_REF then val.asObjectId
+ when TYPE_BOOL then val.asBool
+ when TYPE_FLOAT then val.asFloat
+ when TYPE_DOUBLE then val.asDouble
+ when TYPE_UUID then val.asUuid
+ when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.asInt
+ when TYPE_INT64 then val.asInt64
+ when TYPE_MAP
+ when TYPE_OBJECT
+ when TYPE_LIST
+ when TYPE_ARRAY
end
+ end
- def name
- @impl.getName
+ def set(key, value)
+ val = @map.byKey(key)
+ case val.getType
+ when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.setUint(value)
+ when TYPE_UINT64 then val.setUint64(value)
+ when TYPE_SSTR, TYPE_LSTR then value ? val.setString(value) : val.setString('')
+ when TYPE_ABSTIME then val.setInt64(value)
+ when TYPE_DELTATIME then val.setUint64(value)
+ when TYPE_REF then val.setObjectId(value.impl)
+ when TYPE_BOOL then value ? val.setBool(value) : val.setBool(0)
+ when TYPE_FLOAT then val.setFloat(value)
+ when TYPE_DOUBLE then val.setDouble(value)
+ when TYPE_UUID then val.setUuid(value)
+ when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.setInt(value)
+ when TYPE_INT64 then val.setInt64(value)
+ when TYPE_MAP
+ when TYPE_OBJECT
+ when TYPE_LIST
+ when TYPE_ARRAY
end
end
+ end
- class SchemaStatistic
- attr_reader :impl
- def initialize(name, typecode, kwargs={})
- @impl = Qmfengine::SchemaStatistic.new(name, typecode)
- @impl.setUnit(kwargs[:unit]) if kwargs.include?(:unit)
- @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
+ class Query
+ attr_reader :impl
+ def initialize(i)
+ @impl = i
+ end
+
+ def package_name
+ @impl.getPackage
+ end
+
+ def class_name
+ @impl.getClass
+ end
+
+ def object_id
+ objid = @impl.getObjectId
+ if objid.class == NilClass
+ return nil
end
+ return ObjectId.new(objid)
+ end
+ end
+
+ ##==============================================================================
+ ## SCHEMA
+ ##==============================================================================
+
+ class SchemaArgument
+ attr_reader :impl
+ def initialize(name, typecode, kwargs={})
+ @impl = Qmfengine::SchemaArgument.new(name, typecode)
+ @impl.setDirection(kwargs[:dir]) if kwargs.include?(:dir)
+ @impl.setUnit(kwargs[:unit]) if kwargs.include?(:unit)
+ @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
+ end
+ end
+
+ class SchemaMethod
+ attr_reader :impl
+ def initialize(name, kwargs={})
+ @impl = Qmfengine::SchemaMethod.new(name)
+ @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
+ @arguments = []
+ end
+
+ def add_argument(arg)
+ @arguments << arg
+ @impl.addArgument(arg.impl)
+ end
+ end
+
+ class SchemaProperty
+ attr_reader :impl
+ def initialize(name, typecode, kwargs={})
+ @impl = Qmfengine::SchemaProperty.new(name, typecode)
+ @impl.setAccess(kwargs[:access]) if kwargs.include?(:access)
+ @impl.setIndex(kwargs[:index]) if kwargs.include?(:index)
+ @impl.setOptional(kwargs[:optional]) if kwargs.include?(:optional)
+ @impl.setUnit(kwargs[:unit]) if kwargs.include?(:unit)
+ @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
+ end
+
+ def name
+ @impl.getName
+ end
+ end
+
+ class SchemaStatistic
+ attr_reader :impl
+ def initialize(name, typecode, kwargs={})
+ @impl = Qmfengine::SchemaStatistic.new(name, typecode)
+ @impl.setUnit(kwargs[:unit]) if kwargs.include?(:unit)
+ @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
end
+ end
- class SchemaObjectClass
- attr_reader :impl
- def initialize(package, name, kwargs={})
+ class SchemaClassKey
+ attr_reader :impl
+ def initialize(i)
+ @impl = i
+ end
+
+ def get_package()
+ @impl.getPackageName()
+ end
+
+ def get_class()
+ @impl.getClassName()
+ end
+ end
+
+ class SchemaObjectClass
+ attr_reader :impl
+ def initialize(package='', name='', kwargs={})
+ @properties = []
+ @statistics = []
+ @methods = []
+ if kwargs.include?(:impl)
+ @impl = kwargs[:impl]
+ else
@impl = Qmfengine::SchemaObjectClass.new(package, name)
- @properties = []
- @statistics = []
- @methods = []
end
+ end
- def add_property(prop)
- @properties << prop
- @impl.addProperty(prop.impl)
- end
+ def add_property(prop)
+ @properties << prop
+ @impl.addProperty(prop.impl)
+ end
- def add_statistic(stat)
- @statistics << stat
- @impl.addStatistic(stat.impl)
- end
+ def add_statistic(stat)
+ @statistics << stat
+ @impl.addStatistic(stat.impl)
+ end
- def add_method(meth)
- @methods << meth
- @impl.addMethod(meth.impl)
- end
+ def add_method(meth)
+ @methods << meth
+ @impl.addMethod(meth.impl)
+ end
- def name
- @impl.getName
- end
+ def name
+ @impl.getClassKey.getClassName
+ end
- def properties
- unless @properties
- @properties = []
- @impl.getPropertyCount.times do |i|
- @properties << @impl.getProperty(i)
- end
+ def properties
+ unless @properties
+ @properties = []
+ @impl.getPropertyCount.times do |i|
+ @properties << @impl.getProperty(i)
end
- return @properties
end
+ return @properties
end
-
- class SchemaEventClass
- attr_reader :impl
- def initialize(package, name, kwargs={})
+ end
+
+ class SchemaEventClass
+ attr_reader :impl
+ def initialize(package='', name='', kwargs={})
+ @arguments = []
+ if kwargs.include?(:impl)
+ @impl = kwargs[:impl]
+ else
@impl = Qmfengine::SchemaEventClass.new(package, name)
@impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc)
- @arguments = []
end
+ end
- def add_argument(arg)
- @arguments << arg
- @impl.addArgument(arg.impl)
- end
+ def add_argument(arg)
+ @arguments << arg
+ @impl.addArgument(arg.impl)
end
- class QmfObject
- attr_reader :impl, :object_class
- def initialize(cls)
- @object_class = cls
- @impl = Qmfengine::Object.new(@object_class.impl)
- end
+ def name
+ @impl.getClassKey.getClassName
+ end
+ end
+
+ ##==============================================================================
+ ## CONSOLE
+ ##==============================================================================
+
+ class ConsoleHandler
+ def agent_added(agent); end
+ def agent_deleted(agent); end
+ def new_package(package); end
+ def new_class(class_key); end
+ def object_update(object, hasProps, hasStats); end
+ def event_received(event); end
+ def agent_heartbeat(agent, timestamp); end
+ def method_response(resp); end
+ def broker_info(broker); end
+ end
+
+ class Console
+ attr_reader :impl
+
+ def initialize(handler = nil, kwargs={})
+ @handler = handler
+ @impl = Qmfengine::ConsoleEngine.new
+ @event = Qmfengine::ConsoleEvent.new
+ @broker_list = []
+ end
- def destroy
- @impl.destroy
- end
+ def add_connection(conn)
+ broker = Broker.new(self, conn)
+ @broker_list << broker
+ return broker
+ end
- def object_id
- return ObjectId.new(@impl.getObjectId)
- end
+ def del_connection(broker)
+ end
- def set_object_id(oid)
- @impl.setObjectId(oid.impl)
+ def get_packages()
+ plist = []
+ count = @impl.packageCount
+ for i in 0...count
+ plist << @impl.getPackageName(i)
end
+ return plist
+ end
- def get_attr(name)
- val = value(name)
- case val.getType
- when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.asUint
- when TYPE_UINT64 then val.asUint64
- when TYPE_SSTR, TYPE_LSTR then val.asString
- when TYPE_ABSTIME then val.asInt64
- when TYPE_DELTATIME then val.asUint64
- when TYPE_REF then val.asObjectId
- when TYPE_BOOL then val.asBool
- when TYPE_FLOAT then val.asFloat
- when TYPE_DOUBLE then val.asDouble
- when TYPE_UUID then val.asUuid
- when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.asInt
- when TYPE_INT64 then val.asInt64
- when TYPE_MAP
- when TYPE_OBJECT
- when TYPE_LIST
- when TYPE_ARRAY
+ def get_classes(package, kind=CLASS_OBJECT)
+ clist = []
+ count = @impl.classCount(package)
+ for i in 0...count
+ key = @impl.getClass(package, i)
+ class_kind = @impl.getClassKind(key)
+ if class_kind == kind
+ if kind == CLASS_OBJECT
+ clist << SchemaObjectClass.new('', '', :impl => @impl.getObjectClass(key))
+ elsif kind == CLASS_EVENT
+ clist << SchemaEventClass.new('', '', :impl => @impl.getEventClass(key))
+ end
end
end
- def set_attr(name, v)
- val = value(name)
- case val.getType
- when TYPE_UINT8, TYPE_UINT16, TYPE_UINT32 then val.setUint(v)
- when TYPE_UINT64 then val.setUint64(v)
- when TYPE_SSTR, TYPE_LSTR then v ? val.setString(v) : val.setString('')
- when TYPE_ABSTIME then val.setInt64(v)
- when TYPE_DELTATIME then val.setUint64(v)
- when TYPE_REF then val.setObjectId(v.impl)
- when TYPE_BOOL then v ? val.setBool(v) : val.setBool(0)
- when TYPE_FLOAT then val.setFloat(v)
- when TYPE_DOUBLE then val.setDouble(v)
- when TYPE_UUID then val.setUuid(v)
- when TYPE_INT8, TYPE_INT16, TYPE_INT32 then val.setInt(v)
- when TYPE_INT64 then val.setInt64(v)
- when TYPE_MAP
- when TYPE_OBJECT
- when TYPE_LIST
- when TYPE_ARRAY
+ return clist
+ end
+
+ def get_schema(class_key)
+ end
+
+ def bind_package(package)
+ end
+
+ def bind_class(kwargs = {})
+ end
+
+ def get_agents(broker = nil)
+ end
+
+ def get_objects(query, kwargs = {})
+ end
+
+ def start_sync(query)
+ end
+
+ def touch_sync(sync)
+ end
+
+ def end_sync(sync)
+ end
+
+ def do_console_events()
+ count = 0
+ valid = @impl.getEvent(@event)
+ while valid
+ count += 1
+ puts "Console Event: #{@event.kind}"
+ case @event.kind
+ when Qmfengine::ConsoleEvent::AGENT_ADDED
+ when Qmfengine::ConsoleEvent::AGENT_DELETED
+ when Qmfengine::ConsoleEvent::NEW_PACKAGE
+ when Qmfengine::ConsoleEvent::NEW_CLASS
+ when Qmfengine::ConsoleEvent::OBJECT_UPDATE
+ when Qmfengine::ConsoleEvent::EVENT_RECEIVED
+ when Qmfengine::ConsoleEvent::AGENT_HEARTBEAT
+ when Qmfengine::ConsoleEvent::METHOD_RESPONSE
end
+ @impl.popEvent
+ valid = @impl.getEvent(@event)
end
+ return count
+ end
+ end
+
+ class Broker < ConnectionHandler
+ include MonitorMixin
+ attr_reader :impl
+
+ def initialize(console, conn)
+ super()
+ @console = console
+ @conn = conn
+ @session = nil
+ @cv = new_cond
+ @stable = nil
+ @event = Qmfengine::BrokerEvent.new
+ @xmtMessage = Qmfengine::Message.new
+ @impl = Qmfengine::BrokerProxy.new(@console.impl)
+ @console.impl.addConnection(@impl, self)
+ @conn.add_conn_handler(self)
+ end
- def [](name)
- get_attr(name)
+ def waitForStable(timeout = nil)
+ synchronize do
+ return if @stable
+ if timeout
+ unless @cv.wait(timeout) { @stable }
+ raise "Timed out waiting for broker connection to become stable"
+ end
+ else
+ while not @stable
+ @cv.wait
+ end
+ end
end
+ end
- def []=(name, value)
- set_attr(name, value)
+ def do_broker_events()
+ count = 0
+ valid = @impl.getEvent(@event)
+ while valid
+ count += 1
+ puts "Broker Event: #{@event.kind}"
+ case @event.kind
+ when Qmfengine::BrokerEvent::BROKER_INFO
+ when Qmfengine::BrokerEvent::DECLARE_QUEUE
+ @conn.impl.declareQueue(@session.handle, @event.name)
+ when Qmfengine::BrokerEvent::DELETE_QUEUE
+ @conn.impl.deleteQueue(@session.handle, @event.name)
+ when Qmfengine::BrokerEvent::BIND
+ @conn.impl.bind(@session.handle, @event.exchange, @event.name, @event.bindingKey)
+ when Qmfengine::BrokerEvent::UNBIND
+ @conn.impl.unbind(@session.handle, @event.exchange, @event.name, @event.bindingKey)
+ when Qmfengine::BrokerEvent::SETUP_COMPLETE
+ @impl.startProtocol
+ when Qmfengine::BrokerEvent::STABLE
+ synchronize do
+ @stable = :true
+ @cv.signal
+ end
+ end
+ @impl.popEvent
+ valid = @impl.getEvent(@event)
end
+ return count
+ end
- def inc_attr(name, by=1)
- set_attr(name, get_attr(name) + by)
+ def do_broker_messages()
+ count = 0
+ valid = @impl.getXmtMessage(@xmtMessage)
+ while valid
+ count += 1
+ @conn.impl.sendMessage(@session.handle, @xmtMessage)
+ @impl.popXmt
+ valid = @impl.getXmtMessage(@xmtMessage)
end
+ return count
+ end
+
+ def do_events()
+ begin
+ ccnt = @console.do_console_events
+ bcnt = do_broker_events
+ mcnt = do_broker_messages
+ end until ccnt == 0 and bcnt == 0 and mcnt == 0
+ end
- def dec_attr(name, by=1)
- set_attr(name, get_attr(name) - by)
+ def conn_event_connected()
+ puts "Console Connection Established..."
+ @session = Session.new(@conn, "qmfc-%s.%d" % [Socket.gethostname, Process::pid], self)
+ @impl.sessionOpened(@session.handle)
+ do_events
+ end
+
+ def conn_event_disconnected(error)
+ puts "Console Connection Lost"
+ end
+
+ def sess_event_session_closed(context, error)
+ puts "Console Session Lost"
+ @impl.sessionClosed()
+ end
+
+ def sess_event_recv(context, message)
+ @impl.handleRcvMessage(message)
+ do_events
+ end
+ end
+
+ ##==============================================================================
+ ## AGENT
+ ##==============================================================================
+
+ class AgentHandler
+ def get_query(context, query, userId); end
+ def method_call(context, name, object_id, args, userId); end
+ end
+
+ class Agent < ConnectionHandler
+ def initialize(handler, label="")
+ if label == ""
+ @agentLabel = "rb-%s.%d" % [Socket.gethostname, Process::pid]
+ else
+ @agentLabel = label
+ end
+ @conn = nil
+ @handler = handler
+ @impl = Qmfengine::AgentEngine.new(@agentLabel)
+ @event = Qmfengine::AgentEvent.new
+ @xmtMessage = Qmfengine::Message.new
+ end
+
+ def set_connection(conn)
+ @conn = conn
+ @conn.add_conn_handler(self)
+ end
+
+ def register_class(cls)
+ @impl.registerClass(cls.impl)
+ end
+
+ def alloc_object_id(low = 0, high = 0)
+ ObjectId.new(@impl.allocObjectId(low, high))
+ end
+
+ def query_response(context, object)
+ @impl.queryResponse(context, object.impl)
+ end
+
+ def query_complete(context)
+ @impl.queryComplete(context)
+ end
+
+ def method_response(context, status, text, arguments)
+ @impl.methodResponse(context, status, text, arguments.map)
+ end
+
+ def do_agent_events()
+ count = 0
+ valid = @impl.getEvent(@event)
+ while valid
+ count += 1
+ case @event.kind
+ when Qmfengine::AgentEvent::GET_QUERY
+ @handler.get_query(@event.sequence, Query.new(@event.query), @event.authUserId)
+ when Qmfengine::AgentEvent::START_SYNC
+ when Qmfengine::AgentEvent::END_SYNC
+ when Qmfengine::AgentEvent::METHOD_CALL
+ args = Arguments.new(@event.arguments)
+ @handler.method_call(@event.sequence, @event.name, ObjectId.new(@event.objectId),
+ args, @event.authUserId)
+ when Qmfengine::AgentEvent::DECLARE_QUEUE
+ @conn.impl.declareQueue(@session.handle, @event.name)
+ when Qmfengine::AgentEvent::DELETE_QUEUE
+ @conn.impl.deleteQueue(@session.handle, @event.name)
+ when Qmfengine::AgentEvent::BIND
+ @conn.impl.bind(@session.handle, @event.exchange, @event.name, @event.bindingKey)
+ when Qmfengine::AgentEvent::UNBIND
+ @conn.impl.unbind(@session.handle, @event.exchange, @event.name, @event.bindingKey)
+ when Qmfengine::AgentEvent::SETUP_COMPLETE
+ @impl.startProtocol()
+ end
+ @impl.popEvent
+ valid = @impl.getEvent(@event)
end
+ return count
+ end
- private
- def value(name)
- val = @impl.getValue(name.to_s)
- if val.nil?
- raise ArgumentError, "Attribute '#{name}' not defined for class #{@object_class.impl.getName}"
- end
- return val
+ def do_agent_messages()
+ count = 0
+ valid = @impl.getXmtMessage(@xmtMessage)
+ while valid
+ count += 1
+ @conn.impl.sendMessage(@session.handle, @xmtMessage)
+ @impl.popXmt
+ valid = @impl.getXmtMessage(@xmtMessage)
end
+ return count
+ end
+
+ def do_events()
+ begin
+ ecnt = do_agent_events
+ mcnt = do_agent_messages
+ end until ecnt == 0 and mcnt == 0
+ end
+
+ def conn_event_connected()
+ puts "Agent Connection Established..."
+ @session = Session.new(@conn, "qmfa-%s.%d" % [Socket.gethostname, Process::pid], self)
+ @impl.newSession
+ do_events
+ end
+
+ def conn_event_disconnected(error)
+ puts "Agent Connection Lost"
+ end
+
+ def sess_event_session_closed(context, error)
+ puts "Agent Session Lost"
+ end
+
+ def sess_event_recv(context, message)
+ @impl.handleRcvMessage(message)
+ do_events
end
+ end
end
diff --git a/qpid/cpp/bindings/qmf/ruby/ruby.i b/qpid/cpp/bindings/qmf/ruby/ruby.i
index a8a2a87a97..b7fed403bd 100644
--- a/qpid/cpp/bindings/qmf/ruby/ruby.i
+++ b/qpid/cpp/bindings/qmf/ruby/ruby.i
@@ -38,17 +38,33 @@
%typemap (out) uint16_t
{
- $result = UINT2NUM((unsigned short) $1);
+ $result = UINT2NUM((uint16_t) $1);
}
%typemap (in) uint32_t
{
- $1 = NUM2UINT ($input);
+ if (TYPE($input) == T_BIGNUM)
+ $1 = NUM2UINT($input);
+ else
+ $1 = FIX2UINT($input);
}
%typemap (out) uint32_t
{
- $result = UINT2NUM((unsigned int) $1);
+ $result = UINT2NUM((uint32_t) $1);
+}
+
+%typemap (in) int32_t
+{
+ if (TYPE($input) == T_BIGNUM)
+ $1 = NUM2INT($input);
+ else
+ $1 = FIX2INT($input);
+}
+
+%typemap (out) int32_t
+{
+ $result = INT2NUM((int32_t) $1);
}
%typemap (typecheck, precedence=SWIG_TYPECHECK_INTEGER) uint32_t {
@@ -57,12 +73,28 @@
%typemap (in) uint64_t
{
- $1 = NUM2ULONG ($input);
+ if (TYPE($input) == T_BIGNUM)
+ $1 = NUM2ULL($input);
+ else
+ $1 = (uint64_t) FIX2LONG($input);
}
%typemap (out) uint64_t
{
- $result = ULONG2NUM((unsigned long) $1);
+ $result = ULL2NUM((uint64_t) $1);
+}
+
+%typemap (in) int64_t
+{
+ if (TYPE($input) == T_BIGNUM)
+ $1 = NUM2LL($input);
+ else
+ $1 = (int64_t) FIX2LONG($input);
+}
+
+%typemap (out) int64_t
+{
+ $result = LL2NUM((int64_t) $1);
}
%typemap (typecheck, precedence=SWIG_TYPECHECK_INTEGER) uint64_t {
diff --git a/qpid/cpp/bindings/qmf/tests/Makefile.am b/qpid/cpp/bindings/qmf/tests/Makefile.am
index 1ff8a64bed..182771e16b 100644
--- a/qpid/cpp/bindings/qmf/tests/Makefile.am
+++ b/qpid/cpp/bindings/qmf/tests/Makefile.am
@@ -18,4 +18,10 @@
#
TESTS = run_interop_tests
-EXTRA_DIST = run_interop_tests
+
+EXTRA_DIST = \
+ agent_ruby.rb \
+ python_agent.py \
+ python_console.py \
+ ruby_console.rb \
+ run_interop_tests
diff --git a/qpid/cpp/bindings/qmf/tests/agent_ruby.rb b/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
index d395810cb6..75de2b5fa1 100755
--- a/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
+++ b/qpid/cpp/bindings/qmf/tests/agent_ruby.rb
@@ -29,13 +29,34 @@ class Model
@parent_class = Qmf::SchemaObjectClass.new("org.apache.qpid.qmf", "parent")
@parent_class.add_property(Qmf::SchemaProperty.new("name", Qmf::TYPE_SSTR, :index => true))
@parent_class.add_property(Qmf::SchemaProperty.new("state", Qmf::TYPE_SSTR))
+
+ @parent_class.add_property(Qmf::SchemaProperty.new("uint64val", Qmf::TYPE_UINT64))
@parent_class.add_property(Qmf::SchemaProperty.new("uint32val", Qmf::TYPE_UINT32))
+ @parent_class.add_property(Qmf::SchemaProperty.new("uint16val", Qmf::TYPE_UINT16))
+ @parent_class.add_property(Qmf::SchemaProperty.new("uint8val", Qmf::TYPE_UINT8))
+
+ @parent_class.add_property(Qmf::SchemaProperty.new("int64val", Qmf::TYPE_INT64))
+ @parent_class.add_property(Qmf::SchemaProperty.new("int32val", Qmf::TYPE_INT32))
+ @parent_class.add_property(Qmf::SchemaProperty.new("int16val", Qmf::TYPE_INT16))
+ @parent_class.add_property(Qmf::SchemaProperty.new("int8val", Qmf::TYPE_INT8))
+
@parent_class.add_statistic(Qmf::SchemaStatistic.new("queryCount", Qmf::TYPE_UINT32, :unit => "query", :desc => "Query count"))
+ method = Qmf::SchemaMethod.new("echo", :desc => "Check responsiveness of the agent object")
+ method.add_argument(Qmf::SchemaArgument.new("sequence", Qmf::TYPE_UINT32, :dir => Qmf::DIR_IN_OUT))
+ @parent_class.add_method(method)
+
+ method = Qmf::SchemaMethod.new("set_numerics", :desc => "Set the numeric values in the object")
+ method.add_argument(Qmf::SchemaArgument.new("test", Qmf::TYPE_SSTR, :dir => Qmf::DIR_IN))
+ @parent_class.add_method(method)
+
method = Qmf::SchemaMethod.new("create_child", :desc => "Create a new child object")
method.add_argument(Qmf::SchemaArgument.new("child_name", Qmf::TYPE_LSTR, :dir => Qmf::DIR_IN))
method.add_argument(Qmf::SchemaArgument.new("child_ref", Qmf::TYPE_REF, :dir => Qmf::DIR_OUT))
+ @parent_class.add_method(method)
+ method = Qmf::SchemaMethod.new("probe_userid", :desc => "Return the user-id for this method call")
+ method.add_argument(Qmf::SchemaArgument.new("userid", Qmf::TYPE_SSTR, :dir => Qmf::DIR_OUT))
@parent_class.add_method(method)
@child_class = Qmf::SchemaObjectClass.new("org.apache.qpid.qmf", "child")
@@ -55,24 +76,83 @@ class App < Qmf::AgentHandler
#@parent.inc_attr("queryCount")
if query.class_name == 'parent'
@agent.query_response(context, @parent)
+ elsif query.object_id == @parent_oid
+ @agent.query_response(context, @parent)
end
@agent.query_complete(context)
end
def method_call(context, name, object_id, args, userId)
# puts "Method: user=#{userId} context=#{context} method=#{name} object_num=#{object_id.object_num_low if object_id} args=#{args}"
- oid = @agent.alloc_object_id(2)
- args['child_ref'] = oid
- @child = Qmf::QmfObject.new(@model.child_class)
- @child.set_attr("name", args.by_key("child_name"))
- @child.set_object_id(oid)
- @agent.method_response(context, 0, "OK", args)
+
+ if name == "echo"
+ @agent.method_response(context, 0, "OK", args)
+
+ elsif name == "set_numerics"
+ retCode = 0
+ retText = "OK"
+
+ if args['test'] == "big"
+ @parent.set_attr("uint64val", 0x9494949449494949)
+ @parent.set_attr("uint32val", 0xa5a55a5a)
+ @parent.set_attr("uint16val", 0xb66b)
+ @parent.set_attr("uint8val", 0xc7)
+
+ @parent.set_attr("int64val", 1000000000000000000)
+ @parent.set_attr("int32val", 1000000000)
+ @parent.set_attr("int16val", 10000)
+ @parent.set_attr("int8val", 100)
+
+ elsif args['test'] == "small"
+ @parent.set_attr("uint64val", 4)
+ @parent.set_attr("uint32val", 5)
+ @parent.set_attr("uint16val", 6)
+ @parent.set_attr("uint8val", 7)
+
+ @parent.set_attr("int64val", 8)
+ @parent.set_attr("int32val", 9)
+ @parent.set_attr("int16val", 10)
+ @parent.set_attr("int8val", 11)
+
+ elsif args['test'] == "negative"
+ @parent.set_attr("uint64val", 0)
+ @parent.set_attr("uint32val", 0)
+ @parent.set_attr("uint16val", 0)
+ @parent.set_attr("uint8val", 0)
+
+ @parent.set_attr("int64val", -10000000000)
+ @parent.set_attr("int32val", -100000)
+ @parent.set_attr("int16val", -1000)
+ @parent.set_attr("int8val", -100)
+
+ else
+ retCode = 1
+ retText = "Invalid argument value for test"
+ end
+
+ @agent.method_response(context, retCode, retText, args)
+
+ elsif name == "create_child"
+ oid = @agent.alloc_object_id(2)
+ args['child_ref'] = oid
+ @child = Qmf::QmfObject.new(@model.child_class)
+ @child.set_attr("name", args.by_key("child_name"))
+ @child.set_object_id(oid)
+ @agent.method_response(context, 0, "OK", args)
+
+ elsif name == "probe_userid"
+ args['userid'] = userId
+ @agent.method_response(context, 0, "OK", args)
+
+ else
+ @agent.method_response(context, 1, "Unimplemented Method: #{name}", args)
+ end
end
def main
@settings = Qmf::ConnectionSettings.new
- @settings.host = ARGV[0] if ARGV.size > 0
- @settings.port = ARGV[1].to_i if ARGV.size > 1
+ @settings.set_attr("host", ARGV[0]) if ARGV.size > 0
+ @settings.set_attr("port", ARGV[1].to_i) if ARGV.size > 1
@connection = Qmf::Connection.new(@settings)
@agent = Qmf::Agent.new(self)
@@ -84,10 +164,19 @@ class App < Qmf::AgentHandler
@parent = Qmf::QmfObject.new(@model.parent_class)
@parent.set_attr("name", "Parent One")
@parent.set_attr("state", "OPERATIONAL")
- @parent.set_attr("uint32val", 0xa5a5a5a5)
- oid = @agent.alloc_object_id(1)
- @parent.set_object_id(oid)
+ @parent.set_attr("uint64val", 0)
+ @parent.set_attr("uint32val", 0)
+ @parent.set_attr("uint16val", 0)
+ @parent.set_attr("uint8val", 0)
+
+ @parent.set_attr("int64val", 0)
+ @parent.set_attr("int32val", 0)
+ @parent.set_attr("int16val", 0)
+ @parent.set_attr("int8val", 0)
+
+ @parent_oid = @agent.alloc_object_id(1)
+ @parent.set_object_id(@parent_oid)
sleep
end
diff --git a/qpid/cpp/bindings/qmf/tests/python_agent.py b/qpid/cpp/bindings/qmf/tests/python_agent.py
new file mode 100644
index 0000000000..f6cb51cbf5
--- /dev/null
+++ b/qpid/cpp/bindings/qmf/tests/python_agent.py
@@ -0,0 +1,192 @@
+#!/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_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("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}))
+
+
+ def register(self, agent):
+ agent.register_class(self.parent_class)
+ agent.register_class(self.child_class)
+
+
+
+class App(qmf.AgentHandler):
+ def get_query(self, context, query, userId):
+ # puts "Query: user=#{userId} context=#{context} class=#{query.class_name} object_num=#{query.object_id.object_num_low if query.object_id}"
+ 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):
+ # puts "Method: user=#{userId} context=#{context} method=#{name} object_num=#{object_id.object_num_low if object_id} args=#{args}"
+ # oid = self._agent.alloc_object_id(2)
+ # args['child_ref'] = oid
+ # self._child = qmf.QmfObject(self._model.child_class)
+ # self._child.set_attr("name", args.by_key("child_name"))
+ # self._child.set_object_id(oid)
+ # self._agent.method_response(context, 0, "OK", args)
+ if name == "echo":
+ self._agent.method_response(context, 0, "OK", args)
+
+ elif name == "set_numerics":
+ _retCode = 0
+ _retText = "OK"
+
+ if args['test'] == "big":
+ self._parent.set_attr("uint64val", 0x9494949449494949)
+ self._parent.set_attr("uint32val", 0xa5a55a5a)
+ self._parent.set_attr("uint16val", 0xb66b)
+ self._parent.set_attr("uint8val", 0xc7)
+
+ self._parent.set_attr("int64val", 1000000000000000000)
+ self._parent.set_attr("int32val", 1000000000)
+ self._parent.set_attr("int16val", 10000)
+ self._parent.set_attr("int8val", 100)
+
+ 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)
+
+ 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)
+
+ else:
+ _retCode = 1
+ _retText = "Invalid argument value for test"
+
+ self._agent.method_response(context, _retCode, _retText, args)
+
+ elif name == "create_child":
+ _oid = self._agent.alloc_object_id(2)
+ args['child_ref'] = _oid
+ self._child = qmf.QmfObject(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):
+ self._settings = qmf.ConnectionSettings()
+ if len(sys.argv) > 1:
+ self._settings.set_attr("host", sys.argv[1])
+ if len(sys.argv) > 2:
+ self._settings.set_attr("port", int(sys.argv[2]))
+ self._connection = qmf.Connection(self._settings)
+ self._agent = qmf.Agent(self)
+
+ self._model = Model()
+ self._model.register(self._agent)
+
+ self._agent.set_connection(self._connection)
+
+ self._parent = qmf.QmfObject(self._model.parent_class)
+ 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)
+
+ self._parent_oid = self._agent.alloc_object_id(1)
+ self._parent.set_object_id(self._parent_oid)
+
+ while True: # there may be a better way, but
+ time.sleep(1000) # I'm a python noob...
+
+
+
+app = App()
+app.main()
+
diff --git a/qpid/cpp/bindings/qmf/tests/python_console.py b/qpid/cpp/bindings/qmf/tests/python_console.py
index 7a8a2cb9fe..bcd3063fe3 100755
--- a/qpid/cpp/bindings/qmf/tests/python_console.py
+++ b/qpid/cpp/bindings/qmf/tests/python_console.py
@@ -36,16 +36,109 @@ class QmfInteropTests(TestBase010):
agents = qmf.getObjects(_class="agent")
sleep(1)
count += 1
- if count > 5:
+ if count > 10:
self.fail("Timed out waiting for remote agent")
- def test_B_basic_types(self):
+ def test_B_basic_method_invocation(self):
self.startQmf();
qmf = self.qmf
parents = qmf.getObjects(_class="parent")
self.assertEqual(len(parents), 1)
- self.assertEqual(parents[0].uint32val, 0xA5A5A5A5)
+ parent = parents[0]
+ for seq in range(10):
+ result = parent.echo(seq)
+ self.assertEqual(result.status, 0)
+ self.assertEqual(result.text, "OK")
+ self.assertEqual(result.sequence, seq)
+
+ result = parent.set_numerics("bogus")
+ self.assertEqual(result.status, 1)
+ self.assertEqual(result.text, "Invalid argument value for test")
+
+ def test_C_basic_types_numeric_big(self):
+ self.startQmf();
+ qmf = self.qmf
+
+ parents = qmf.getObjects(_class="parent")
+ self.assertEqual(len(parents), 1)
+ parent = parents[0]
+
+ result = parent.set_numerics("big")
+ self.assertEqual(result.status, 0)
+ self.assertEqual(result.text, "OK")
+
+ parent.update()
+
+ self.assertEqual(parent.uint64val, 0x9494949449494949)
+ self.assertEqual(parent.uint32val, 0xA5A55A5A)
+ self.assertEqual(parent.uint16val, 0xB66B)
+ self.assertEqual(parent.uint8val, 0xC7)
+
+ self.assertEqual(parent.int64val, 1000000000000000000)
+ self.assertEqual(parent.int32val, 1000000000)
+ self.assertEqual(parent.int16val, 10000)
+ self.assertEqual(parent.int8val, 100)
+
+ def test_C_basic_types_numeric_small(self):
+ self.startQmf();
+ qmf = self.qmf
+
+ parents = qmf.getObjects(_class="parent")
+ self.assertEqual(len(parents), 1)
+ parent = parents[0]
+
+ result = parent.set_numerics("small")
+ self.assertEqual(result.status, 0)
+ self.assertEqual(result.text, "OK")
+
+ parent.update()
+
+ self.assertEqual(parent.uint64val, 4)
+ self.assertEqual(parent.uint32val, 5)
+ self.assertEqual(parent.uint16val, 6)
+ self.assertEqual(parent.uint8val, 7)
+
+ self.assertEqual(parent.int64val, 8)
+ self.assertEqual(parent.int32val, 9)
+ self.assertEqual(parent.int16val, 10)
+ self.assertEqual(parent.int8val, 11)
+
+ def test_C_basic_types_numeric_negative(self):
+ self.startQmf();
+ qmf = self.qmf
+
+ parents = qmf.getObjects(_class="parent")
+ self.assertEqual(len(parents), 1)
+ parent = parents[0]
+
+ result = parent.set_numerics("negative")
+ self.assertEqual(result.status, 0)
+ self.assertEqual(result.text, "OK")
+
+ parent.update()
+
+ self.assertEqual(parent.uint64val, 0)
+ self.assertEqual(parent.uint32val, 0)
+ self.assertEqual(parent.uint16val, 0)
+ self.assertEqual(parent.uint8val, 0)
+
+ self.assertEqual(parent.int64val, -10000000000)
+ self.assertEqual(parent.int32val, -100000)
+ self.assertEqual(parent.int16val, -1000)
+ self.assertEqual(parent.int8val, -100)
+
+ def test_D_userid_for_method(self):
+ self.startQmf();
+ qmf = self.qmf
+
+ parents = qmf.getObjects(_class="parent")
+ self.assertEqual(len(parents), 1)
+ parent = parents[0]
+
+ result = parent.probe_userid()
+ self.assertEqual(result.status, 0)
+ self.assertEqual(result.userid, "guest")
def getProperty(self, msg, name):
for h in msg.headers:
diff --git a/qpid/cpp/bindings/qmf/tests/ruby_console.rb b/qpid/cpp/bindings/qmf/tests/ruby_console.rb
new file mode 100755
index 0000000000..fb48c29566
--- /dev/null
+++ b/qpid/cpp/bindings/qmf/tests/ruby_console.rb
@@ -0,0 +1,61 @@
+#!/usr/bin/ruby
+
+#
+# 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.
+#
+
+require 'qmf'
+require 'socket'
+
+class App < Qmf::ConsoleHandler
+
+ def main
+ @settings = Qmf::ConnectionSettings.new
+ @settings.set_attr("host", ARGV[0]) if ARGV.size > 0
+ @settings.set_attr("port", ARGV[1].to_i) if ARGV.size > 1
+ @connection = Qmf::Connection.new(@settings)
+ @qmf = Qmf::Console.new
+
+ @broker = @qmf.add_connection(@connection)
+ @broker.waitForStable
+
+ packages = @qmf.get_packages
+ puts "----- Packages -----"
+ packages.each do |p|
+ puts p
+ puts " ----- Object Classes -----"
+ classes = @qmf.get_classes(p)
+ classes.each do |c|
+ puts " #{c.name}"
+ end
+ puts " ----- Event Classes -----"
+ classes = @qmf.get_classes(p, Qmf::CLASS_EVENT)
+ classes.each do |c|
+ puts " #{c.name}"
+ end
+ end
+ puts "-----"
+
+ sleep
+ end
+end
+
+app = App.new
+app.main
+
+
diff --git a/qpid/cpp/bindings/qmf/tests/run_interop_tests b/qpid/cpp/bindings/qmf/tests/run_interop_tests
index e6fc872dbb..01d7221ac6 100755
--- a/qpid/cpp/bindings/qmf/tests/run_interop_tests
+++ b/qpid/cpp/bindings/qmf/tests/run_interop_tests
@@ -28,6 +28,9 @@ BROKER_DIR=${BUILD_DIR}/src
API_DIR=${BUILD_DIR}/bindings/qmf
SPEC_DIR=${QPID_DIR}/specs
+RUBY_LIB_DIR=${API_DIR}/ruby/.libs
+PYTHON_LIB_DIR=${API_DIR}/python/.libs
+
trap stop_broker INT TERM QUIT
start_broker() {
@@ -41,7 +44,7 @@ stop_broker() {
}
start_ruby_agent() {
- ruby -I${MY_DIR}/../ruby -I${API_DIR}/ruby/.libs ${MY_DIR}/agent_ruby.rb localhost $BROKER_PORT &
+ ruby -I${MY_DIR}/../ruby -I${RUBY_LIB_DIR} ${MY_DIR}/agent_ruby.rb localhost $BROKER_PORT &
AGENT_PID=$!
}
@@ -49,19 +52,62 @@ stop_ruby_agent() {
kill $AGENT_PID
}
+start_python_agent() {
+ PYTHONPATH="${MY_DIR}/../python:${API_DIR}/python:${PYTHON_LIB_DIR}" python ${MY_DIR}/python_agent.py localhost $BROKER_PORT &
+ PY_AGENT_PID=$!
+}
+
+stop_python_agent() {
+ kill $PY_AGENT_PID
+}
+
+TESTS_FAILED=0
+
if test -d ${PYTHON_DIR} ; then
start_broker
echo "Running qmf interop tests using broker on port $BROKER_PORT"
PYTHONPATH=${PYTHON_DIR}:${MY_DIR}
export PYTHONPATH
- echo " Ruby Agent vs. Pure-Python Console"
- start_ruby_agent
- echo " Ruby agent started at pid $AGENT_PID"
- ${PYTHON_DIR}/qpid-python-test -m python_console -b localhost:$BROKER_PORT $@
- RETCODE=$?
- stop_ruby_agent
+
+ if test -d ${PYTHON_LIB_DIR} ; then
+ echo " Python Agent (external storage) vs. Pure-Python Console"
+ start_python_agent
+ echo " Python agent started at pid $PY_AGENT_PID"
+ ${PYTHON_DIR}/qpid-python-test -m python_console -b localhost:$BROKER_PORT $@
+ RETCODE=$?
+ stop_python_agent
+ if test x$RETCODE != x0; then
+ echo "FAIL qmf interop tests (Python Agent)";
+ TESTS_FAILED=1
+ fi
+ fi
+
+ if test -d ${RUBY_LIB_DIR} ; then
+ echo " Ruby Agent (external storage) vs. Pure-Python Console"
+ start_ruby_agent
+ echo " Ruby agent started at pid $AGENT_PID"
+ ${PYTHON_DIR}/qpid-python-test -m python_console -b localhost:$BROKER_PORT $@
+ RETCODE=$?
+ stop_ruby_agent
+ if test x$RETCODE != x0; then
+ echo "FAIL qmf interop tests (Ruby Agent)";
+ TESTS_FAILED=1
+ fi
+ fi
+
+ # Also against the Pure-Python console:
+ # Ruby agent (internal storage)
+ # Python agent (external and internal)
+ # C++ agent (external and internal)
+ #
+ # Other consoles against the same set of agents:
+ # Wrapped Python console
+ # Ruby console
+ # C++ console
+
stop_broker
- if test x$RETCODE != x0; then
- echo "FAIL qmf interop tests"; exit 1;
+ if test x$TESTS_FAILED != x0; then
+ echo "TEST FAILED!"
+ exit 1
fi
fi