diff options
| author | Kim van der Riet <kpvdr@apache.org> | 2013-09-20 18:59:30 +0000 |
|---|---|---|
| committer | Kim van der Riet <kpvdr@apache.org> | 2013-09-20 18:59:30 +0000 |
| commit | c70bf3ea28cdf6bafd8571690d3e5c466a0658a2 (patch) | |
| tree | 68b24940e433f3f9c278b054d9ea1622389bd332 /qpid/cpp/bindings | |
| parent | fcdf1723c7b5cdf0772054a93edb6e7d97c4bb1e (diff) | |
| download | qpid-python-c70bf3ea28cdf6bafd8571690d3e5c466a0658a2.tar.gz | |
QPID-4984: WIP - Merge from trunk r.1525056
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/linearstore@1525101 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/bindings')
42 files changed, 880 insertions, 5982 deletions
diff --git a/qpid/cpp/bindings/CMakeLists.txt b/qpid/cpp/bindings/CMakeLists.txt index 14e30ed6ca..883eef286f 100644 --- a/qpid/cpp/bindings/CMakeLists.txt +++ b/qpid/cpp/bindings/CMakeLists.txt @@ -73,7 +73,7 @@ if (SWIG_FOUND) set(CMAKE_SWIG_FLAGS "-w361,362,401,467,503") if (PYTHONLIBS_FOUND) - message("Building Python bindings") + message(STATUS "Building Python bindings") execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(True, prefix='${CMAKE_INSTALL_PREFIX}')" OUTPUT_VARIABLE PYTHON_SITEARCH_PACKAGES @@ -81,11 +81,10 @@ if (SWIG_FOUND) add_subdirectory(qpid/python) add_subdirectory(qmf2/python) - add_subdirectory(qmf/python) endif (PYTHONLIBS_FOUND) if (RUBY_FOUND) - message("Building Ruby bindings") + message(STATUS "Building Ruby bindings") execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "puts RbConfig::CONFIG['prefix']" OUTPUT_VARIABLE RUBY_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -93,11 +92,10 @@ if (SWIG_FOUND) # string(REPLACE ${RUBY_PREFIX} ${CMAKE_INSTALL_PREFIX} RUBY_PFX_ARCH_DIR ${RUBY_ARCH_DIR}) add_subdirectory(qpid/ruby) add_subdirectory(qmf2/ruby) - add_subdirectory(qmf/ruby) endif (RUBY_FOUND) if (PERLLIBS_FOUND) - message("Building Perl bindings") + message(STATUS "Building Perl bindings") execute_process(COMMAND ${PERL_EXECUTABLE} "-V::prefix:" OUTPUT_VARIABLE QPERL_PREFIX OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/qpid/cpp/bindings/qmf/python/CMakeLists.txt b/qpid/cpp/bindings/qmf/python/CMakeLists.txt deleted file mode 100644 index 14ba888c78..0000000000 --- a/qpid/cpp/bindings/qmf/python/CMakeLists.txt +++ /dev/null @@ -1,66 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -##------------------------------------------------------ -## Use Swig to generate a literal binding to the C++ API -##------------------------------------------------------ -set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/python.i PROPERTIES CPLUSPLUS ON) -set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/python.i PROPERTIES SWIG_FLAGS "-I${qpid-cpp_SOURCE_DIR}/include;-I${qpid-cpp_SOURCE_DIR}/bindings") - -swig_add_module(qmfengine_python python ${CMAKE_CURRENT_SOURCE_DIR}/python.i) -swig_link_libraries(qmfengine_python qmf qmfconsole ${PYTHON_LIBRARIES}) - -set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing -I${PYTHON_INCLUDE_PATH} -I${qpid-cpp_SOURCE_DIR}/include") - -##------------------------------------ -## Install the complete Python binding -##------------------------------------ - -# Copy py source to binary dir so pyc/pyo will be generated in binary dir. -# NOTE: not using the file(COPY) command as it is not available in cmake 2.6 -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/qmf.py" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) - -# Python compile the modules -install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m py_compile qmfengine.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") - -install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile qmfengine.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") -install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m py_compile qmf.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") -install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile qmf.py - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") - -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/qmfengine.py - ${CMAKE_CURRENT_BINARY_DIR}/qmfengine.pyc - ${CMAKE_CURRENT_BINARY_DIR}/qmfengine.pyo - ${CMAKE_CURRENT_SOURCE_DIR}/qmf.py - ${CMAKE_CURRENT_BINARY_DIR}/qmf.pyc - ${CMAKE_CURRENT_BINARY_DIR}/qmf.pyo - DESTINATION ${PYTHON_SITEARCH_PACKAGES} - COMPONENT ${QPID_COMPONENT_CLIENT} - ) - -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/_qmfengine_python.so - RENAME _qmfengine.so - DESTINATION ${PYTHON_SITEARCH_PACKAGES} - COMPONENT ${QPID_COMPONENT_CLIENT} - ) - diff --git a/qpid/cpp/bindings/qmf/python/Makefile.am b/qpid/cpp/bindings/qmf/python/Makefile.am deleted file mode 100644 index f787d3955f..0000000000 --- a/qpid/cpp/bindings/qmf/python/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -if HAVE_PYTHON_DEVEL - -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src/qmf -I$(top_srcdir)/src -I$(top_builddir)/src - -generated_file_list = \ - qmfengine.cpp \ - qmfengine.py - -EXTRA_DIST = CMakeLists.txt python.i qmfengine.py -BUILT_SOURCES = $(generated_file_list) -SWIG_FLAGS = -w362,401 - -$(generated_file_list): $(srcdir)/python.i - $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o qmfengine.cpp $(srcdir)/python.i - -pylibdir = $(pyexecdir) - -pylib_LTLIBRARIES = _qmfengine.la -qenginedir = $(pythondir) -qengine_PYTHON = qmfengine.py qmf.py - -#_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/libqmf.la -_qmfengine_la_CXXFLAGS = $(INCLUDES) -I$(srcdir)/qmf $(PYTHON_CFLAGS) -fno-strict-aliasing -nodist__qmfengine_la_SOURCES = qmfengine.cpp - -CLEANFILES = $(generated_file_list) - -endif # HAVE_PYTHON_DEVEL - diff --git a/qpid/cpp/bindings/qmf/python/python.i b/qpid/cpp/bindings/qmf/python/python.i deleted file mode 100644 index 118d0d3dbd..0000000000 --- a/qpid/cpp/bindings/qmf/python/python.i +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -%module qmfengine - - -/* 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 -} - - -/* 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 "qmf/qmfengine.i" - diff --git a/qpid/cpp/bindings/qmf/python/qmf.py b/qpid/cpp/bindings/qmf/python/qmf.py deleted file mode 100644 index 06d3070841..0000000000 --- a/qpid/cpp/bindings/qmf/python/qmf.py +++ /dev/null @@ -1,1680 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -import sys -import socket -import os -import logging -from threading import Thread -from threading import RLock -from threading import Condition -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) -from qmfengine import (O_EQ, O_NE, O_LT, O_LE, O_GT, O_GE, O_RE_MATCH, O_RE_NOMATCH, - E_NOT, E_AND, E_OR, E_XOR) -from qmfengine import (SEV_EMERG, SEV_ALERT, SEV_CRIT, SEV_ERROR, SEV_WARN, SEV_NOTICE, - SEV_INFORM, SEV_DEBUG) - - -def qmf_to_native(val): - typecode = val.getType() - if typecode == TYPE_UINT8: return val.asUint() - elif typecode == TYPE_UINT16: return val.asUint() - elif typecode == TYPE_UINT32: return val.asUint() - elif typecode == TYPE_UINT64: return val.asUint64() - elif typecode == TYPE_SSTR: return val.asString() - elif typecode == TYPE_LSTR: return val.asString() - elif typecode == TYPE_ABSTIME: return val.asInt64() - elif typecode == TYPE_DELTATIME: return val.asUint64() - elif typecode == TYPE_REF: return ObjectId(val.asObjectId()) - elif typecode == TYPE_BOOL: return val.asBool() - elif typecode == TYPE_FLOAT: return val.asFloat() - elif typecode == TYPE_DOUBLE: return val.asDouble() - elif typecode == TYPE_UUID: return val.asUuid() - elif typecode == TYPE_INT8: return val.asInt() - elif typecode == TYPE_INT16: return val.asInt() - elif typecode == TYPE_INT32: return val.asInt() - elif typecode == TYPE_INT64: return val.asInt64() - elif typecode == TYPE_MAP: return value_to_dict(val) - elif typecode == TYPE_LIST: return value_to_list(val) - else: - # when TYPE_OBJECT - logging.error( "Unsupported type for get_attr? '%s'" % str(val.getType()) ) - return None - - -def native_to_qmf(target, value): - val = None - typecode = None - if target.__class__ == qmfengine.Value: - val = target - typecode = val.getType() - else: - typecode = target - val = qmfengine.Value(typecode) - - if typecode == TYPE_UINT8: val.setUint(value) - elif typecode == TYPE_UINT16: val.setUint(value) - elif typecode == TYPE_UINT32: val.setUint(value) - elif typecode == TYPE_UINT64: val.setUint64(value) - elif typecode == TYPE_SSTR: - if value: val.setString(value) - else: val.setString('') - elif typecode == TYPE_LSTR: - if value: val.setString(value) - else: val.setString('') - elif typecode == TYPE_ABSTIME: val.setInt64(value) - elif typecode == TYPE_DELTATIME: val.setUint64(value) - elif typecode == TYPE_REF: val.setObjectId(value.impl) - elif typecode == TYPE_BOOL: val.setBool(value) - elif typecode == TYPE_FLOAT: val.setFloat(value) - elif typecode == TYPE_DOUBLE: val.setDouble(value) - elif typecode == TYPE_UUID: val.setUuid(value) - elif typecode == TYPE_INT8: val.setInt(value) - elif typecode == TYPE_INT16: val.setInt(value) - elif typecode == TYPE_INT32: val.setInt(value) - elif typecode == TYPE_INT64: val.setInt64(value) - elif typecode == TYPE_MAP: dict_to_value(val, value) - elif typecode == TYPE_LIST: list_to_value(val, value) - else: - # when TYPE_OBJECT - logging.error("Unsupported type for get_attr? '%s'" % str(val.getType())) - return None - return val - - -def pick_qmf_type(value): - if value.__class__ == int: - if value >= 0: - if value < 0x100000000: return TYPE_UINT32 - return TYPE_UINT64 - else: - if value > -0xffffffff: return TYPE_INT32 - return TYPE_INT64 - - if value.__class__ == long: - if value >= 0: return TYPE_UINT64 - return TYPE_INT64 - - if value.__class__ == str: - if len(value) < 256: return TYPE_SSTR - return TYPE_LSTR - - if value.__class__ == float: return TYPE_DOUBLE - if value.__class__ == bool: return TYPE_BOOL - if value == None: return TYPE_BOOL - if value.__class__ == dict: return TYPE_MAP - if value.__class__ == list: return TYPE_LIST - - raise "QMF type not known for native type %s" % value.__class__ - - -def value_to_dict(val): - if not val.isMap(): raise "value_to_dict must be given a map value" - mymap = {} - for i in range(val.keyCount()): - key = val.key(i) - mymap[key] = qmf_to_native(val.byKey(key)) - return mymap - - -def dict_to_value(val, mymap): - for key, value in mymap.items(): - if key.__class__ != str: raise "QMF map key must be a string" - typecode = pick_qmf_type(value) - val.insert(key, native_to_qmf(typecode, value)) - - -def value_to_list(val): - mylist = [] - if val.isList(): - for i in range(val.listItemCount()): - mylist.append(qmf_to_native(val.listItem(i))) - return mylist - #if val.isArray(): - # for i in range(val.arrayItemCount()): - # mylist.append(qmf_to_native(val.arrayItem(i))) - # return mylist - - raise "value_to_list must be given a list value" - - -def list_to_value(val, mylist): - for item in mylist: - typecode = pick_qmf_type(item) - val.appendToList(native_to_qmf(typecode, item)) - - - ##============================================================================== - ## CONNECTION - ##============================================================================== - -class ConnectionSettings(object): - #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) == int: - _v = qmfengine.Value(TYPE_UINT32) - _v.setUint(val) - elif type(val) == bool: - _v = qmfengine.Value(TYPE_BOOL) - _v.setBool(val) - else: - raise Exception("Argument error: value for attribute '%s' has unsupported type: %s" % ( key, type(val))) - - good = self.impl.setAttr(key, _v) - if not good: - raise Exception("Argument error: unsupported attribute '%s'" % key ) - - - def get_attr(self, key): - _v = self.impl.getAttr(key) - if _v.isString(): - return _v.asString() - elif _v.isUint(): - return _v.asUint() - elif _v.isBool(): - return _v.asBool() - else: - raise Exception("Argument error: value for attribute '%s' has unsupported type: %s" % ( key, str(_v.getType()))) - - - def __getattr__(self, name): - return self.get_attr(name) - - - def __setattr__(self, name, value): - if name == "impl": - return super.__setattr__(self, name, value) - return self.set_attr(name, value) - - - -class ConnectionHandler: - def conn_event_connected(self): None - def conn_event_disconnected(self, error): None - def conn_event_visit(self): 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_to_delete = [] - self._conn_handlers = [] - self._connected = False - self._operational = True - self.start() - - - def destroy(self, timeout=None): - logging.debug("Destroying Connection...") - self._operational = False - self.kick() - self.join(timeout) - logging.debug("... Conn Destroyed!" ) - if self.isAlive(): - logging.error("Error: Connection thread '%s' is hung..." % self.getName()) - - - def connected(self): - return self._connected - - - def kick(self): - self.impl.notify() - - - def add_conn_handler(self, handler): - self._lock.acquire() - try: - self._new_conn_handlers.append(handler) - finally: - self._lock.release() - self.kick() - - - def del_conn_handler(self, handler): - self._lock.acquire() - try: - self._conn_handlers_to_delete.append(handler) - finally: - self._lock.release() - self.kick() - - - def run(self): - eventImpl = qmfengine.ResilientConnectionEvent() - new_handlers = [] - del_handlers = [] - bt_count = 0 - - while self._operational: - logging.debug("Connection thread waiting for socket data...") - self._sock.recv(1) - - self._lock.acquire() - try: - new_handlers = self._new_conn_handlers - del_handlers = self._conn_handlers_to_delete - self._new_conn_handlers = [] - self._conn_handlers_to_delete = [] - finally: - self._lock.release() - - for nh in new_handlers: - self._conn_handlers.append(nh) - if self._connected: - nh.conn_event_connected() - new_handlers = [] - - for dh in del_handlers: - if dh in self._conn_handlers: - self._conn_handlers.remove(dh) - del_handlers = [] - - valid = self.impl.getEvent(eventImpl) - while valid: - try: - if eventImpl.kind == qmfengine.ResilientConnectionEvent.CONNECTED: - logging.debug("Connection thread: CONNECTED event received.") - self._connected = True - for h in self._conn_handlers: - h.conn_event_connected() - - elif eventImpl.kind == qmfengine.ResilientConnectionEvent.DISCONNECTED: - logging.debug("Connection thread: DISCONNECTED event received.") - self._connected = False - for h in self._conn_handlers: - h.conn_event_disconnected(eventImpl.errorText) - - elif eventImpl.kind == qmfengine.ResilientConnectionEvent.SESSION_CLOSED: - logging.debug("Connection thread: SESSION_CLOSED event received.") - eventImpl.sessionContext.handler.sess_event_session_closed(eventImpl.sessionContext, eventImpl.errorText) - - elif eventImpl.kind == qmfengine.ResilientConnectionEvent.RECV: - logging.debug("Connection thread: RECV event received.") - eventImpl.sessionContext.handler.sess_event_recv(eventImpl.sessionContext, eventImpl.message) - else: - logging.debug("Connection thread received unknown event: '%s'" % str(eventImpl.kind)) - - except: - import traceback - logging.error( "Exception occurred during Connection event processing:" ) - logging.error( str(sys.exc_info()) ) - if bt_count < 2: - traceback.print_exc() - traceback.print_stack() - bt_count += 1 - - self.impl.popEvent() - valid = self.impl.getEvent(eventImpl) - - for h in self._conn_handlers: - h.conn_event_visit() - - logging.debug("Shutting down Connection thread") - - - -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 destroy(self): - self._conn.impl.destroySession(self.handle) - - - - ##============================================================================== - ## OBJECTS and EVENTS - ##============================================================================== - -class QmfEvent(object): - # attr_reader :impl, :event_class - def __init__(self, cls, kwargs={}): - self._allow_sets = True - if kwargs.has_key("broker"): - self._broker = kwargs["broker"] - else: - self._broker = None - if cls: - self.event_class = cls - self.impl = qmfengine.Event(self.event_class.impl) - elif kwargs.has_key("impl"): - self.impl = qmfengine.Event(kwargs["impl"]) - self.event_class = SchemaEventClass(None, None, 0, - {"impl":self.impl.getClass()}) - else: - raise Exception("Argument error: required parameter ('impl') not supplied") - - - def arguments(self): - list = [] - for arg in self.event_class.arguments: - list.append([arg, self.get_attr(arg.name())]) - return list - - - def get_attr(self, name): - val = self._value(name) - return qmf_to_native(val) - - - def set_attr(self, name, v): - val = self._value(name) - native_to_qmf(val, v) - - - def __getitem__(self, name): - return self.get_attr(name) - - - def __setitem__(self, name, value): - self.set_attr(name, value) - - - def __setattr__(self, name, value): - # - # Ignore the internal attributes, set them normally... - # - if (name[0] == '_' or - name == 'impl' or - name == 'event_class'): - return super.__setattr__(self, name, value) - - if not self._allow_sets: - raise Exception("'Set' operations not permitted on this object") - - # - # If the name matches an argument name, set the value of the argument. - # - # print "set name=%s" % str(name) - for arg in self.event_class.arguments: - if arg.name() == name: - return self.set_attr(name, value) - - # unrecognized name? should I raise an exception? - super.__setattr__(self, name, value) - - - def __getattr__(self, name, *args): - # - # If the name matches an argument name, return the value of the argument. - # - for arg in self.event_class.arguments: - if arg.name() == name: - return self.get_attr(name) - - # - # This name means nothing to us, pass it up the line to the parent - # class's handler. - # - # print "__getattr__=%s" % str(name) - super.__getattr__(self, name) - - - def _value(self, name): - val = self.impl.getValue(name) - if not val: - raise Exception("Argument error: attribute named '%s' not defined for package %s, class %s" % - (name, - self.event_class.impl.getClassKey().getPackageName(), - self.event_class.impl.getClassKey().getClassName())) - return val - - -class QmfObject(object): - # attr_reader :impl, :object_class - def __init__(self, cls, kwargs={}): - self._cv = Condition() - self._sync_count = 0 - self._sync_result = None - self._allow_sets = False - if kwargs.has_key("broker"): - self._broker = kwargs["broker"] - else: - self._broker = None - if cls: - self.object_class = cls - self.impl = qmfengine.Object(self.object_class.impl) - elif kwargs.has_key("impl"): - self.impl = qmfengine.Object(kwargs["impl"]) - self.object_class = SchemaObjectClass(None, - None, - {"impl":self.impl.getClass()}) - else: - raise Exception("Argument error: required parameter ('impl') not supplied") - - - def destroy(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 properties(self): - list = [] - for prop in self.object_class.properties: - list.append([prop, self.get_attr(prop.name())]) - return list - - - def statistics(self): - list = [] - for stat in self.object_class.statistics: - list.append([stat, self.get_attr(stat.name())]) - return list - - - def get_attr(self, name): - val = self._value(name) - return qmf_to_native(val) - - - def set_attr(self, name, v): - val = self._value(name) - native_to_qmf(val, v) - - - 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 __setattr__(self, name, value): - # - # Ignore the internal attributes, set them normally... - # - if (name[0] == '_' or - name == 'impl' or - name == 'object_class'): - return super.__setattr__(self, name, value) - - if not self._allow_sets: - raise Exception("'Set' operations not permitted on this object") - # - # If the name matches a property name, set the value of the property. - # - # print "set name=%s" % str(name) - for prop in self.object_class.properties: - if prop.name() == name: - return self.set_attr(name, value) - # - # otherwise, check for a statistic set... - # - for stat in self.object_class.statistics: - if stat.name() == name: - return self.set_attr(name, value) - - # unrecognized name? should I raise an exception? - super.__setattr__(self, name, value) - - - def __getattr__(self, name, *args): - # - # If the name matches a property name, return the value of the property. - # - for prop in self.object_class.properties: - if prop.name() == name: - return self.get_attr(name) - # - # Do the same for statistics - # - for stat in self.object_class.statistics: - if stat.name() == name: - return self.get_attr(name) - # - # If we still haven't found a match for the name, check to see if - # it matches a method name. If so, marshall up the arguments into - # a map, and invoke the method. - # - for method in self.object_class.methods: - if method.name() == name: - argMap = self._marshall(method, args) - return lambda name, argMap : self._invokeMethod(name, argMap) - - # - # This name means nothing to us, pass it up the line to the parent - # class's handler. - # - # print "__getattr__=%s" % str(name) - super.__getattr__(self, name) - - - def _invokeMethod(self, name, argMap): - """ - Private: Helper function that invokes an object's method, and waits for the result. - """ - self._cv.acquire() - try: - timeout = 30 - self._sync_count = 1 - self.impl.invokeMethod(name, argMap, self) - if self._broker: - self._broker.conn.kick() - self._cv.wait(timeout) - if self._sync_count == 1: - raise Exception("Timed out: waiting for response to method call.") - finally: - self._cv.release() - - return self._sync_result - - - def _method_result(self, result): - """ - Called to return the result of a method call on an object - """ - self._cv.acquire(); - try: - self._sync_result = result - self._sync_count -= 1 - self._cv.notify() - finally: - self._cv.release() - - - def _marshall(schema, args): - ''' - Private: Convert a list of arguments (positional) into a Value object of type "map". - Used to create the argument parameter for an object's method invokation. - ''' - # Build a map of the method's arguments - map = qmfengine.Value(TYPE_MAP) - for arg in schema.arguments: - if arg.direction == DIR_IN or arg.direction == DIR_IN_OUT: - map.insert(arg.name, qmfengine.Value(arg.typecode)) - - # install each argument's value into the map - marshalled = Arguments(map) - idx = 0 - for arg in schema.arguments: - if arg.direction == DIR_IN or arg.direction == DIR_IN_OUT: - if args[idx]: - marshalled[arg.name] = args[idx] - idx += 1 - - return marshalled.map - - - def _value(self, name): - val = self.impl.getValue(name) - if not val: - raise Exception("Argument error: attribute named '%s' not defined for package %s, class %s" % - (name, - self.object_class.impl.getClassKey().getPackageName(), - self.object_class.impl.getClassKey().getClassName())) - return val - - - -class AgentObject(QmfObject): - def __init__(self, cls, kwargs={}): - QmfObject.__init__(self, cls, kwargs) - self._allow_sets = True - - - def destroy(self): - self.impl.destroy() - - - def set_object_id(self, oid): - self.impl.setObjectId(oid.impl) - - - -class ConsoleObject(QmfObject): - # attr_reader :current_time, :create_time, :delete_time - def __init__(self, cls, kwargs={}): - QmfObject.__init__(self, cls, kwargs) - - - def update(self): - if not self._broker: - raise Exception("No linkage to broker") - newer = self._broker.console.objects(Query({"object_id":object_id})) - if newer.size != 1: - raise Exception("Expected exactly one update for this object, %d present" % int(newer.size)) - self.merge_update(newer[0]) - - - def merge_update(self, newObject): - self.impl.merge(new_object.impl) - - - def is_deleted(self): - return self.impl.isDeleted() - - - def key(self): pass - - - -class ObjectId: - def __init__(self, impl=None): - if impl: - self.impl = impl - else: - self.impl = qmfengine.ObjectId() - self.agent_key = "%d.%d" % (self.impl.getBrokerBank(), self.impl.getAgentBank()) - - - def object_num_high(self): - return self.impl.getObjectNumHi() - - - def object_num_low(self): - return self.impl.getObjectNumLo() - - - def agent_key(self): - self.agent_key - - def __eq__(self, other): - if not isinstance(other, self.__class__): return False - return self.impl == other.impl - - def __ne__(self, other): - return not self.__eq__(other) - - def __repr__(self): - return self.impl.str() - - - -class Arguments(object): - def __init__(self, map): - self.map = map - self._by_hash = {} - key_count = self.map.keyCount() - a = 0 - while a < key_count: - key = self.map.key(a) - self._by_hash[key] = qmf_to_native(self.map.byKey(key)) - 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 self._by_hash.__iter__ - - - def __getattr__(self, name): - if name in self._by_hash: - return self._by_hash[name] - return super.__getattr__(self, name) - - - def __setattr__(self, name, value): - # - # ignore local data members - # - if (name[0] == '_' or - name == 'map'): - return super.__setattr__(self, name, value) - - if name in self._by_hash: - self._by_hash[name] = value - return self.set(name, value) - - return super.__setattr__(self, name, value) - - - def set(self, key, value): - val = self.map.byKey(key) - native_to_qmf(val, value) - - - -class MethodResponse(object): - def __init__(self, impl): - self.impl = qmfengine.MethodResponse(impl) - - - def status(self): - return self.impl.getStatus() - - - def exception(self): - return self.impl.getException() - - - def text(self): - return exception().asString() - - - def args(self): - return Arguments(self.impl.getArgs()) - - - def __getattr__(self, name): - myArgs = self.args() - return myArgs.__getattr__(name) - - - def __setattr__(self, name, value): - if name == 'impl': - return super.__setattr__(self, name, value) - - myArgs = self.args() - return myArgs.__setattr__(name, value) - - - - ##============================================================================== - ## QUERY - ##============================================================================== - - -class Query: - def __init__(self, kwargs={}): - if "impl" in kwargs: - self.impl = kwargs["impl"] - else: - package = '' - if "key" in kwargs: - # construct using SchemaClassKey: - self.impl = qmfengine.Query(kwargs["key"]) - elif "object_id" in kwargs: - self.impl = qmfengine.Query(kwargs["object_id"].impl) - else: - if "package" in kwargs: - package = kwargs["package"] - if "class" in kwargs: - self.impl = qmfengine.Query(kwargs["class"], package) - else: - raise Exception("Argument error: invalid arguments, use 'key', 'object_id' or 'class'[,'package']") - - - 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 - - - ##============================================================================== - ## SCHEMA - ##============================================================================== - - - -class SchemaArgument: - #attr_reader :impl - def __init__(self, name, typecode, kwargs={}): - if "impl" in kwargs: - self.impl = kwargs["impl"] - else: - 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"]) - - - def name(self): - return self.impl.getName() - - - def direction(self): - return self.impl.getDirection() - - - def typecode(self): - return self.impl.getType() - - - def __repr__(self): - return self.name() - - - -class SchemaMethod: - # attr_reader :impl, arguments - def __init__(self, name, kwargs={}): - self.arguments = [] - if "impl" in kwargs: - self.impl = kwargs["impl"] - for i in range(self.impl.getArgumentCount()): - self.arguments.append(SchemaArgument(None,None,{"impl":self.impl.getArgument(i)})) - else: - self.impl = qmfengine.SchemaMethod(name) - if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"]) - - - def add_argument(self, arg): - self.arguments.append(arg) - self.impl.addArgument(arg.impl) - - def name(self): - return self.impl.getName() - - def __repr__(self): - return self.name() - - - -class SchemaProperty: - #attr_reader :impl - def __init__(self, name, typecode, kwargs={}): - if "impl" in kwargs: - self.impl = kwargs["impl"] - else: - 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() - - def __repr__(self): - return self.name() - - - -class SchemaStatistic: - # attr_reader :impl - def __init__(self, name, typecode, kwargs={}): - if "impl" in kwargs: - self.impl = kwargs["impl"] - else: - 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"]) - - - def name(self): - return self.impl.getName() - - def __repr__(self): - return self.name() - - - -class SchemaClassKey: - #attr_reader :impl - def __init__(self, i): - self.impl = i - - - def package_name(self): - return self.impl.getPackageName() - - - def class_name(self): - return self.impl.getClassName() - - def __repr__(self): - return self.impl.asString() - - - -class SchemaObjectClass: - # attr_reader :impl, :properties, :statistics, :methods - def __init__(self, package, name, kwargs={}): - self.properties = [] - self.statistics = [] - self.methods = [] - if "impl" in kwargs: - self.impl = kwargs["impl"] - - for i in range(self.impl.getPropertyCount()): - self.properties.append(SchemaProperty(None, None, {"impl":self.impl.getProperty(i)})) - - for i in range(self.impl.getStatisticCount()): - self.statistics.append(SchemaStatistic(None, None, {"impl":self.impl.getStatistic(i)})) - - for i in range(self.impl.getMethodCount()): - self.methods.append(SchemaMethod(None, {"impl":self.impl.getMethod(i)})) - else: - self.impl = qmfengine.SchemaObjectClass(package, name) - - - 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 class_key(self): - return SchemaClassKey(self.impl.getClassKey()) - - - def package_name(self): - return self.impl.getClassKey().getPackageName() - - - def class_name(self): - return self.impl.getClassKey().getClassName() - - - -class SchemaEventClass: - # attr_reader :impl :arguments - def __init__(self, package, name, sev, kwargs={}): - self.arguments = [] - if "impl" in kwargs: - self.impl = kwargs["impl"] - for i in range(self.impl.getArgumentCount()): - self.arguments.append(SchemaArgument(nil, nil, {"impl":self.impl.getArgument(i)})) - else: - self.impl = qmfengine.SchemaEventClass(package, name, sev) - if kwargs.has_key("desc"): self.impl.setDesc(kwargs["desc"]) - - - def add_argument(self, arg): - self.arguments.append(arg) - self.impl.addArgument(arg.impl) - - - def name(self): - return self.impl.getClassKey().getClassName() - - def class_key(self): - return SchemaClassKey(self.impl.getClassKey()) - - - def package_name(self): - return self.impl.getClassKey().getPackageName() - - - def class_name(self): - return self.impl.getClassKey().getClassName() - - - ##============================================================================== - ## 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(Thread): - # attr_reader :impl - def __init__(self, handler=None, kwargs={}): - Thread.__init__(self) - self._handler = handler - self.impl = qmfengine.Console() - self._event = qmfengine.ConsoleEvent() - self._broker_list = [] - self._cv = Condition() - self._sync_count = 0 - self._sync_result = None - self._select = {} - self._cb_cond = Condition() - self._operational = True - self.start() - - - def destroy(self, timeout=None): - logging.debug("Destroying Console...") - self._operational = False - self.start_console_events() # wake thread up - self.join(timeout) - logging.debug("... Console Destroyed!") - if self.isAlive(): - logging.error( "Console thread '%s' is hung..." % self.getName() ) - - - def add_connection(self, conn): - broker = Broker(self, conn) - self._cv.acquire() - try: - self._broker_list.append(broker) - finally: - self._cv.release() - return broker - - - def del_connection(self, broker): - logging.debug("shutting down broker...") - broker.shutdown() - logging.debug("...broker down.") - self._cv.acquire() - try: - self._broker_list.remove(broker) - finally: - self._cv.release() - logging.debug("del_connection() finished") - - - def packages(self): - plist = [] - for i in range(self.impl.packageCount()): - plist.append(self.impl.getPackageName(i)) - return plist - - - def classes(self, package, kind=CLASS_OBJECT): - clist = [] - for i in range(self.impl.classCount(package)): - key = self.impl.getClass(package, i) - class_kind = self.impl.getClassKind(key) - if class_kind == kind: - if kind == CLASS_OBJECT: - clist.append(SchemaObjectClass(None, None, {"impl":self.impl.getObjectClass(key)})) - elif kind == CLASS_EVENT: - clist.append(SchemaEventClass(None, None, 0, {"impl":self.impl.getEventClass(key)})) - return clist - - - def bind_package(self, package): - return self.impl.bindPackage(package) - - - def bind_class(self, kwargs = {}): - if "key" in kwargs: - self.impl.bindClass(kwargs["key"]) - elif "package" in kwargs: - package = kwargs["package"] - if "class" in kwargs: - self.impl.bindClass(package, kwargs["class"]) - else: - self.impl.bindClass(package, "*") - else: - raise Exception("Argument error: invalid arguments, use 'key' or 'package'[,'class']") - - - def bind_event(self, kwargs = {}): - if "key" in kwargs: - self.impl.bindEvent(kwargs["key"]) - elif "package" in kwargs: - package = kwargs["package"] - if "event" in kwargs: - self.impl.bindEvent(package, kwargs["event"]) - else: - self.impl.bindEvent(package, "*") - else: - raise Exception("Argument error: invalid arguments, use 'key' or 'package'[,'event']") - - - def agents(self, broker=None): - blist = [] - if broker: - blist.append(broker) - else: - self._cv.acquire() - try: - # copy while holding lock - blist = self._broker_list[:] - finally: - self._cv.release() - - agents = [] - for b in blist: - for idx in range(b.impl.agentCount()): - agents.append(AgentProxy(b.impl.getAgent(idx), b)) - - return agents - - - def objects(self, query, kwargs = {}): - timeout = 30 - agent = None - temp_args = kwargs.copy() - if type(query) == type({}): - temp_args.update(query) - - if "_timeout" in temp_args: - timeout = temp_args["_timeout"] - temp_args.pop("_timeout") - - if "_agent" in temp_args: - agent = temp_args["_agent"] - temp_args.pop("_agent") - - if type(query) == type({}): - query = Query(temp_args) - - self._select = {} - for k in temp_args.iterkeys(): - if type(k) == str: - self._select[k] = temp_args[k] - - self._cv.acquire() - try: - self._sync_count = 1 - self._sync_result = [] - broker = self._broker_list[0] - broker.send_query(query.impl, None, agent) - self._cv.wait(timeout) - if self._sync_count == 1: - raise Exception("Timed out: waiting for query response") - finally: - self._cv.release() - - return self._sync_result - - - def object(self, query, kwargs = {}): - ''' - Return one and only one object or None. - ''' - objs = objects(query, kwargs) - if len(objs) == 1: - return objs[0] - else: - return None - - - def first_object(self, query, kwargs = {}): - ''' - Return the first of potentially many objects. - ''' - objs = objects(query, kwargs) - if objs: - return objs[0] - else: - return None - - - # Check the object against select to check for a match - def _select_match(self, object): - schema_props = object.properties() - for key in self._select.iterkeys(): - for prop in schema_props: - if key == p[0].name() and self._select[key] != p[1]: - return False - return True - - - def _get_result(self, list, context): - ''' - Called by Broker proxy to return the result of a query. - ''' - self._cv.acquire() - try: - for item in list: - if self._select_match(item): - self._sync_result.append(item) - self._sync_count -= 1 - self._cv.notify() - finally: - self._cv.release() - - - def start_sync(self, query): pass - - - def touch_sync(self, sync): pass - - - def end_sync(self, sync): pass - - - def run(self): - while self._operational: - self._cb_cond.acquire() - try: - self._cb_cond.wait(1) - while self._do_console_events(): - pass - finally: - self._cb_cond.release() - logging.debug("Shutting down Console thread") - - - def start_console_events(self): - self._cb_cond.acquire() - try: - self._cb_cond.notify() - finally: - self._cb_cond.release() - - - def _do_console_events(self): - ''' - Called by the Console thread to poll for events. Passes the events - onto the ConsoleHandler associated with this Console. Is called - periodically, but can also be kicked by Console.start_console_events(). - ''' - count = 0 - valid = self.impl.getEvent(self._event) - while valid: - count += 1 - try: - if self._event.kind == qmfengine.ConsoleEvent.AGENT_ADDED: - logging.debug("Console Event AGENT_ADDED received") - if self._handler: - self._handler.agent_added(AgentProxy(self._event.agent, None)) - elif self._event.kind == qmfengine.ConsoleEvent.AGENT_DELETED: - logging.debug("Console Event AGENT_DELETED received") - if self._handler: - self._handler.agent_deleted(AgentProxy(self._event.agent, None)) - elif self._event.kind == qmfengine.ConsoleEvent.NEW_PACKAGE: - logging.debug("Console Event NEW_PACKAGE received") - if self._handler: - self._handler.new_package(self._event.name) - elif self._event.kind == qmfengine.ConsoleEvent.NEW_CLASS: - logging.debug("Console Event NEW_CLASS received") - if self._handler: - self._handler.new_class(SchemaClassKey(self._event.classKey)) - elif self._event.kind == qmfengine.ConsoleEvent.OBJECT_UPDATE: - logging.debug("Console Event OBJECT_UPDATE received") - if self._handler: - self._handler.object_update(ConsoleObject(None, {"impl":self._event.object}), - self._event.hasProps, self._event.hasStats) - elif self._event.kind == qmfengine.ConsoleEvent.EVENT_RECEIVED: - logging.debug("Console Event EVENT_RECEIVED received") - elif self._event.kind == qmfengine.ConsoleEvent.AGENT_HEARTBEAT: - logging.debug("Console Event AGENT_HEARTBEAT received") - if self._handler: - self._handler.agent_heartbeat(AgentProxy(self._event.agent, None), self._event.timestamp) - elif self._event.kind == qmfengine.ConsoleEvent.METHOD_RESPONSE: - logging.debug("Console Event METHOD_RESPONSE received") - else: - logging.debug("Console thread received unknown event: '%s'" % str(self._event.kind)) - except e: - print "Exception caught in callback thread:", e - self.impl.popEvent() - valid = self.impl.getEvent(self._event) - return count - - - -class AgentProxy: - # attr_reader :broker - def __init__(self, impl, broker): - self.impl = impl - self.broker = broker - self.key = "%d.%d" % (self.impl.getBrokerBank(), self.impl.getAgentBank()) - - - def label(self): - return self.impl.getLabel() - - - def key(self): - return self.key - - -class Broker(ConnectionHandler): - # attr_reader :impl :conn, :console, :broker_bank - def __init__(self, console, conn): - self.broker_bank = 1 - self.console = console - self.conn = conn - self._session = None - self._cv = Condition() - self._stable = 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) - self._operational = True - - - def shutdown(self): - logging.debug("broker.shutdown() called.") - self.console.impl.delConnection(self.impl) - self.conn.del_conn_handler(self) - if self._session: - self.impl.sessionClosed() - logging.debug("broker.shutdown() sessionClosed done.") - self._session.destroy() - logging.debug("broker.shutdown() session destroy done.") - self._session = None - self._operational = False - logging.debug("broker.shutdown() done.") - - - def wait_for_stable(self, timeout = None): - self._cv.acquire() - try: - if self._stable: - return - if timeout: - self._cv.wait(timeout) - if not self._stable: - raise Exception("Timed out: waiting for broker connection to become stable") - else: - while not self._stable: - self._cv.wait() - finally: - self._cv.release() - - - def send_query(self, query, ctx, agent): - agent_impl = None - if agent: - agent_impl = agent.impl - self.impl.sendQuery(query, ctx, agent_impl) - self.conn.kick() - - - def _do_broker_events(self): - count = 0 - valid = self.impl.getEvent(self._event) - while valid: - count += 1 - if self._event.kind == qmfengine.BrokerEvent.BROKER_INFO: - logging.debug("Broker Event BROKER_INFO received"); - elif self._event.kind == qmfengine.BrokerEvent.DECLARE_QUEUE: - logging.debug("Broker Event DECLARE_QUEUE received"); - self.conn.impl.declareQueue(self._session.handle, self._event.name) - elif self._event.kind == qmfengine.BrokerEvent.DELETE_QUEUE: - logging.debug("Broker Event DELETE_QUEUE received"); - self.conn.impl.deleteQueue(self._session.handle, self._event.name) - elif self._event.kind == qmfengine.BrokerEvent.BIND: - logging.debug("Broker Event BIND received"); - self.conn.impl.bind(self._session.handle, self._event.exchange, self._event.name, self._event.bindingKey) - elif self._event.kind == qmfengine.BrokerEvent.UNBIND: - logging.debug("Broker Event UNBIND received"); - self.conn.impl.unbind(self._session.handle, self._event.exchange, self._event.name, self._event.bindingKey) - elif self._event.kind == qmfengine.BrokerEvent.SETUP_COMPLETE: - logging.debug("Broker Event SETUP_COMPLETE received"); - self.impl.startProtocol() - elif self._event.kind == qmfengine.BrokerEvent.STABLE: - logging.debug("Broker Event STABLE received"); - self._cv.acquire() - try: - self._stable = True - self._cv.notify() - finally: - self._cv.release() - elif self._event.kind == qmfengine.BrokerEvent.QUERY_COMPLETE: - result = [] - for idx in range(self._event.queryResponse.getObjectCount()): - result.append(ConsoleObject(None, {"impl":self._event.queryResponse.getObject(idx), "broker":self})) - self.console._get_result(result, self._event.context) - elif self._event.kind == qmfengine.BrokerEvent.METHOD_RESPONSE: - obj = self._event.context - obj._method_result(MethodResponse(self._event.methodResponse())) - - 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 - logging.debug("Broker: sending msg on connection") - 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: - self.console.start_console_events() - bcnt = self._do_broker_events() - mcnt = self._do_broker_messages() - if bcnt == 0 and mcnt == 0: - break; - - - def conn_event_connected(self): - logging.debug("Broker: Connection event CONNECTED") - 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): - logging.debug("Broker: Connection event DISCONNECTED") - pass - - - def conn_event_visit(self): - self._do_events() - - - def sess_event_session_closed(self, context, error): - logging.debug("Broker: Session event CLOSED") - self.impl.sessionClosed() - - - def sess_event_recv(self, context, message): - logging.debug("Broker: Session event MSG_RECV") - if not self._operational: - logging.warning("Unexpected session event message received by Broker proxy: context='%s'" % str(context)) - 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.Agent(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 raise_event(self, event): - self.impl.raiseEvent(event.impl) - - 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({"impl":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): - logging.debug("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): - logging.debug("Agent Connection Lost") - pass - - - def conn_event_visit(self): - self.do_events() - - - def sess_event_session_closed(self, context, error): - logging.debug("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/ruby/CMakeLists.txt b/qpid/cpp/bindings/qmf/ruby/CMakeLists.txt deleted file mode 100644 index 37ce73293f..0000000000 --- a/qpid/cpp/bindings/qmf/ruby/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -##------------------------------------------------------ -## Use Swig to generate a literal binding to the C++ API -##------------------------------------------------------ -set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ruby.i PROPERTIES CPLUSPLUS ON) - -if ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8)) - set (RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_PATH}) -endif ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8)) - -include_directories(${RUBY_INCLUDE_DIRS} - ${qpid-cpp_SOURCE_DIR}/include - ${qpid-cpp_SOURCE_DIR}/bindings) - -swig_add_module(qmfengine_ruby ruby ${CMAKE_CURRENT_SOURCE_DIR}/ruby.i) -swig_link_libraries(qmfengine_ruby qmf qmfconsole ${RUBY_LIBRARY}) - -##---------------------------------- -## Install the complete Ruby binding -##---------------------------------- -if ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8)) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qmfengine_ruby.so - RENAME qmfengine.so - DESTINATION ${RUBY_PFX_ARCH_DIR} - COMPONENT ${QPID_COMPONENT_CLIENT} - ) -else() - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libqmfengine_ruby.so - RENAME qmfengine.so - DESTINATION ${RUBY_PFX_ARCH_DIR} - COMPONENT ${QPID_COMPONENT_CLIENT} - ) -endif ((${CMAKE_MAJOR_VERSION} EQUAL 2) AND (${CMAKE_MINOR_VERSION} LESS 8)) diff --git a/qpid/cpp/bindings/qmf/ruby/Makefile.am b/qpid/cpp/bindings/qmf/ruby/Makefile.am deleted file mode 100644 index 488d5550c5..0000000000 --- a/qpid/cpp/bindings/qmf/ruby/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -if HAVE_RUBY_DEVEL - -INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src - -EXTRA_DIST = $(srcdir)/CMakeLists.txt $(srcdir)/ruby.i -BUILT_SOURCES = qmfengine.cpp -SWIG_FLAGS = -w362,401 - -rubylibdir = $(RUBY_LIB) - -dist_rubylib_DATA = qmf.rb - -qmfengine.cpp: $(srcdir)/ruby.i - $(SWIG) -ruby -c++ $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o qmfengine.cpp $(srcdir)/ruby.i - -rubylibarchdir = $(RUBY_LIB_ARCH) -rubylibarch_LTLIBRARIES = qmfengine.la - -qmfengine_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)" -qmfengine_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidclient $(top_builddir)/src/libqmfengine.la -qmfengine_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing -nodist_qmfengine_la_SOURCES = qmfengine.cpp - -CLEANFILES = qmfengine.cpp - -endif # HAVE_RUBY_DEVEL diff --git a/qpid/cpp/bindings/qmf/ruby/qmf.rb b/qpid/cpp/bindings/qmf/ruby/qmf.rb deleted file mode 100644 index d05127db4b..0000000000 --- a/qpid/cpp/bindings/qmf/ruby/qmf.rb +++ /dev/null @@ -1,1528 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -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| - c = c.to_s - if c.index('TYPE_') == 0 or c.index('ACCESS_') == 0 or c.index('DIR_') == 0 or - c.index('CLASS_') == 0 or c.index('SEV_') == 0 - const_set(c, Qmfengine.const_get(c)) - end - end - - module StringHelpers - def ensure_encoding(str) - enc = (Encoding.default_external.name || "UTF-8" rescue "UTF-8") - str.respond_to?(:force_encoding) ? str.force_encoding(enc) : str - end - end - - class Util - include StringHelpers - - def qmf_to_native(val) - 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 ensure_encoding(val.asString) - when TYPE_ABSTIME then val.asInt64 - when TYPE_DELTATIME then val.asUint64 - when TYPE_REF then ObjectId.new(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 then value_to_dict(val) - when TYPE_LIST then value_to_list(val) - when TYPE_OBJECT - when TYPE_ARRAY - end - end - - def native_to_qmf(target, value) - if target.class == Qmfengine::Value - val = target - typecode = val.getType - else - typecode = target - val = Qmfengine::Value.new(typecode) - end - - case typecode - 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 then dict_to_value(val, value) - when TYPE_LIST then list_to_value(val, value) - when TYPE_OBJECT - when TYPE_ARRAY - end - return val - end - - def pick_qmf_type(value) - if value.class == Fixnum - if value >= 0 - return TYPE_UINT32 if value < 0x100000000 - return TYPE_UINT64 - else - return TYPE_INT32 if value > -0xffffffff - return TYPE_INT64 - end - end - - if value.class == Bignum - return TYPE_UINT64 if value >= 0 - return TYPE_INT64 - end - - if value.class == String - return TYPE_SSTR if value.length < 256 - return TYPE_LSTR - end - - return TYPE_DOUBLE if value.class == Float - - return TYPE_BOOL if value.class == TrueClass - return TYPE_BOOL if value.class == FalseClass - return TYPE_BOOL if value.class == NilClass - - return TYPE_MAP if value.class == Hash - return TYPE_LIST if value.class == Array - - raise ArgumentError, "QMF type not known for native type #{value.class}" - end - - def value_to_dict(val) - # Assume val is of type Qmfengine::Value - raise ArgumentError, "value_to_dict must be given a map value" if !val.isMap - map = {} - for i in 0...val.keyCount - key = val.key(i) - map[key] = qmf_to_native(val.byKey(key)) - end - return map - end - - def dict_to_value(val, map) - map.each do |key, value| - raise ArgumentError, "QMF map key must be a string" if key.class != String - typecode = pick_qmf_type(value) - val.insert(key, native_to_qmf(typecode, value)) - end - end - - def value_to_list(val) - # Assume val is of type Qmfengine::Value - raise ArgumentError, "value_to_dict must be given a map value" if !val.isList - list = [] - for i in 0...val.listItemCount - list.push(qmf_to_native(val.listItem(i))) - end - return list - end - - def list_to_value(val, list) - list.each do |value| - typecode = pick_qmf_type(value) - val.appendToList(native_to_qmf(typecode, value)) - end - end - end - - $util = Util.new - - ##============================================================================== - ## CONNECTION - ##============================================================================== - - class ConnectionSettings - include StringHelpers - attr_reader :impl - - def initialize(url = nil) - if url - @impl = Qmfengine::ConnectionSettings.new(url) - else - @impl = Qmfengine::ConnectionSettings.new() - end - 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 - - good = @impl.setAttr(key, v) - raise "Invalid attribute '#{key}'" unless good - end - - def get_attr(key) - _v = @impl.getAttr(key) - if _v.isString() - return ensure_encoding(_v.asString()) - elsif _v.isUint() - return _v.asUint() - elsif _v.isBool() - return _v.asBool() - else - raise Exception("Argument error: value for attribute '#{key}' has unsupported type: #{_v.getType()}") - end - end - - - def method_missing(name_in, *args) - name = name_in.to_s - if name[name.length - 1] == 61 - attr = name[0..name.length - 2] - set_attr(attr, args[0]) - return - else - return get_attr(name) - end - end - end - - class ConnectionHandler - def conn_event_connected(); end - def conn_event_disconnected(error); end - def conn_event_visit(); end - def sess_event_session_closed(context, error); end - def sess_event_recv(context, message); end - end - - class Connection - include MonitorMixin - - attr_reader :impl - - 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_to_delete = [] - @conn_handlers = [] - @connected = nil - - @thread = Thread.new do - run - end - end - - def connected? - @connected - end - - def kick - @impl.notify - end - - def add_conn_handler(handler) - synchronize do - @new_conn_handlers << handler - end - kick - end - - def del_conn_handler(handler) - synchronize do - @conn_handlers_to_delete << handler - end - kick - end - - def run() - eventImpl = Qmfengine::ResilientConnectionEvent.new - new_handlers = nil - del_handlers = nil - bt_count = 0 - - while :true - @sock.read(1) - - synchronize do - new_handlers = @new_conn_handlers - del_handlers = @conn_handlers_to_delete - @new_conn_handlers = [] - @conn_handlers_to_delete = [] - end - - new_handlers.each do |nh| - @conn_handlers << nh - nh.conn_event_connected() if @connected - end - new_handlers = nil - - del_handlers.each do |dh| - d = @conn_handlers.delete(dh) - end - del_handlers = nil - - 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 - if bt_count < 2 - bt_count += 1 - end - end - @impl.popEvent - valid = @impl.getEvent(eventImpl) - end - @conn_handlers.each { |h| h.conn_event_visit } - end - end - end - - class Session - attr_reader :handle, :handler - - def initialize(conn, label, handler) - @conn = conn - @label = label - @handler = handler - @handle = Qmfengine::SessionHandle.new - result = @conn.impl.createSession(label, self, @handle) - end - - def destroy() - @conn.impl.destroySession(@handle) - end - end - - ##============================================================================== - ## OBJECTS and EVENTS - ##============================================================================== - - class QmfEvent - attr_reader :impl, :event_class - def initialize(cls, kwargs={}) - @broker = kwargs[:broker] if kwargs.include?(:broker) - @allow_sets = :true - - if cls - @event_class = cls - @impl = Qmfengine::Event.new(@event_class.impl) - elsif kwargs.include?(:impl) - @impl = Qmfengine::Event.new(kwargs[:impl]) - @event_class = SchemaEventClass.new(nil, nil, nil, :impl => @impl.getClass) - end - end - - def arguments - list = [] - @event_class.arguments.each do |arg| - list << [arg, get_attr(arg.name)] - end - return list - end - - def get_attr(name) - val = value(name) - $util.qmf_to_native(val) - end - - def set_attr(name, v) - val = value(name) - $util.native_to_qmf(val, v) - end - - def [](name) - get_attr(name) - end - - def []=(name, value) - set_attr(name, value) - end - - def method_missing(name_in, *args) - # - # Convert the name to a string and determine if it represents an - # attribute assignment (i.e. "attr=") - # - name = name_in.to_s - attr_set = (name[name.length - 1] == 61) - name = name[0..name.length - 2] if attr_set - raise "Sets not permitted on this object" if attr_set && !@allow_sets - - # - # If the name matches an argument name, set or return the value of the argument. - # - @event_class.arguments.each do |arg| - if arg.name == name - if attr_set - return set_attr(name, args[0]) - else - return get_attr(name) - end - end - end - - # - # This name means nothing to us, pass it up the line to the parent - # class's handler. - # - super.method_missing(name_in, args) - end - - private - def value(name) - val = @impl.getValue(name.to_s) - if val.nil? - raise ArgumentError, "Attribute '#{name}' not defined for event #{@event_class.impl.getClassKey.getPackageName}:#{@object_class.impl.getClassKey.getClassName}" - end - return val - end - end - - class QmfObject - include MonitorMixin - attr_reader :impl, :object_class - def initialize(cls, kwargs={}) - super() - @cv = new_cond - @sync_count = 0 - @sync_result = nil - @allow_sets = :false - @broker = kwargs[:broker] if kwargs.include?(:broker) - - if cls - @object_class = cls - @impl = Qmfengine::Object.new(@object_class.impl) - elsif kwargs.include?(:impl) - @impl = Qmfengine::Object.new(kwargs[:impl]) - @object_class = SchemaObjectClass.new(nil, nil, :impl => @impl.getClass) - end - end - - def object_id - return ObjectId.new(@impl.getObjectId) - end - - def properties - list = [] - @object_class.properties.each do |prop| - list << [prop, get_attr(prop.name)] - end - return list - end - - def statistics - list = [] - @object_class.statistics.each do |stat| - list << [stat, get_attr(stat.name)] - end - return list - end - - def get_attr(name) - val = value(name) - $util.qmf_to_native(val) - end - - def set_attr(name, v) - val = value(name) - $util.native_to_qmf(val, v) - end - - def [](name) - get_attr(name) - end - - def []=(name, value) - set_attr(name, value) - end - - def inc_attr(name, by=1) - set_attr(name, get_attr(name) + by) - end - - def dec_attr(name, by=1) - set_attr(name, get_attr(name) - by) - end - - def method_missing(name_in, *args) - # - # Convert the name to a string and determine if it represents an - # attribute assignment (i.e. "attr=") - # - name = name_in.to_s - attr_set = (name[name.length - 1] == 61) - name = name[0..name.length - 2] if attr_set - raise "Sets not permitted on this object" if attr_set && !@allow_sets - - # - # If the name matches a property name, set or return the value of the property. - # - @object_class.properties.each do |prop| - if prop.name == name - if attr_set - return set_attr(name, args[0]) - else - return get_attr(name) - end - end - end - - # - # Do the same for statistics - # - @object_class.statistics.each do |stat| - if stat.name == name - if attr_set - return set_attr(name, args[0]) - else - return get_attr(name) - end - end - end - - # - # If we still haven't found a match for the name, check to see if - # it matches a method name. If so, marshall the arguments and invoke - # the method. - # - @object_class.methods.each do |method| - if method.name == name - raise "Sets not permitted on methods" if attr_set - timeout = 30 - synchronize do - @sync_count = 1 - @impl.invokeMethod(name, _marshall(method, args), self) - @broker.conn.kick if @broker - unless @cv.wait(timeout) { @sync_count == 0 } - raise "Timed out waiting for response" - end - end - - return @sync_result - end - end - - # - # This name means nothing to us, pass it up the line to the parent - # class's handler. - # - super.method_missing(name_in, args) - end - - def _method_result(result) - synchronize do - @sync_result = result - @sync_count -= 1 - @cv.signal - end - end - - # - # Convert a Ruby array of arguments (positional) into a Value object of type "map". - # - private - def _marshall(schema, args) - map = Qmfengine::Value.new(TYPE_MAP) - schema.arguments.each do |arg| - if arg.direction == DIR_IN || arg.direction == DIR_IN_OUT - map.insert(arg.name, Qmfengine::Value.new(arg.typecode)) - end - end - - marshalled = Arguments.new(map) - idx = 0 - schema.arguments.each do |arg| - if arg.direction == DIR_IN || arg.direction == DIR_IN_OUT - marshalled[arg.name] = args[idx] unless args[idx] == nil - idx += 1 - end - end - - return marshalled.map - 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.getClassKey.getPackageName}:#{@object_class.impl.getClassKey.getClassName}" - end - return val - end - end - - class AgentObject < QmfObject - def initialize(cls, kwargs={}) - super(cls, kwargs) - @allow_sets = :true - end - - def destroy - @impl.destroy - end - - def set_object_id(oid) - @impl.setObjectId(oid.impl) - end - end - - class ConsoleObject < QmfObject - attr_reader :current_time, :create_time, :delete_time - - def initialize(cls, kwargs={}) - super(cls, kwargs) - end - - def update() - raise "No linkage to broker" unless @broker - newer = @broker.console.objects(Query.new(:object_id => object_id)) - raise "Expected exactly one update for this object" unless newer.size == 1 - merge_update(newer[0]) - end - - def merge_update(new_object) - @impl.merge(new_object.impl) - end - - def deleted?() - @impl.isDeleted - end - - def key() - end - end - - class ObjectId - attr_reader :impl, :agent_key - def initialize(impl=nil) - if impl - @impl = Qmfengine::ObjectId.new(impl) - else - @impl = Qmfengine::ObjectId.new - end - @agent_key = "#{@impl.getBrokerBank}.#{@impl.getAgentBank}" - end - - def object_num_high - @impl.getObjectNumHi - end - - def object_num_low - @impl.getObjectNumLo - end - - def ==(other) - return @impl == other.impl - end - - def to_s - @impl.str - end - end - - class Arguments - attr_reader :map - def initialize(map) - @map = map - @by_hash = {} - key_count = @map.keyCount - a = 0 - while a < key_count - key = @map.key(a) - @by_hash[key] = $util.qmf_to_native(@map.byKey(key)) - a += 1 - end - end - - 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 method_missing(name, *args) - if @by_hash.include?(name.to_s) - return @by_hash[name.to_s] - end - - super.method_missing(name, args) - end - - def set(key, value) - val = @map.byKey(key) - $util.native_to_qmf(val, value) - end - end - - class MethodResponse - include StringHelpers - - def initialize(impl) - @impl = Qmfengine::MethodResponse.new(impl) - end - - def status - @impl.getStatus - end - - def exception - @impl.getException - end - - def text - ensure_encoding(exception.asString) - end - - def args - Arguments.new(@impl.getArgs) - end - - def method_missing(name, *extra_args) - args.__send__(name, extra_args) - end - end - - ##============================================================================== - ## QUERY - ##============================================================================== - - class Query - attr_reader :impl - def initialize(kwargs = {}) - if kwargs.include?(:impl) - @impl = Qmfengine::Query.new(kwargs[:impl]) - else - package = '' - if kwargs.include?(:key) - @impl = Qmfengine::Query.new(kwargs[:key]) - elsif kwargs.include?(:object_id) - @impl = Qmfengine::Query.new(kwargs[:object_id].impl) - else - package = kwargs[:package] if kwargs.include?(:package) - if kwargs.include?(:class) - @impl = Qmfengine::Query.new(kwargs[:class], package) - else - raise ArgumentError, "Invalid arguments, use :key, :object_id or :class[,:package]" - end - end - end - 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={}) - if kwargs.include?(:impl) - @impl = kwargs[:impl] - else - @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 - - def name - @impl.getName - end - - def direction - @impl.getDirection - end - - def typecode - @impl.getType - end - - def to_s - name - end - end - - class SchemaMethod - attr_reader :impl, :arguments - def initialize(name, kwargs={}) - @arguments = [] - if kwargs.include?(:impl) - @impl = kwargs[:impl] - arg_count = @impl.getArgumentCount - for i in 0...arg_count - @arguments << SchemaArgument.new(nil, nil, :impl => @impl.getArgument(i)) - end - else - @impl = Qmfengine::SchemaMethod.new(name) - @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc) - end - end - - def add_argument(arg) - @arguments << arg - @impl.addArgument(arg.impl) - end - - def name - @impl.getName - end - - def to_s - name - end - end - - class SchemaProperty - attr_reader :impl - def initialize(name, typecode, kwargs={}) - if kwargs.include?(:impl) - @impl = kwargs[:impl] - else - @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 - end - - def name - @impl.getName - end - - def to_s - name - end - end - - class SchemaStatistic - attr_reader :impl - def initialize(name, typecode, kwargs={}) - if kwargs.include?(:impl) - @impl = kwargs[:impl] - else - @impl = Qmfengine::SchemaStatistic.new(name, typecode) - @impl.setUnit(kwargs[:unit]) if kwargs.include?(:unit) - @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc) - end - end - - def name - @impl.getName - end - - def to_s - name - end - end - - class SchemaClassKey - include StringHelpers - attr_reader :impl - def initialize(i) - @impl = Qmfengine::SchemaClassKey.new(i) - end - - def package_name - @impl.getPackageName - end - - def class_name - @impl.getClassName - end - - def to_s - ensure_encoding(@impl.asString) - end - end - - class SchemaObjectClass - attr_reader :impl, :properties, :statistics, :methods - def initialize(package, name, kwargs={}) - @properties = [] - @statistics = [] - @methods = [] - if kwargs.include?(:impl) - @impl = kwargs[:impl] - - @impl.getPropertyCount.times do |i| - @properties << SchemaProperty.new(nil, nil, :impl => @impl.getProperty(i)) - end - - @impl.getStatisticCount.times do |i| - @statistics << SchemaStatistic.new(nil, nil, :impl => @impl.getStatistic(i)) - end - - @impl.getMethodCount.times do |i| - @methods << SchemaMethod.new(nil, :impl => @impl.getMethod(i)) - end - else - @impl = Qmfengine::SchemaObjectClass.new(package, name) - end - 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_method(meth) - @methods << meth - @impl.addMethod(meth.impl) - end - - def class_key - SchemaClassKey.new(@impl.getClassKey) - end - - def package_name - @impl.getClassKey.getPackageName - end - - def class_name - @impl.getClassKey.getClassName - end - end - - class SchemaEventClass - attr_reader :impl, :arguments - def initialize(package, name, sev, kwargs={}) - @arguments = [] - if kwargs.include?(:impl) - @impl = kwargs[:impl] - @impl.getArgumentCount.times do |i| - @arguments << SchemaArgument.new(nil, nil, :impl => @impl.getArgument(i)) - end - else - @impl = Qmfengine::SchemaEventClass.new(package, name, sev) - @impl.setDesc(kwargs[:desc]) if kwargs.include?(:desc) - end - end - - def add_argument(arg) - @arguments << arg - @impl.addArgument(arg.impl) - end - - def name - @impl.getClassKey.getClassName - end - - def class_key - SchemaClassKey.new(@impl.getClassKey) - end - - def package_name - @impl.getClassKey.getPackageName - end - - def class_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 - include MonitorMixin - attr_reader :impl - - def initialize(handler = nil, kwargs={}) - super() - @handler = handler - @impl = Qmfengine::Console.new - @event = Qmfengine::ConsoleEvent.new - @broker_list = [] - @cv = new_cond - @sync_count = nil - @sync_result = nil - @select = [] - @bt_count = 0 - @cb_cond = new_cond - @cb_thread = Thread.new do - run_cb_thread - end - end - - def add_connection(conn) - broker = Broker.new(self, conn) - synchronize { @broker_list << broker } - return broker - end - - def del_connection(broker) - broker.shutdown - synchronize { @broker_list.delete(broker) } - end - - def packages() - plist = [] - count = @impl.packageCount - for i in 0...count - plist << @impl.getPackageName(i) - end - return plist - end - - def 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(nil, nil, :impl => @impl.getObjectClass(key)) - elsif kind == CLASS_EVENT - clist << SchemaEventClass.new(nil, nil, nil, :impl => @impl.getEventClass(key)) - end - end - end - - return clist - end - - def bind_package(package) - @impl.bindPackage(package) - end - - def bind_class(kwargs = {}) - if kwargs.include?(:key) - @impl.bindClass(kwargs[:key]) - elsif kwargs.include?(:package) - package = kwargs[:package] - if kwargs.include?(:class) - @impl.bindClass(package, kwargs[:class]) - else - @impl.bindClass(package) - end - else - raise ArgumentError, "Invalid arguments, use :key or :package[,:class]" - end - end - - def bind_event(kwargs = {}) - if kwargs.include?(:key) - @impl.bindEvent(kwargs[:key]) - elsif kwargs.include?(:package) - package = kwargs[:package] - if kwargs.include?(:event) - @impl.bindEvent(package, kwargs[:event]) - else - @impl.bindEvent(package, "*") - end - else - raise ArgumentError, "Invalid arguments, use :key or :package[,:event]" - end - end - - def agents(broker = nil) - blist = [] - if broker - blist << broker - else - synchronize { blist = @broker_list } - end - - agents = [] - blist.each do |b| - count = b.impl.agentCount - for idx in 0...count - agents << AgentProxy.new(b.impl.getAgent(idx), b) - end - end - - return agents - end - - def objects(query, kwargs = {}) - timeout = 30 - agent = nil - kwargs.merge!(query) if query.class == Hash - - if kwargs.include?(:timeout) - timeout = kwargs[:timeout] - kwargs.delete(:timeout) - end - - if kwargs.include?(:agent) - agent = kwargs[:agent] - kwargs.delete(:agent) - end - - query = Query.new(kwargs) if query.class == Hash - - @select = [] - kwargs.each do |k,v| - @select << [k, v] if k.is_a?(String) - end - - synchronize do - @sync_count = 1 - @sync_result = [] - broker = nil - synchronize { broker = @broker_list[0] } - broker.send_query(query.impl, nil, agent) - unless @cv.wait(timeout) { @sync_count == 0 } - raise "Timed out waiting for response" - end - - return @sync_result - end - end - - # Return one and only one object or nil. - def object(query, kwargs = {}) - objs = objects(query, kwargs) - return objs.length == 1 ? objs[0] : nil - end - - # Return the first of potentially many objects. - def first_object(query, kwargs = {}) - objs = objects(query, kwargs) - return objs.length > 0 ? objs[0] : nil - end - - # Check the object against select to check for a match - def select_match(object) - @select.each do |key, value| - object.properties.each do |prop, propval| - if key == prop.name && value != propval - return nil - end - end - end - return :true - end - - def _get_result(list, context) - synchronize do - list.each do |item| - @sync_result << item if select_match(item) - end - @sync_count -= 1 - @cv.signal - end - end - - def start_sync(query) - end - - def touch_sync(sync) - end - - def end_sync(sync) - end - - def run_cb_thread - while :true - synchronize { @cb_cond.wait(1) } - begin - count = do_console_events - end until count == 0 - end - end - - def start_console_events - synchronize { @cb_cond.signal } - end - - def do_console_events - count = 0 - valid = @impl.getEvent(@event) - while valid - count += 1 - begin - case @event.kind - when Qmfengine::ConsoleEvent::AGENT_ADDED - @handler.agent_added(AgentProxy.new(@event.agent, nil)) if @handler - when Qmfengine::ConsoleEvent::AGENT_DELETED - @handler.agent_deleted(AgentProxy.new(@event.agent, nil)) if @handler - when Qmfengine::ConsoleEvent::NEW_PACKAGE - @handler.new_package(@event.name) if @handler - when Qmfengine::ConsoleEvent::NEW_CLASS - @handler.new_class(SchemaClassKey.new(@event.classKey)) if @handler - when Qmfengine::ConsoleEvent::OBJECT_UPDATE - @handler.object_update(ConsoleObject.new(nil, :impl => @event.object), @event.hasProps, @event.hasStats) if @handler - when Qmfengine::ConsoleEvent::EVENT_RECEIVED - @handler.event_received(QmfEvent.new(nil, :impl => @event.event)) if @handler - when Qmfengine::ConsoleEvent::AGENT_HEARTBEAT - @handler.agent_heartbeat(AgentProxy.new(@event.agent, nil), @event.timestamp) if @handler - when Qmfengine::ConsoleEvent::METHOD_RESPONSE - end - rescue Exception => ex - if @bt_count < 2 - @bt_count += 1 - end - end - @impl.popEvent - valid = @impl.getEvent(@event) - end - return count - end - end - - class AgentProxy - attr_reader :impl, :broker, :label, :key - - def initialize(impl, broker) - @impl = Qmfengine::AgentProxy.new(impl) - @broker = broker - @label = @impl.getLabel - @key = "#{@impl.getBrokerBank}.#{@impl.getAgentBank}" - end - end - - class Broker < ConnectionHandler - include MonitorMixin - attr_reader :impl, :conn, :console, :broker_bank - - def initialize(console, conn) - super() - @broker_bank = 1 - @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) - @operational = :true - end - - def shutdown() - @console.impl.delConnection(@impl) - @conn.del_conn_handler(self) - @operational = :false - end - - def wait_for_stable(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 send_query(query, ctx, agent) - agent_impl = agent.impl if agent - @impl.sendQuery(query, ctx, agent_impl) - @conn.kick - end - - def do_broker_events() - count = 0 - valid = @impl.getEvent(@event) - while valid - count += 1 - 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 - when Qmfengine::BrokerEvent::QUERY_COMPLETE - result = [] - for idx in 0...@event.queryResponse.getObjectCount - result << ConsoleObject.new(nil, :impl => @event.queryResponse.getObject(idx), :broker => self) - end - @console._get_result(result, @event.context) - when Qmfengine::BrokerEvent::METHOD_RESPONSE - obj = @event.context - obj._method_result(MethodResponse.new(@event.methodResponse)) - end - @impl.popEvent - valid = @impl.getEvent(@event) - end - return count - end - - 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 - @console.start_console_events - bcnt = do_broker_events - mcnt = do_broker_messages - end until bcnt == 0 and mcnt == 0 - end - - def conn_event_connected() - @session = Session.new(@conn, "qmfc-%s.%d" % [Socket.gethostname, Process::pid], self) - @impl.sessionOpened(@session.handle) - do_events - end - - def conn_event_disconnected(error) - - end - - def conn_event_visit - do_events - end - - def sess_event_session_closed(context, error) - @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::Agent.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 raise_event(event) - @impl.raiseEvent(event.impl) - 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(:impl => @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 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() - @session = Session.new(@conn, "qmfa-%s.%d" % [Socket.gethostname, Process::pid], self) - @impl.newSession - do_events - end - - def conn_event_disconnected(error) - - end - - def conn_event_visit - do_events - end - - def sess_event_session_closed(context, error) - - 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 deleted file mode 100644 index 2854aa0c7e..0000000000 --- a/qpid/cpp/bindings/qmf/ruby/ruby.i +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -%include stl.i - -%module qmfengine - -%typemap (in) void * -{ - $1 = (void *) $input; -} - -%typemap (out) void * -{ - $result = (VALUE) $1; -} - -%typemap (in) uint16_t -{ - $1 = NUM2UINT ($input); -} - -%typemap (out) uint16_t -{ - $result = UINT2NUM((uint16_t) $1); -} - -%typemap (in) uint32_t -{ - if (TYPE($input) == T_BIGNUM) - $1 = NUM2UINT($input); - else - $1 = FIX2UINT($input); -} - -%typemap (out) uint32_t -{ - $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 { - $1 = FIXNUM_P($input); -} - -%typemap (in) uint64_t -{ - if (TYPE($input) == T_BIGNUM) - $1 = NUM2ULL($input); - else - $1 = (uint64_t) FIX2ULONG($input); -} - -%typemap (out) uint64_t -{ - $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 { - $1 = FIXNUM_P($input); -} - - -%include "qmf/qmfengine.i" - diff --git a/qpid/cpp/bindings/qmf/tests/Makefile.am b/qpid/cpp/bindings/qmf/tests/Makefile.am deleted file mode 100644 index 182771e16b..0000000000 --- a/qpid/cpp/bindings/qmf/tests/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -TESTS = 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 deleted file mode 100755 index 5ee5e371d3..0000000000 --- a/qpid/cpp/bindings/qmf/tests/agent_ruby.rb +++ /dev/null @@ -1,279 +0,0 @@ -#!/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 Model - attr_reader :parent_class, :child_class, :event_class - - def initialize - @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_property(Qmf::SchemaProperty.new("sstrval", Qmf::TYPE_SSTR)) - @parent_class.add_property(Qmf::SchemaProperty.new("lstrval", Qmf::TYPE_LSTR)) - - @parent_class.add_property(Qmf::SchemaProperty.new("mapval", Qmf::TYPE_MAP)) - @parent_class.add_property(Qmf::SchemaProperty.new("listval", Qmf::TYPE_LIST)) - - @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("test_map_list", :desc => "A method call that accepts map and list arguments.") - method.add_argument(Qmf::SchemaArgument.new("inMap", Qmf::TYPE_MAP, :dir => Qmf::DIR_IN)) - method.add_argument(Qmf::SchemaArgument.new("inList", Qmf::TYPE_LIST, :dir => Qmf::DIR_IN)) - method.add_argument(Qmf::SchemaArgument.new("outMap", Qmf::TYPE_MAP, :dir => Qmf::DIR_OUT)) - method.add_argument(Qmf::SchemaArgument.new("outList", Qmf::TYPE_LIST, :dir => Qmf::DIR_OUT)) - @parent_class.add_method(method) - - method = Qmf::SchemaMethod.new("set_short_string", :desc => "Set the short string value in the object") - method.add_argument(Qmf::SchemaArgument.new("value", Qmf::TYPE_SSTR, :dir => Qmf::DIR_IN_OUT)) - @parent_class.add_method(method) - - method = Qmf::SchemaMethod.new("set_long_string", :desc => "Set the long string value in the object") - method.add_argument(Qmf::SchemaArgument.new("value", Qmf::TYPE_LSTR, :dir => Qmf::DIR_IN_OUT)) - @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") - @child_class.add_property(Qmf::SchemaProperty.new("name", Qmf::TYPE_SSTR, :index => true)) - - @event_class = Qmf::SchemaEventClass.new("org.apache.qpid.qmf", "test_event", Qmf::SEV_INFORM) - @event_class.add_argument(Qmf::SchemaArgument.new("uint32val", Qmf::TYPE_UINT32)) - @event_class.add_argument(Qmf::SchemaArgument.new("strval", Qmf::TYPE_LSTR)) - @event_class.add_argument(Qmf::SchemaArgument.new("mapval", Qmf::TYPE_MAP)) - @event_class.add_argument(Qmf::SchemaArgument.new("listval", Qmf::TYPE_LIST)) - end - - def register(agent) - agent.register_class(@parent_class) - agent.register_class(@child_class) - agent.register_class(@event_class) - end -end - - -class App < Qmf::AgentHandler - def get_query(context, query, userId) -# puts "Query: user=#{userId} context=#{context} class=#{query.class_name} object_num=#{query.object_id if query.object_id}" - 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 if object_id} args=#{args}" - - retCode = 0 - retText = "OK" - - if name == "echo" - @agent.method_response(context, 0, "OK", args) - - elsif name == "test_map_list" - # build the output map from the input map, accessing each key, - # value to ensure they are encoded/decoded - outMap = {} - args['inMap'].each do |k,v| - outMap[k] = v - end - - # same deal for the output list - outList = [] - args['inList'].each do |v| - outList << v - end - - args['outMap'] = outMap - args['outList'] = outList - - elsif name == "set_numerics" - - if args['test'] == "big" - @parent.uint64val = 0x9494949449494949 - @parent.uint32val = 0xa5a55a5a - @parent.uint16val = 0xb66b - @parent.uint8val = 0xc7 - - @parent.int64val = 1000000000000000000 - @parent.int32val = 1000000000 - @parent.int16val = 10000 - @parent.int8val = 100 - - event = Qmf::QmfEvent.new(@model.event_class) - event.uint32val = @parent.uint32val - event.strval = "Unused" - event.mapval = @parent.mapval - event.listval = @parent.listval - @agent.raise_event(event) - - elsif args['test'] == "small" - @parent.uint64val = 4 - @parent.uint32val = 5 - @parent.uint16val = 6 - @parent.uint8val = 7 - - @parent.int64val = 8 - @parent.int32val = 9 - @parent.int16val = 10 - @parent.int8val = 11 - - event = Qmf::QmfEvent.new(@model.event_class) - event.uint32val = @parent.uint32val - event.strval = "Unused" - @agent.raise_event(event) - - elsif args['test'] == "negative" - @parent.uint64val = 0 - @parent.uint32val = 0 - @parent.uint16val = 0 - @parent.uint8val = 0 - - @parent.int64val = -10000000000 - @parent.int32val = -100000 - @parent.int16val = -1000 - @parent.int8val = -100 - - event = Qmf::QmfEvent.new(@model.event_class) - event.uint32val = @parent.uint32val - event.strval = "Unused" - @agent.raise_event(event) - - else - retCode = 1 - retText = "Invalid argument value for test" - end - - elsif name == "set_short_string" - @parent.sstrval = args['value'] - - event = Qmf::QmfEvent.new(@model.event_class) - event.uint32val = 0 - event.strval = @parent.sstrval - @agent.raise_event(event) - - elsif name == "set_long_string" - @parent.lstrval = args['value'] - - event = Qmf::QmfEvent.new(@model.event_class) - event.uint32val = 0 - event.strval = @parent.lstrval - @agent.raise_event(event) - - elsif name == "create_child" - oid = @agent.alloc_object_id(2) - args['child_ref'] = oid - @child = Qmf::AgentObject.new(@model.child_class) - @child.name = args.by_key("child_name") - @child.set_object_id(oid) - - elsif name == "probe_userid" - args['userid'] = userId - - else - retCode = 1 - retText = "Unimplemented Method: #{name}" - end - - @agent.method_response(context, retCode, retText, args) - end - - 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) - @agent = Qmf::Agent.new(self, "agent_test_label") - - @model = Model.new - @model.register(@agent) - - @agent.set_connection(@connection) - - @parent = Qmf::AgentObject.new(@model.parent_class) - @parent.name = "Parent One" - @parent.state = "OPERATIONAL" - - @parent.uint64val = 0 - @parent.uint32val = 0 - @parent.uint16val = 0 - @parent.uint8val = 0 - - @parent.int64val = 0 - @parent.int32val = 0 - @parent.int16val = 0 - @parent.int8val = 0 - - # a list containing a list that contains a map (so there!) - @parent.listval = ['a', 1, 'b', -2, - ['c', true, 3.1415, - {"hi" => 10, "lo" => 5, "neg" => -3}]] - - # a default map - @parent.mapval = {'aLong' => 9999999999, - 'aInt' => 54321, - 'aSigned' => -666, - 'aString' => "A String", - 'aFloat'=> 3.1415, - 'aMap' => {"first" => 1, "second" => 2}, - 'aList' => ['x', -1, 'y', 2]} - - @parent_oid = @agent.alloc_object_id(1) - @parent.set_object_id(@parent_oid) - - sleep - end -end - -app = App.new -app.main - - diff --git a/qpid/cpp/bindings/qmf/tests/python_agent.py b/qpid/cpp/bindings/qmf/tests/python_agent.py deleted file mode 100644 index 28ba47e1bb..0000000000 --- a/qpid/cpp/bindings/qmf/tests/python_agent.py +++ /dev/null @@ -1,326 +0,0 @@ -#!/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() - diff --git a/qpid/cpp/bindings/qmf/tests/python_console.py b/qpid/cpp/bindings/qmf/tests/python_console.py deleted file mode 100755 index 1cef824fb5..0000000000 --- a/qpid/cpp/bindings/qmf/tests/python_console.py +++ /dev/null @@ -1,311 +0,0 @@ -#!/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 sys -from qpid.testlib import TestBase010 -from qpid.datatypes import Message -from qpid.queue import Empty -from time import sleep -import qmf.console - -class QmfInteropTests(TestBase010): - - def test_A_agent_presence(self): - self.startQmf(); - qmf = self.qmf - - agents = [] - count = 0 - while len(agents) == 0: - agents = qmf.getObjects(_class="agent") - sleep(1) - count += 1 - if count > 10: - self.fail("Timed out waiting for remote agent") - - def test_B_basic_method_invocation(self): - self.startQmf(); - qmf = self.qmf - - parents = qmf.getObjects(_class="parent") - self.assertEqual(len(parents), 1) - parent = parents[0] - for seq in range(10): - result = parent.echo(seq, _timeout=5) - 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 disabled_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 test_D_get_by_object_id(self): - self.startQmf() - qmf = self.qmf - - parents = qmf.getObjects(_class="parent") - self.assertEqual(len(parents), 1) - parent = parents[0] - - newList = qmf.getObjects(_objectId=parent.getObjectId()) - self.assertEqual(len(newList), 1) - - def test_E_filter_by_object_id(self): - self.startQmf() - qmf = self.qmf - - list = qmf.getObjects(_class="exchange", name="qpid.management") - self.assertEqual(len(list), 1, "No Management Exchange") - mgmt_exchange = list[0] - - bindings = qmf.getObjects(_class="binding", exchangeRef=mgmt_exchange.getObjectId()) - if len(bindings) == 0: - self.fail("No bindings found on management exchange") - - for binding in bindings: - self.assertEqual(binding.exchangeRef, mgmt_exchange.getObjectId()) - - def test_F_events(self): - class Handler(qmf.console.Console): - def __init__(self): - self.queue = [] - - def event(self, broker, event): - if event.getClassKey().getClassName() == "test_event": - self.queue.append(event) - - handler = Handler() - self.startQmf(handler) - - parents = self.qmf.getObjects(_class="parent") - self.assertEqual(len(parents), 1) - parent = parents[0] - - parent.set_numerics("big") - parent.set_numerics("small") - parent.set_numerics("negative") - parent.set_short_string("TEST") - parent.set_long_string("LONG_TEST") - parent.probe_userid() - - queue = handler.queue - self.assertEqual(len(queue), 5) - self.assertEqual(queue[0].arguments["uint32val"], 0xA5A55A5A) - self.assertEqual(queue[0].arguments["strval"], "Unused") - - # verify map and list event content. - # see agent for structure of listval and mapval - listval = queue[0].arguments["listval"] - self.assertTrue(isinstance(listval, list)) - self.assertEqual(len(listval), 5) - self.assertTrue(isinstance(listval[4], list)) - self.assertEqual(len(listval[4]), 4) - self.assertTrue(isinstance(listval[4][3], dict)) - self.assertEqual(listval[4][3]["hi"], 10) - self.assertEqual(listval[4][3]["lo"], 5) - self.assertEqual(listval[4][3]["neg"], -3) - - mapval = queue[0].arguments["mapval"] - self.assertTrue(isinstance(mapval, dict)) - self.assertEqual(len(mapval), 7) - self.assertEqual(mapval['aLong'], 9999999999) - self.assertEqual(mapval['aInt'], 54321) - self.assertEqual(mapval['aSigned'], -666) - self.assertEqual(mapval['aString'], "A String"), - self.assertEqual(mapval['aFloat'], 3.1415), - self.assertTrue(isinstance(mapval['aMap'], dict)) - self.assertEqual(len(mapval['aMap']), 2) - self.assertEqual(mapval['aMap']['second'], 2) - self.assertTrue(isinstance(mapval['aList'], list)) - self.assertEqual(len(mapval['aList']), 4) - self.assertEqual(mapval['aList'][1], -1) - - self.assertEqual(queue[1].arguments["uint32val"], 5) - self.assertEqual(queue[1].arguments["strval"], "Unused") - self.assertEqual(queue[2].arguments["uint32val"], 0) - self.assertEqual(queue[2].arguments["strval"], "Unused") - self.assertEqual(queue[3].arguments["uint32val"], 0) - self.assertEqual(queue[3].arguments["strval"], "TEST") - self.assertEqual(queue[4].arguments["uint32val"], 0) - self.assertEqual(queue[4].arguments["strval"], "LONG_TEST") - - - - def test_G_basic_map_list_data(self): - self.startQmf(); - qmf = self.qmf - - parents = qmf.getObjects(_class="parent") - self.assertEqual(len(parents), 1) - parent = parents[0] - - # see agent for structure of listval - - self.assertTrue(isinstance(parent.listval, list)) - self.assertEqual(len(parent.listval), 5) - self.assertTrue(isinstance(parent.listval[4], list)) - self.assertEqual(len(parent.listval[4]), 4) - self.assertTrue(isinstance(parent.listval[4][3], dict)) - self.assertEqual(parent.listval[4][3]["hi"], 10) - self.assertEqual(parent.listval[4][3]["lo"], 5) - self.assertEqual(parent.listval[4][3]["neg"], -3) - - # see agent for structure of mapval - - self.assertTrue(isinstance(parent.mapval, dict)) - self.assertEqual(len(parent.mapval), 7) - self.assertEqual(parent.mapval['aLong'], 9999999999) - self.assertEqual(parent.mapval['aInt'], 54321) - self.assertEqual(parent.mapval['aSigned'], -666) - self.assertEqual(parent.mapval['aString'], "A String"), - self.assertEqual(parent.mapval['aFloat'], 3.1415), - self.assertTrue(isinstance(parent.mapval['aMap'], dict)) - self.assertEqual(len(parent.mapval['aMap']), 2) - self.assertEqual(parent.mapval['aMap']['second'], 2) - self.assertTrue(isinstance(parent.mapval['aList'], list)) - self.assertEqual(len(parent.mapval['aList']), 4) - self.assertEqual(parent.mapval['aList'][1], -1) - - def test_H_map_list_method_call(self): - self.startQmf(); - qmf = self.qmf - - parents = qmf.getObjects(_class="parent") - self.assertEqual(len(parents), 1) - parent = parents[0] - - inMap = {'aLong' : long(9999999999), - 'aInt' : int(54321), - 'aSigned' : -666, - 'aString' : "A String", - 'aFloat' : 3.1415, - 'aList' : ['x', -1, 'y', 2], - 'abool' : False} - inList = ['aString', long(1), -1, 2.7182, {'aMap': -8}, True] - - result = parent.test_map_list(inMap, inList) - self.assertEqual(result.status, 0) - self.assertEqual(result.text, "OK") - - # verify returned values - self.assertEqual(len(inMap), len(result.outArgs['outMap'])) - for key,value in result.outArgs['outMap'].items(): - self.assertEqual(inMap[key], value) - - self.assertEqual(len(inList), len(result.outArgs['outList'])) - for idx in range(len(inList)): - self.assertEqual(inList[idx], result.outArgs['outList'][idx]) - - - def getProperty(self, msg, name): - for h in msg.headers: - if hasattr(h, name): return getattr(h, name) - return None - - def getAppHeader(self, msg, name): - headers = self.getProperty(msg, "application_headers") - if headers: - return headers[name] - return None diff --git a/qpid/cpp/bindings/qmf/tests/ruby_console.rb b/qpid/cpp/bindings/qmf/tests/ruby_console.rb deleted file mode 100755 index 31670312d6..0000000000 --- a/qpid/cpp/bindings/qmf/tests/ruby_console.rb +++ /dev/null @@ -1,174 +0,0 @@ -#!/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 agent_added(agent) - puts "AgentAdded: label=#{agent.label} key=#{agent.key}" - end - - def agent_deleted(agent) - puts "AgentDeleted: #{agent.label}" - end - - def new_package(package) - puts "NewPackage: #{package}" - end - - def new_class(class_key) - puts "NewClass: #{class_key}" - end - - def object_update(object, hasProps, hasStats) - puts "ObjectUpdate: #{object.object_class.class_name} props=#{hasProps} stats=#{hasStats}" - puts " agent-key=#{object.object_id.agent_key}" - puts " package=#{object.object_class.package_name}" - end - - def event_received(event); end - - def agent_heartbeat(agent, timestamp) - puts "AgentHeartbeat: #{agent.label} time=#{timestamp/1000000000}" - end - - def method_response(resp); end - def broker_info(broker); end - - - def dump_schema - packages = @qmfc.packages - puts "----- Packages -----" - packages.each do |p| - puts p - puts " ----- Object Classes -----" - classes = @qmfc.classes(p) - classes.each do |c| - puts " #{c.name}" - - puts " ---- Properties ----" - props = c.properties - props.each do |prop| - puts " #{prop.name}" - end - - puts " ---- Statistics ----" - stats = c.statistics - stats.each do |stat| - puts " #{stat.name}" - end - - puts " ---- Methods ----" - methods = c.methods - methods.each do |method| - puts " #{method.name}" - puts " ---- Args ----" - args = method.arguments - args.each do |arg| - puts " #{arg.name}" - end - end - end - - puts " ----- Event Classes -----" - classes = @qmfc.classes(p, Qmf::CLASS_EVENT) - classes.each do |c| - puts " #{c.name}" - puts " ---- Args ----" - args = c.arguments - args.each do |arg| - puts " #{arg.name}" - end - end - end - puts "-----" - 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 - @connection = Qmf::Connection.new(@settings) - @qmfc = Qmf::Console.new(self) - - @broker = @qmfc.add_connection(@connection) - @broker.wait_for_stable - - ##dump_schema - - agents = @qmfc.agents() - puts "---- Agents ----" - agents.each do |a| - puts " => #{a.label}" - end - puts "----" - - for idx in 0...20 - blist = @qmfc.objects(Qmf::Query.new(:class => "broker")) - puts "---- Brokers ----" - blist.each do |b| - puts " ---- Broker ----" - puts " systemRef: #{b.systemRef}" - puts " port : #{b.port}" - puts " uptime : #{b.uptime / 1000000000}" - puts " properties : #{b.properties}" - puts " statistics : #{b.statistics}" - - for rep in 0...1 - puts " Pinging..." - ret = b.echo(45, 'text string') - puts " status=#{ret.status} text=#{ret.exception.asString} seq=#{ret.args.sequence} body=#{ret.args.body}" - end - end - puts "----" - - elist = @qmfc.objects(:package => "org.apache.qpid.broker", :class => "exchange", 'durable' => true) - puts "---- Durable Exchanges ----" - elist.each do |e| - puts "Exchange: #{e.name}" - end - puts "----" - - qlist = @qmfc.objects(Qmf::Query.new(:package => "org.apache.qpid.broker", - :class => "queue")) - puts "---- Queues ----" - qlist.each do |q| - puts " ---- Queue ----" - puts " name : #{q.name}" - end - puts "----" - sleep(5) - end - - sleep(5) - puts "Deleting connection..." - @qmfc.del_connection(@broker) - puts " done" - sleep - end -end - -app = App.new -app.main - - diff --git a/qpid/cpp/bindings/qmf/tests/ruby_console_test.rb b/qpid/cpp/bindings/qmf/tests/ruby_console_test.rb deleted file mode 100755 index 972d5977b8..0000000000 --- a/qpid/cpp/bindings/qmf/tests/ruby_console_test.rb +++ /dev/null @@ -1,397 +0,0 @@ -#!/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 'test_base' - -class ConsoleTest < ConsoleTestBase - - def test_A_agent_presence - assert(@connection.connected?, "Connection not connected") - - agents = [] - count = 0 - while agents.size == 0 - agents = @qmfc.objects(Qmf::Query.new(:class => "agent")) - sleep(1) - count += 1 - fail("Timed out waiting for remote agent") if count > 10 - end - - agentList = @qmfc.agents - assert_equal(agentList.size, 2, "Number of agents reported by Console") - end - - def test_A_connection_settings - begin - @settings.bogusAttribute = 25 - fail("Connection settings accepted bogus attribute") - rescue - end - end - - def test_B_basic_method_invocation - parent = @qmfc.object(:class => "parent") - assert(parent, "Number of 'parent' objects") - for seq in 0...10 - result = parent.echo(seq) - assert_equal(result.status, 0, "Method Response Status") - assert_equal(result.text, "OK", "Method Response Text") - assert_equal(result.args.sequence, seq, "Echo Response Sequence") - end - - result = parent.set_numerics("bogus") - assert_equal(result.status, 1) - assert_equal(result.text, "Invalid argument value for test") - end - - def test_C_basic_types_numeric_big - parent = @qmfc.object(:class =>"parent") - assert(parent, "Number of parent objects") - - result = parent.set_numerics("big") - assert_equal(result.status, 0, "Method Response Status") - assert_equal(result.text, "OK", "Method Response Text") - - parent.update - - assert_equal(parent.uint64val, 0x9494949449494949) - assert_equal(parent.uint32val, 0xA5A55A5A) - assert_equal(parent.uint16val, 0xB66B) - assert_equal(parent.uint8val, 0xC7) - - assert_equal(parent.int64val, 1000000000000000000) - assert_equal(parent.int32val, 1000000000) - assert_equal(parent.int16val, 10000) - assert_equal(parent.int8val, 100) - end - - def test_C_basic_types_numeric_small - parent = @qmfc.object(:class =>"parent") - assert(parent, "Number of parent objects") - - result = parent.set_numerics("small") - assert_equal(result.status, 0, "Method Response Status") - assert_equal(result.text, "OK", "Method Response Text") - - parent.update - - assert_equal(parent.uint64val, 4) - assert_equal(parent.uint32val, 5) - assert_equal(parent.uint16val, 6) - assert_equal(parent.uint8val, 7) - - assert_equal(parent.int64val, 8) - assert_equal(parent.int32val, 9) - assert_equal(parent.int16val, 10) - assert_equal(parent.int8val, 11) - end - - def test_C_basic_types_numeric_negative - parent = @qmfc.object(:class =>"parent") - assert(parent, "Number of parent objects") - - result = parent.set_numerics("negative") - assert_equal(result.status, 0, "Method Response Status") - assert_equal(result.text, "OK", "Method Response Text") - - parent.update - - assert_equal(parent.uint64val, 0) - assert_equal(parent.uint32val, 0) - assert_equal(parent.uint16val, 0) - assert_equal(parent.uint8val, 0) - - assert_equal(parent.int64val, -10000000000) - assert_equal(parent.int32val, -100000) - assert_equal(parent.int16val, -1000) - assert_equal(parent.int8val, -100) - end - - def test_C_basic_types_string_short - parent = @qmfc.object(:class =>"parent") - assert(parent, "Number of parent objects") - - strings = [] - strings << "" - strings << "A" - strings << "BC" - strings << "DEF" - strings << "GHIJKLMNOPQRSTUVWXYZ" - big = "a" - for i in 0...254 - big << "X" - end - strings << big - - strings.each do |str| - result = parent.set_short_string(str) - assert_equal(result.status, 0, "Method Response Status") - compare = str - compare = compare[0..254] if compare.size > 255 - assert_equal(result.args.value, compare, "Value returned by method") - parent.update - assert_equal(parent.sstrval, compare, "Value stored in the object") - end - end - - def test_C_basic_types_string_long - parent = @qmfc.object(:class =>"parent") - assert(parent, "Number of parent objects") - - strings = [] - strings << "" - strings << "A" - strings << "BC" - strings << "DEF" - strings << "GHIJKLMNOPQRSTUVWXYZ" - big = "a" - for i in 0...270 - big << "X" - end - strings << big - - strings.each do |str| - result = parent.set_long_string(str) - assert_equal(result.status, 0, "Method Response Status") - assert_equal(result.args.value, str, "Value returned by method") - parent.update - assert_equal(parent.lstrval, str, "Value stored in the object") - end - end - - def test_D_userid_for_method - parent = @qmfc.object(:class => "parent") - assert(parent, "Number of parent objects") - - result = parent.probe_userid - assert_equal(result.status, 0, "Method Response Status") - assert_equal(result.args.userid, "anonymous") - end - - def test_D_get_by_object_id - parent = @qmfc.object(:class => "parent") - assert(parent, "Number of parent objects") - - list = @qmfc.objects(:object_id => parent.object_id) - assert_equal(list.size, 1) - - bad_oid = Qmf::ObjectId.new - list = @qmfc.objects(:object_id => bad_oid) - assert_equal(list.size, 0) - - # TODO: test a bad_oid that has an agent-bank that is not associated with an attached agent. - - end - - def test_D_get_with_agent - agents = @qmfc.agents - agents.each do |agent| - if agent.label == "agent_test_label" - parent = @qmfc.object(:class => "parent", :agent => agent) - assert(parent, "Number of parent objects") - return - end - end - - fail("Didn't find a non-broker agent") - end - - def test_E_filter_by_object_id - mgmt_exchange = @qmfc.object(:class => "exchange", 'name' => "qpid.management") - assert(mgmt_exchange, "No Management Exchange") - - bindings = @qmfc.objects(:class => "binding", 'exchangeRef' => mgmt_exchange.object_id) - if bindings.size == 0 - fail("No bindings found on management exchange") - end - - bindings.each do |binding| - assert_equal(binding.exchangeRef, mgmt_exchange.object_id) - end - end - - - def test_F_events - - @event_list.clear - @store_events = :true - - parent = @qmfc.object(:class =>"parent") - assert(parent, "Number of parent objects") - - parent.set_numerics("big") - parent.set_numerics("small") - parent.set_numerics("negative") - parent.set_short_string("TEST") - parent.set_long_string("LONG_TEST") - parent.probe_userid() - - @store_events = :false - - assert_equal(@event_list.length, 5) - - assert_equal(@event_list[0].get_attr("uint32val"), 0xA5A55A5A) - assert_equal(@event_list[0].get_attr("strval"), "Unused") - - # verify map and list event content. - # see agent for structure of listval and mapval - - listval = @event_list[0].listval - assert(listval.class == Array) - assert_equal(listval.length, 5) - assert(listval[4].class == Array) - assert_equal(listval[4].length, 4) - assert(listval[4][3].class == Hash) - assert_equal(listval[4][3]["hi"], 10) - assert_equal(listval[4][3]["lo"], 5) - assert_equal(listval[4][3]["neg"], -3) - - mapval = @event_list[0].mapval - assert(mapval.class == Hash) - assert_equal(mapval.length, 7) - assert_equal(mapval['aLong'], 9999999999) - assert_equal(mapval['aInt'], 54321) - assert_equal(mapval['aSigned'], -666) - assert_equal(mapval['aString'], "A String") - assert_equal(mapval['aFloat'], 3.1415) - assert(mapval['aMap'].class == Hash) - assert_equal(mapval['aMap'].length, 2) - assert_equal(mapval['aMap']['second'], 2) - assert(mapval['aList'].class == Array) - assert_equal(mapval['aList'].length, 4) - assert_equal(mapval['aList'][1], -1) - - assert_equal(@event_list[1]["uint32val"], 5) - assert_equal(@event_list[1].get_attr("strval"), "Unused") - assert_equal(@event_list[2].get_attr("uint32val"), 0) - assert_equal(@event_list[2].get_attr("strval"), "Unused") - assert_equal(@event_list[3].get_attr("uint32val"), 0) - assert_equal(@event_list[3].get_attr("strval"), "TEST") - assert_equal(@event_list[4].get_attr("uint32val"), 0) - assert_equal(@event_list[4].get_attr("strval"), "LONG_TEST") - - @event_list.clear - - end - - def test_G_basic_map_list_data - parent = @qmfc.object(:class => "parent") - assert(parent, "Number of 'parent' objects") - - # see agent for structure of listval - - assert(parent.listval.class == Array) - assert_equal(parent.listval.length, 5) - assert(parent.listval[4].class == Array) - assert_equal(parent.listval[4].length, 4) - assert(parent.listval[4][3].class == Hash) - assert_equal(parent.listval[4][3]["hi"], 10) - assert_equal(parent.listval[4][3]["lo"], 5) - assert_equal(parent.listval[4][3]["neg"], -3) - - # see agent for structure of mapval - - assert(parent.mapval.class == Hash) - assert_equal(parent.mapval.length, 7) - assert_equal(parent.mapval['aLong'], 9999999999) - assert_equal(parent.mapval['aInt'], 54321) - assert_equal(parent.mapval['aSigned'], -666) - assert_equal(parent.mapval['aString'], "A String") - assert_equal(parent.mapval['aFloat'], 3.1415) - assert(parent.mapval['aMap'].class == Hash) - assert_equal(parent.mapval['aMap'].length, 2) - assert_equal(parent.mapval['aMap']['second'], 2) - assert(parent.mapval['aList'].class == Array) - assert_equal(parent.mapval['aList'].length, 4) - assert_equal(parent.mapval['aList'][1], -1) - end - - def test_H_map_list_method_call - parent = @qmfc.object(:class => "parent") - assert(parent, "Number of 'parent' objects") - - inMap = {'aLong' => 9999999999, - 'aInt' => 54321, - 'aSigned' => -666, - 'aString' => "A String", - 'aFloat' => 3.1415, - 'aList' => ['x', -1, 'y', 2], - 'abool' => false} - - inList = ['aString', 1, -1, 2.7182, {'aMap'=> -8}, true] - - result = parent.test_map_list(inMap, inList) - assert_equal(result.status, 0) - assert_equal(result.text, "OK") - - # verify returned values - assert_equal(inMap.length, result.args['outMap'].length) - result.args['outMap'].each do |k,v| - assert_equal(inMap[k], v) - end - - assert_equal(inList.length, result.args['outList'].length) - for idx in 0...inList.length - assert_equal(inList[idx], result.args['outList'][idx]) - end - end - - def test_H_map_list_method_call_big - parent = @qmfc.object(:class => "parent") - assert(parent, "Number of 'parent' objects") - - big_string = "" - segment = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - for idx in 1...1500 - big_string = big_string + segment - end - - inMap = {'aLong' => 9999999999, - 'aInt' => 54321, - 'aSigned' => -666, - 'aString' => big_string, - 'another' => big_string, - 'aFloat' => 3.1415, - 'aList' => ['x', -1, 'y', 2], - 'abool' => false} - - inList = ['aString', 1, -1, 2.7182, {'aMap'=> -8}, true] - - result = parent.test_map_list(inMap, inList) - assert_equal(result.status, 0) - assert_equal(result.text, "OK") - - # verify returned values - assert_equal(inMap.length, result.args['outMap'].length) - result.args['outMap'].each do |k,v| - assert_equal(inMap[k], v) - end - - assert_equal(inList.length, result.args['outList'].length) - for idx in 0...inList.length - assert_equal(inList[idx], result.args['outList'][idx]) - end - end - -end - -app = ConsoleTest.new - diff --git a/qpid/cpp/bindings/qmf/tests/run_interop_tests b/qpid/cpp/bindings/qmf/tests/run_interop_tests deleted file mode 100755 index c370f211af..0000000000 --- a/qpid/cpp/bindings/qmf/tests/run_interop_tests +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/sh - -# -# 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. -# - -# Run the qmf interoperability tests. -MY_DIR=`dirname \`which $0\`` -QPID_DIR=${MY_DIR}/../../../.. -BUILD_DIR=../../.. -PYTHON_DIR=${QPID_DIR}/python -TOOLS_PY_DIR=${QPID_DIR}/tools/src/py -QMF_DIR=${QPID_DIR}/extras/qmf -QMF_DIR_PY=${QMF_DIR}/src/py -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() { - ${BROKER_DIR}/qpidd --daemon --port 0 --no-data-dir --no-module-dir --auth no > _qpidd.port - BROKER_PORT=`cat _qpidd.port` -} - -stop_broker() { - ${BROKER_DIR}/qpidd -q --port $BROKER_PORT - echo "Broker stopped" -} - -start_ruby_agent() { - ruby -I${MY_DIR}/../ruby -I${RUBY_LIB_DIR} ${MY_DIR}/agent_ruby.rb localhost $BROKER_PORT & - AGENT_PID=$! -} - -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}:${QMF_DIR_PY}:${MY_DIR}:${TOOLS_PY_DIR} - export PYTHONPATH - - 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=$? - if test x$RETCODE != x0; then - echo "FAIL qmf interop tests (Ruby Agent)"; - TESTS_FAILED=1 - fi - - echo " Ruby Agent (external storage) vs. Ruby Console" - ruby -I${MY_DIR} -I${MY_DIR}/../ruby -I${RUBY_LIB_DIR} ${MY_DIR}/ruby_console_test.rb localhost $BROKER_PORT $@ - RETCODE=$? - stop_ruby_agent - if test x$RETCODE != x0; then - echo "FAIL qmf interop tests (Ruby Console/Ruby Agent)"; - TESTS_FAILED=1 - fi - - if test -d ${PYTHON_LIB_DIR} ; then - echo " Python Agent (external storage) vs. Ruby Console" - start_python_agent - ruby -I${MY_DIR} -I${MY_DIR}/../ruby -I${RUBY_LIB_DIR} ${MY_DIR}/ruby_console_test.rb localhost $BROKER_PORT $@ - RETCODE=$? - stop_python_agent - if test x$RETCODE != x0; then - echo "FAIL qmf interop tests (Ruby Console/Python Agent)"; - TESTS_FAILED=1 - fi - 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$TESTS_FAILED != x0; then - echo "TEST FAILED!" - exit 1 - fi -fi diff --git a/qpid/cpp/bindings/qmf/tests/test_base.rb b/qpid/cpp/bindings/qmf/tests/test_base.rb deleted file mode 100644 index 7d4609097c..0000000000 --- a/qpid/cpp/bindings/qmf/tests/test_base.rb +++ /dev/null @@ -1,82 +0,0 @@ -#!/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 ConsoleTestBase < Qmf::ConsoleHandler - def initialize - sleep(2) - @settings = Qmf::ConnectionSettings.new - @settings.host = ARGV[0] if ARGV.size > 0 - @settings.port = ARGV[1].to_i if ARGV.size > 1 - @connection = Qmf::Connection.new(@settings) - @qmfc = Qmf::Console.new(self) - - @broker = @qmfc.add_connection(@connection) - @broker.wait_for_stable - - @store_events = :false - @event_list = [] - - tests = [] - methods.each do |m| - name = m.to_s - tests << name if name[0..4] == "test_" - end - - failures = 0 - - tests.sort.each do |t| - begin - print "#{t}..." - $stdout.flush - send(t) - puts " Pass" - rescue - puts " Fail: #{$!}" - failures += 1 - end - end - - @qmfc.del_connection(@broker) - exit(1) if failures > 0 - end - - def assert_equal(left, right, in_text=nil) - text = " (#{in_text})" if in_text - raise "Assertion failed: #{left} != #{right}#{text}" unless left == right - end - - def assert(condition, in_text=nil) - text = " (#{in_text})" if in_text - raise "Assertion failed: #{condition} #{text}" unless condition - end - - def fail(text) - raise text - end - - def event_received(event) - @event_list << event if @store_events - end - -end diff --git a/qpid/cpp/bindings/qmf2/Makefile.am b/qpid/cpp/bindings/qmf2/Makefile.am deleted file mode 100644 index 0f50e757a2..0000000000 --- a/qpid/cpp/bindings/qmf2/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -if HAVE_SWIG - -SUBDIRS = examples/cpp - -if HAVE_RUBY_DEVEL -SUBDIRS += ruby -endif - -if HAVE_PYTHON_DEVEL -SUBDIRS += python -endif - -endif diff --git a/qpid/cpp/bindings/qmf2/examples/cpp/CMakeLists.txt b/qpid/cpp/bindings/qmf2/examples/cpp/CMakeLists.txt index 6621137ba9..0e1e00d34e 100644 --- a/qpid/cpp/bindings/qmf2/examples/cpp/CMakeLists.txt +++ b/qpid/cpp/bindings/qmf2/examples/cpp/CMakeLists.txt @@ -57,10 +57,10 @@ macro(add_example subdir example) add_executable(${subdir}_${example} ${example}.cpp) set_target_properties(${subdir}_${example} PROPERTIES OUTPUT_NAME ${example}) if (${ARGC} GREATER 2) - target_link_libraries(${subdir}_${example} ${ARGN} qpidclient + target_link_libraries(${subdir}_${example} ${ARGN} qpidmessaging qpidtypes ${_boost_libs_needed}) else (${ARGC} GREATER 2) - target_link_libraries(${subdir}_${example} qpidclient + target_link_libraries(${subdir}_${example} qpidmessaging qpidtypes ${_boost_libs_needed}) endif (${ARGC} GREATER 2) endmacro(add_example) @@ -73,22 +73,11 @@ macro(add_installed_example subdir example) install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${example}.cpp DESTINATION ${QPID_INSTALL_EXAMPLESDIR}/${subdir} COMPONENT ${QPID_COMPONENT_EXAMPLES}) - if (MSVC) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}_${example}.vcproj - DESTINATION ${QPID_INSTALL_EXAMPLESDIR}/${subdir} - COMPONENT ${QPID_COMPONENT_EXAMPLES}) - endif (MSVC) - endmacro(add_installed_example) install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.txt DESTINATION ${QPID_INSTALL_EXAMPLESDIR} COMPONENT ${QPID_COMPONENT_EXAMPLES}) -if (MSVC) - install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/examples.sln - DESTINATION ${QPID_INSTALL_EXAMPLESDIR} - COMPONENT ${QPID_COMPONENT_EXAMPLES}) -endif (MSVC) add_installed_example(qmf2 agent qmf2) if (NOT WIN32) diff --git a/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am b/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am deleted file mode 100644 index 8bf56ead91..0000000000 --- a/qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -INCLUDE = -I$(top_srcdir)/include - -AM_CPPFLAGS = $(INCLUDE) - -TYPES_LIB=$(top_builddir)/src/libqpidtypes.la -MESSAGING_LIB=$(top_builddir)/src/libqpidmessaging.la - -noinst_PROGRAMS=agent event_driven_list_agents list_agents print_events - -agent_SOURCES=agent.cpp -agent_LDADD=$(top_builddir)/src/libqmf2.la $(TYPES_LIB) $(MESSAGING_LIB) - -list_agents_SOURCES=list_agents.cpp -list_agents_LDADD=$(top_builddir)/src/libqmf2.la $(MESSAGING_LIB) - -event_driven_list_agents_SOURCES=event_driven_list_agents.cpp -event_driven_list_agents_LDADD=$(top_builddir)/src/libqmf2.la $(MESSAGING_LIB) - -print_events_SOURCES=print_events.cpp -print_events_LDADD=$(top_builddir)/src/libqmf2.la $(TYPES_LIB) $(MESSAGING_LIB) diff --git a/qpid/cpp/bindings/qmf2/python/Makefile.am b/qpid/cpp/bindings/qmf2/python/Makefile.am deleted file mode 100644 index 309e8f8dad..0000000000 --- a/qpid/cpp/bindings/qmf2/python/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -if HAVE_PYTHON_DEVEL - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/bindings -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src $(QMF_INCLUDES) - -generated_file_list = \ - cqmf2.cpp \ - cqmf2.py - -EXTRA_DIST = CMakeLists.txt python.i -BUILT_SOURCES = $(generated_file_list) -SWIG_FLAGS = -w362,401 - -$(generated_file_list): $(srcdir)/python.i - $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqmf2.cpp $(srcdir)/python.i - -pylibdir = $(pyexecdir) - -pylib_LTLIBRARIES = _cqmf2.la -cqpiddir = $(pythondir) -cqpid_PYTHON = qmf2.py cqmf2.py - -_cqmf2_la_LDFLAGS = -avoid-version -module -shared -_cqmf2_la_LIBADD = $(PYTHON_LIBS) -L$(top_builddir)/src/.libs $(top_builddir)/src/libqmf2.la -_cqmf2_la_CXXFLAGS = $(INCLUDES) -I$(srcdir)/qmf $(PYTHON_CFLAGS) -fno-strict-aliasing -nodist__cqmf2_la_SOURCES = cqmf2.cpp - -CLEANFILES = $(generated_file_list) - -endif # HAVE_PYTHON_DEVEL - diff --git a/qpid/cpp/bindings/qmf2/ruby/Makefile.am b/qpid/cpp/bindings/qmf2/ruby/Makefile.am deleted file mode 100644 index 9952edb972..0000000000 --- a/qpid/cpp/bindings/qmf2/ruby/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -if HAVE_RUBY_DEVEL - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/bindings -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src $(QMF_INCLUDES) - -EXTRA_DIST = CMakeLists.txt ruby.i -BUILT_SOURCES = cqmf2.cpp -SWIG_FLAGS = -w362,401 - -rubylibdir = $(RUBY_LIB) - -cqmf2.cpp: $(srcdir)/ruby.i - $(SWIG) -ruby -c++ $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqmf2.cpp $(srcdir)/ruby.i - -rubylibarchdir = $(RUBY_LIB_ARCH) -rubylibarch_LTLIBRARIES = cqmf2.la -dist_rubylib_DATA = qmf2.rb - -cqmf2_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)" -cqmf2_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqmf2 $(top_builddir)/src/libqmf2.la -cqmf2_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing -nodist_cqmf2_la_SOURCES = cqmf2.cpp - -CLEANFILES = cqmf2.cpp - -endif # HAVE_RUBY_DEVEL diff --git a/qpid/cpp/bindings/qpid/Makefile.am b/qpid/cpp/bindings/qpid/Makefile.am deleted file mode 100644 index 5f47ee9b0a..0000000000 --- a/qpid/cpp/bindings/qpid/Makefile.am +++ /dev/null @@ -1,79 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -SUBDIRS = dotnet - -if HAVE_SWIG - -if HAVE_RUBY_DEVEL -SUBDIRS += ruby -endif - -if HAVE_PYTHON_DEVEL -SUBDIRS += python -endif - -if HAVE_PERL_DEVEL - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/bindings -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src -I$(PERL_INC) - -EXTRA_DIST = perl/perl.i perl/CMakeLists.txt perl/Makefile.PL perl/lib/qpid.pm perl/lib -BUILT_SOURCES = perl/cqpid_perl.cpp -SWIG_FLAGS = -w362,401 - -perl/cqpid_perl.cpp: $(srcdir)/perl/perl.i - mkdir -p perl - $(SWIG) -perl -c++ $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o perl/cqpid_perl.cpp $(srcdir)/perl/perl.i - -perl/Makefile: perl/cqpid_perl.cpp - mkdir -p perl - cd perl; \ - $(PERL) Makefile.PL PREFIX=$(prefix) ; \ - cd .. - -all-local: perl/Makefile - cd perl; \ - $(MAKE) OPTIMIZE="$(CXXFLAGS)" ; \ - cd .. - -install-exec-local: - cd perl ; \ - $(MAKE) pure_install ; \ - cd .. - -clean-local: - cd perl ; \ - $(MAKE) clean ; \ - cd .. - -distclean-local: - cd perl ; \ - $(MAKE) distclean ; \ - cd .. - -maintainer-clean-local: - cd perl ; \ - $(PERL) maintainer-clean ; \ - cd .. - -CLEANFILES = perl/cqpid_perl.cpp perl/Makefile.old perl/cqpid_perl.pm - -endif - -endif diff --git a/qpid/cpp/bindings/qpid/dotnet/Makefile.am b/qpid/cpp/bindings/qpid/dotnet/Makefile.am deleted file mode 100644 index 82ae315578..0000000000 --- a/qpid/cpp/bindings/qpid/dotnet/Makefile.am +++ /dev/null @@ -1,159 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -EXTRA_DIST = configure-windows.ps1 \ - examples/csharp.direct.receiver/csharp.direct.receiver.cs \ - examples/csharp.direct.receiver/Properties/AssemblyInfo.cs \ - examples/csharp.direct.sender/csharp.direct.sender.cs \ - examples/csharp.direct.sender/Properties/AssemblyInfo.cs \ - examples/csharp.example.client/csharp.example.client.cs \ - examples/csharp.example.client/Properties/AssemblyInfo.cs \ - examples/csharp.example.declare_queues/csharp.example.declare_queues.cs \ - examples/csharp.example.declare_queues/Properties/AssemblyInfo.cs \ - examples/csharp.example.drain/csharp.example.drain.cs \ - examples/csharp.example.drain/Options.cs \ - examples/csharp.example.drain/Properties/AssemblyInfo.cs \ - examples/csharp.example.helloworld/csharp.example.helloworld.cs \ - examples/csharp.example.helloworld/Properties/AssemblyInfo.cs \ - examples/csharp.example.server/csharp.example.server.cs \ - examples/csharp.example.server/Properties/AssemblyInfo.cs \ - examples/csharp.example.spout/csharp.example.spout.cs \ - examples/csharp.example.spout/Options.cs \ - examples/csharp.example.spout/Properties/AssemblyInfo.cs \ - examples/csharp.map.callback.receiver/csharp.map.callback.receiver.cs \ - examples/csharp.map.callback.receiver/Properties/AssemblyInfo.cs \ - examples/csharp.map.callback.sender/csharp.map.callback.sender.cs \ - examples/csharp.map.callback.sender/Properties/AssemblyInfo.cs \ - examples/csharp.map.receiver/csharp.map.receiver.cs \ - examples/csharp.map.receiver/Properties/AssemblyInfo.cs \ - examples/csharp.map.sender/csharp.map.sender.cs \ - examples/csharp.map.sender/Properties/AssemblyInfo.cs \ - examples/msvc10/csharp.direct.receiver/app.config \ - examples/msvc10/csharp.direct.receiver/csharp.direct.receiver.csproj \ - examples/msvc10/csharp.direct.sender/app.config \ - examples/msvc10/csharp.direct.sender/csharp.direct.sender.csproj \ - examples/msvc10/csharp.example.client/app.config \ - examples/msvc10/csharp.example.client/csharp.example.client.csproj \ - examples/msvc10/csharp.example.declare_queues/app.config \ - examples/msvc10/csharp.example.declare_queues/csharp.example.declare_queues.csproj \ - examples/msvc10/csharp.example.drain/app.config \ - examples/msvc10/csharp.example.drain/csharp.example.drain.csproj \ - examples/msvc10/csharp.example.helloworld/app.config \ - examples/msvc10/csharp.example.helloworld/csharp.example.helloworld.csproj \ - examples/msvc10/csharp.example.server/app.config \ - examples/msvc10/csharp.example.server/csharp.example.server.csproj \ - examples/msvc10/csharp.example.spout/app.config \ - examples/msvc10/csharp.example.spout/csharp.example.spout.csproj \ - examples/msvc10/csharp.map.callback.receiver/app.config \ - examples/msvc10/csharp.map.callback.receiver/csharp.map.callback.receiver.csproj \ - examples/msvc10/csharp.map.callback.sender/app.config \ - examples/msvc10/csharp.map.callback.sender/csharp.map.callback.sender.csproj \ - examples/msvc10/csharp.map.receiver/app.config \ - examples/msvc10/csharp.map.receiver/csharp.map.receiver.csproj \ - examples/msvc10/csharp.map.sender/app.config \ - examples/msvc10/csharp.map.sender/csharp.map.sender.csproj \ - examples/msvc9/csharp.direct.receiver/csharp.direct.receiver.csproj \ - examples/msvc9/csharp.direct.sender/csharp.direct.sender.csproj \ - examples/msvc9/csharp.example.client/csharp.example.client.csproj \ - examples/msvc9/csharp.example.declare_queues/csharp.example.declare_queues.csproj \ - examples/msvc9/csharp.example.drain/csharp.example.drain.csproj \ - examples/msvc9/csharp.example.helloworld/csharp.example.helloworld.csproj \ - examples/msvc9/csharp.example.server/csharp.example.server.csproj \ - examples/msvc9/csharp.example.spout/csharp.example.spout.csproj \ - examples/msvc9/csharp.map.callback.receiver/csharp.map.callback.receiver.csproj \ - examples/msvc9/csharp.map.callback.sender/csharp.map.callback.sender.csproj \ - examples/msvc9/csharp.map.receiver/csharp.map.receiver.csproj \ - examples/msvc9/csharp.map.sender/csharp.map.sender.csproj \ - Makefile.am \ - msvc10/org.apache.qpid.messaging.sessionreceiver.sln \ - msvc10/org.apache.qpid.messaging.sln \ - msvc9/org.apache.qpid.messaging.sessionreceiver.sln \ - msvc9/org.apache.qpid.messaging.sln \ - ReadMe.txt \ - src/Address.cpp \ - src/Address.h \ - src/app.rc \ - src/AssemblyInfo.cpp \ - src/Connection.cpp \ - src/Connection.h \ - src/Duration.h \ - src/FailoverUpdates.cpp \ - src/FailoverUpdates.h \ - src/Message.cpp \ - src/Message.h \ - src/msvc10/org.apache.qpid.messaging.vcxproj \ - src/msvc10/org.apache.qpid.messaging.vcxproj.filters \ - src/msvc9/org.apache.qpid.messaging.vcproj \ - src/org.apache.qpid.messaging.template.rc \ - src/qpid.snk \ - src/QpidException.h \ - src/QpidMarshal.h \ - src/QpidTypeCheck.h \ - src/ReadMe.txt \ - src/Receiver.cpp \ - src/Receiver.h \ - src/resource1.h \ - src/Sender.cpp \ - src/Sender.h \ - src/Session.cpp \ - src/Session.h \ - src/sessionreceiver/msvc10/org.apache.qpid.messaging.sessionreceiver.csproj \ - src/sessionreceiver/msvc9/org.apache.qpid.messaging.sessionreceiver.csproj \ - src/sessionreceiver/Properties/sessionreceiver-AssemblyInfo-template.cs \ - src/sessionreceiver/qpid.snk \ - src/sessionreceiver/sessionreceiver.cs \ - src/TypeTranslator.cpp \ - src/TypeTranslator.h \ - test/messaging.test/messaging.test.address.cs \ - test/messaging.test/messaging.test.connection.cs \ - test/messaging.test/messaging.test.cs \ - test/messaging.test/messaging.test.duration.cs \ - test/messaging.test/messaging.test.message.cs \ - test/messaging.test/msvc10/messaging.test.csproj \ - test/messaging.test/msvc9/messaging.test.csproj \ - test/messaging.test/Properties/AssemblyInfo.cs \ - winsdk_sources/msvc10/examples/csharp.direct.receiver/csharp.direct.receiver.csproj \ - winsdk_sources/msvc10/examples/csharp.direct.sender/csharp.direct.sender.csproj \ - winsdk_sources/msvc10/examples/csharp.example.client/csharp.example.client.csproj \ - winsdk_sources/msvc10/examples/csharp.example.declare_queues/csharp.example.declare_queues.csproj \ - winsdk_sources/msvc10/examples/csharp.example.drain/csharp.example.drain.csproj \ - winsdk_sources/msvc10/examples/csharp.example.helloworld/csharp.example.helloworld.csproj \ - winsdk_sources/msvc10/examples/csharp.example.server/csharp.example.server.csproj \ - winsdk_sources/msvc10/examples/csharp.example.spout/csharp.example.spout.csproj \ - winsdk_sources/msvc10/examples/csharp.map.callback.receiver/csharp.map.callback.receiver.csproj \ - winsdk_sources/msvc10/examples/csharp.map.callback.sender/csharp.map.callback.sender.csproj \ - winsdk_sources/msvc10/examples/csharp.map.receiver/csharp.map.receiver.csproj \ - winsdk_sources/msvc10/examples/csharp.map.sender/csharp.map.sender.csproj \ - winsdk_sources/msvc10/winsdk_dotnet_examples.sln \ - winsdk_sources/msvc9/examples/csharp.direct.receiver/csharp.direct.receiver.csproj \ - winsdk_sources/msvc9/examples/csharp.direct.sender/csharp.direct.sender.csproj \ - winsdk_sources/msvc9/examples/csharp.example.client/csharp.example.client.csproj \ - winsdk_sources/msvc9/examples/csharp.example.declare_queues/csharp.example.declare_queues.csproj \ - winsdk_sources/msvc9/examples/csharp.example.drain/csharp.example.drain.csproj \ - winsdk_sources/msvc9/examples/csharp.example.helloworld/csharp.example.helloworld.csproj \ - winsdk_sources/msvc9/examples/csharp.example.server/csharp.example.server.csproj \ - winsdk_sources/msvc9/examples/csharp.example.spout/csharp.example.spout.csproj \ - winsdk_sources/msvc9/examples/csharp.map.callback.receiver/csharp.map.callback.receiver.csproj \ - winsdk_sources/msvc9/examples/csharp.map.callback.sender/csharp.map.callback.sender.csproj \ - winsdk_sources/msvc9/examples/csharp.map.receiver/csharp.map.receiver.csproj \ - winsdk_sources/msvc9/examples/csharp.map.sender/csharp.map.sender.csproj \ - winsdk_sources/msvc9/winsdk_dotnet_examples.sln \ - ../../../src/windows/resources/qpid-icon.ico \ - ../../../src/windows/resources/template-resource.rc \ - ../../../src/windows/resources/version-resource.h diff --git a/qpid/cpp/bindings/qpid/examples/perl/spout.pl b/qpid/cpp/bindings/qpid/examples/perl/spout.pl index 74e589b617..7468a25a3a 100755 --- a/qpid/cpp/bindings/qpid/examples/perl/spout.pl +++ b/qpid/cpp/bindings/qpid/examples/perl/spout.pl @@ -28,6 +28,7 @@ use Time::Local; my $url = "127.0.0.1"; my $timeout = 0; my $count = 1; +my $durable = 0; my $id = ""; my $replyto = ""; my @properties; @@ -41,6 +42,7 @@ my $result = GetOptions( "broker|b=s" => \$url, "timeout|t=i" => \$timeout, "count|c=i" => \$count, + "durable|d" => \$durable, "id|i=s" => \$id, "replyto=s" => \$replyto, "property|p=s@" => \@properties, @@ -96,6 +98,9 @@ eval { $message->set_content_type("text/plain"); } + # set durable flag + $message->set_durable($durable); + # if a reply-to address was supplied, then create a receiver from the # session and wait for a response to be sent my $receiver; diff --git a/qpid/cpp/bindings/qpid/examples/python/console b/qpid/cpp/bindings/qpid/examples/python/console new file mode 100755 index 0000000000..2facc368c3 --- /dev/null +++ b/qpid/cpp/bindings/qpid/examples/python/console @@ -0,0 +1,99 @@ +#!/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 optparse, sys, traceback + +try: + from qpid_messaging import * +except: + from qpid.messaging import * + +parser = optparse.OptionParser(usage="usage: %prog [options] ADDRESS ...", + description="handle requests from the supplied address.") +parser.add_option("-b", "--broker", default="localhost", + help="connect to specified BROKER (default %default)") +parser.add_option("-r", "--reconnect", action="store_true", + help="enable auto reconnect") +parser.add_option("-i", "--reconnect-interval", type="float", default=3, + help="interval between reconnect attempts") +parser.add_option("-l", "--reconnect-limit", type="int", default=10, + help="maximum number of reconnect attempts") +parser.add_option("-v", dest="verbose", action="store_true", + help="enable logging") + +opts, args = parser.parse_args() + +if args: + addr = args.pop(0) +else: + parser.error("address is required") + +conn = Connection(opts.broker, + reconnect=opts.reconnect, + reconnect_interval=opts.reconnect_interval, + reconnect_limit=opts.reconnect_limit) + +try: + conn.open() + session = conn.session() + sender = session.sender(addr) + response_queue = "response-queue;{create:always}" + receiver = session.receiver(response_queue) + receiver.capacity = 10 + + while True: + cmdtype = None + data = None + input = raw_input("Type (eval/shell/exit, ENTER=shell):") + if input != "exit": + if input == "eval": + cmdtype = input + data = raw_input("Text to evaluate: ") + elif input == "shell" or input == "": + cmdtype = "shell" + data = raw_input("Shell cmd: ") + + if cmdtype != None and data != "": + msg = Message() + msg.properties["type"] = cmdtype + # TODO: fix this + # msg.setProperty("type", cmdtype) + msg.content = data + msg.reply_to = response_queue + try: + sender.send(msg) + response = receiver.fetch() + print "Response:" + print "%s" % response.content + session.acknowledge(response) + except SendError, e: + print e + else: + break + if sender is not None: + sender.close() + if receiver is not None: + receiver.close() +except ReceiverError, e: + print e +except KeyboardInterrupt: + pass + +conn.close() diff --git a/qpid/cpp/bindings/qpid/examples/python/drain b/qpid/cpp/bindings/qpid/examples/python/drain new file mode 100755 index 0000000000..2b15a50500 --- /dev/null +++ b/qpid/cpp/bindings/qpid/examples/python/drain @@ -0,0 +1,102 @@ +#!/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 optparse + +try: + from qpid_messaging import * +except: + from qpid.messaging import * + +from qpid.util import URL +from qpid.log import enable, DEBUG, WARN + +parser = optparse.OptionParser(usage="usage: %prog [options] ADDRESS ...", + description="Drain messages from the supplied address.") +parser.add_option("-b", "--broker", default="localhost", + help="connect to specified BROKER (default %default)") +parser.add_option("-c", "--count", type="int", + help="number of messages to drain") +parser.add_option("-f", "--forever", action="store_true", + help="ignore timeout and wait forever") +parser.add_option("-r", "--reconnect", action="store_true", + help="enable auto reconnect") +parser.add_option("-i", "--reconnect-interval", type="float", default=3, + help="interval between reconnect attempts") +parser.add_option("-l", "--reconnect-limit", type="int", + help="maximum number of reconnect attempts") +parser.add_option("-t", "--timeout", type="float", default=0, + help="timeout in seconds to wait before exiting (default %default)") +parser.add_option("-p", "--print", dest="format", default="%(M)s", + help="format string for printing messages (default %default)") +parser.add_option("-v", dest="verbose", action="store_true", + help="enable logging") + +opts, args = parser.parse_args() + +if opts.verbose: + enable("qpid", DEBUG) +else: + enable("qpid", WARN) + +if args: + addr = args.pop(0) +else: + parser.error("address is required") +if opts.forever: + timeout = None +else: + timeout = opts.timeout + +class Formatter: + + def __init__(self, message): + self.message = message + self.environ = {"M": self.message, + "P": self.message.properties, + "C": self.message.content} + + def __getitem__(self, st): + return eval(st, self.environ) + +conn = Connection(opts.broker, + reconnect=opts.reconnect, + reconnect_interval=opts.reconnect_interval, + reconnect_limit=opts.reconnect_limit) +try: + conn.open() + ssn = conn.session() + rcv = ssn.receiver(addr) + + count = 0 + while not opts.count or count < opts.count: + try: + msg = rcv.fetch(timeout=timeout) + print opts.format % Formatter(msg) + count += 1 + ssn.acknowledge() + except Empty: + break +except ReceiverError, e: + print e +except KeyboardInterrupt: + pass + +conn.close() diff --git a/qpid/cpp/bindings/qmf/Makefile.am b/qpid/cpp/bindings/qpid/examples/python/hello index ee4ff1d3c1..52ea955093 100644..100755 --- a/qpid/cpp/bindings/qmf/Makefile.am +++ b/qpid/cpp/bindings/qpid/examples/python/hello @@ -1,3 +1,4 @@ +#!/usr/bin/env python # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file @@ -17,16 +18,39 @@ # under the License. # -if HAVE_SWIG +import sys -SUBDIRS = tests +try: + from qpid_messaging import * +except: + from qpid.messaging import * -if HAVE_RUBY_DEVEL -SUBDIRS += ruby -endif +if len(sys.argv)<2: + broker = "localhost:5672" +else: + broker = sys.argv[1] -if HAVE_PYTHON_DEVEL -SUBDIRS += python -endif +if len(sys.argv)<3: + address = "amq.topic" +else: + address = sys.argv[2] -endif +connection = Connection(broker) + +try: + connection.open() + session = connection.session() + + sender = session.sender(address) + receiver = session.receiver(address) + + sender.send(Message("Hello world!")); + + message = receiver.fetch() + print message.content + session.acknowledge() + +except MessagingError,m: + print m + +connection.close() diff --git a/qpid/cpp/bindings/qpid/examples/python/hello_xml b/qpid/cpp/bindings/qpid/examples/python/hello_xml new file mode 100755 index 0000000000..05fa5cc7ba --- /dev/null +++ b/qpid/cpp/bindings/qpid/examples/python/hello_xml @@ -0,0 +1,81 @@ +#!/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 sys + +try: + from qpid_messaging import * +except: + from qpid.messaging import * + +broker = "localhost:5672" +connection = Connection(broker) + +try: + connection.open() + session = connection.session() + +# Set up the receiver + query = """ + let $w := ./weather + return $w/station = 'Raleigh-Durham International Airport (KRDU)' + and $w/temperature_f > 50 + and $w/temperature_f - $w/dewpoint > 5 + and $w/wind_speed_mph > 7 + and $w/wind_speed_mph < 20 """ + +# query="./weather" + + address = """ + xml; { + create: always, + node:{ type: queue }, + link: { + x-bindings: [{ exchange: xml, key: weather, arguments: { xquery: %r} }] + } + } + """ % query + + receiver = session.receiver(address) + +# Send an observation + + observations = """ + <weather> + <station>Raleigh-Durham International Airport (KRDU)</station> + <wind_speed_mph>16</wind_speed_mph> + <temperature_f>70</temperature_f> + <dewpoint>35</dewpoint> + </weather> """ + + message = Message(subject="weather", content=observations) + sender = session.sender("xml") + sender.send(message) + +# Retrieve matching message from the receiver and print it + + message = receiver.fetch(timeout=1) + print message.content + session.acknowledge() + +except MessagingError,m: + print m + +connection.close() diff --git a/qpid/cpp/bindings/qpid/examples/python/server b/qpid/cpp/bindings/qpid/examples/python/server new file mode 100755 index 0000000000..fb87951bad --- /dev/null +++ b/qpid/cpp/bindings/qpid/examples/python/server @@ -0,0 +1,100 @@ +#!/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 optparse, sys, traceback + +try: + from qpid_messaging import * +except: + from qpid.messaging import * + +from qpid.util import URL +from subprocess import Popen, STDOUT, PIPE +from qpid.log import enable, DEBUG, WARN + +parser = optparse.OptionParser(usage="usage: %prog [options] ADDRESS ...", + description="handle requests from the supplied address.") +parser.add_option("-b", "--broker", default="localhost", + help="connect to specified BROKER (default %default)") +parser.add_option("-r", "--reconnect", action="store_true", + help="enable auto reconnect") +parser.add_option("-i", "--reconnect-interval", type="float", default=3, + help="interval between reconnect attempts") +parser.add_option("-l", "--reconnect-limit", type="int", + help="maximum number of reconnect attempts") +parser.add_option("-v", dest="verbose", action="store_true", + help="enable logging") + +opts, args = parser.parse_args() + +if opts.verbose: + enable("qpid", DEBUG) +else: + enable("qpid", WARN) + +if args: + addr = args.pop(0) +else: + parser.error("address is required") + +conn = Connection(opts.broker, + reconnect=opts.reconnect, + reconnect_interval=opts.reconnect_interval, + reconnect_limit=opts.reconnect_limit) +def dispatch(msg): + msg_type = msg.properties.get("type") + if msg_type == "shell": + proc = Popen(msg.content, shell=True, stderr=STDOUT, stdin=PIPE, stdout=PIPE) + output, _ = proc.communicate() + result = Message(output) + result.properties["exit"] = proc.returncode + elif msg_type == "eval": + try: + content = str(eval(msg.content)) + except: + content = traceback.format_exc() + result = Message(content = content) + else: + result = Message("unrecognized message type: %s" % msg_type) + return result + +try: + conn.open() + ssn = conn.session() + rcv = ssn.receiver(addr) + + while True: + msg = rcv.fetch() + response = dispatch(msg) + snd = None + try: + snd = ssn.sender(msg.reply_to) + snd.send(response) + except SendError, e: + print e + if snd is not None: + snd.close() + ssn.acknowledge() +except ReceiverError, e: + print e +except KeyboardInterrupt: + pass + +conn.close() diff --git a/qpid/cpp/bindings/qpid/examples/python/spout b/qpid/cpp/bindings/qpid/examples/python/spout new file mode 100755 index 0000000000..48921d4387 --- /dev/null +++ b/qpid/cpp/bindings/qpid/examples/python/spout @@ -0,0 +1,139 @@ +#!/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 optparse, time + +try: + from qpid_messaging import * + from uuid import uuid4 +except: + from qpid.messaging import * + +from qpid.util import URL +from qpid.log import enable, DEBUG, WARN + +def nameval(st): + idx = st.find("=") + if idx >= 0: + name = st[0:idx] + value = st[idx+1:] + else: + name = st + value = None + return name, value + +parser = optparse.OptionParser(usage="usage: %prog [options] ADDRESS [ CONTENT ... ]", + description="Send messages to the supplied address.") +parser.add_option("-b", "--broker", default="localhost", + help="connect to specified BROKER (default %default)") +parser.add_option("-r", "--reconnect", action="store_true", + help="enable auto reconnect") +parser.add_option("-i", "--reconnect-interval", type="float", default=3, + help="interval between reconnect attempts") +parser.add_option("-l", "--reconnect-limit", type="int", + help="maximum number of reconnect attempts") +parser.add_option("-c", "--count", type="int", default=1, + help="stop after count messages have been sent, zero disables (default %default)") +parser.add_option("-d", "--durable", action="store_true", + help="make the message persistent") +parser.add_option("-t", "--timeout", type="float", default=None, + help="exit after the specified time") +parser.add_option("-I", "--id", help="use the supplied id instead of generating one") +parser.add_option("-S", "--subject", help="specify a subject") +parser.add_option("-R", "--reply-to", help="specify reply-to address") +parser.add_option("-P", "--property", dest="properties", action="append", default=[], + metavar="NAME=VALUE", help="specify message property") +parser.add_option("-M", "--map", dest="entries", action="append", default=[], + metavar="KEY=VALUE", + help="specify map entry for message body") +parser.add_option("-v", dest="verbose", action="store_true", + help="enable logging") + +opts, args = parser.parse_args() + +if opts.verbose: + enable("qpid", DEBUG) +else: + enable("qpid", WARN) + +if opts.id is None: + spout_id = str(uuid4()) +else: + spout_id = opts.id +if args: + addr = args.pop(0) +else: + parser.error("address is required") + +content = None +content_type = None + +if args: + text = " ".join(args) +else: + text = None + +if opts.entries: + content = {} + if text: + content["text"] = text + for e in opts.entries: + name, val = nameval(e) + content[name] = val +else: + content = text + # no entries were supplied, so assume text/plain for + # compatibility with java (and other) clients + content_type = "text/plain" + +conn = Connection(opts.broker, + reconnect=opts.reconnect, + reconnect_interval=opts.reconnect_interval, + reconnect_limit=opts.reconnect_limit) +try: + conn.open() + ssn = conn.session() + snd = ssn.sender(addr) + + count = 0 + start = time.time() + while (opts.count == 0 or count < opts.count) and \ + (opts.timeout is None or time.time() - start < opts.timeout): + msg = Message(subject=opts.subject, + reply_to=opts.reply_to, + content=content) + if opts.durable: + msg.durable = True + if content_type is not None: + msg.content_type = content_type + msg.properties["spout-id"] = "%s:%s" % (spout_id, count) + for p in opts.properties: + name, val = nameval(p) + msg.properties[name] = val + + snd.send(msg) + count += 1 + print msg +except SendError, e: + print e +except KeyboardInterrupt: + pass + +conn.close() diff --git a/qpid/cpp/bindings/qpid/examples/python/statistics.py b/qpid/cpp/bindings/qpid/examples/python/statistics.py new file mode 100644 index 0000000000..089b81b740 --- /dev/null +++ b/qpid/cpp/bindings/qpid/examples/python/statistics.py @@ -0,0 +1,139 @@ +#!/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 time + +TS = "ts" +TIME_SEC = 1000000000 +MILLISECOND = 1000 + +class Statistic: + def message(self, msg): + return + def report(self): + return "" + def header(self): + return "" + + +class Throughput(Statistic): + def __init__(self): + self.messages = 0 + self.started = False + + def message(self, m): + self.messages += 1 + if not self.started: + self.start = time.time() + self.started = True + + def header(self): + return "tp(m/s)" + + def report(self): + if self.started: + elapsed = time.time() - self.start + return str(int(self.messages/elapsed)) + else: + return "0" + + +class ThroughputAndLatency(Throughput): + def __init__(self): + Throughput.__init__(self) + self.total = 0.0 + self.min = float('inf') + self.max = -float('inf') + self.samples = 0 + + def message(self, m): + Throughput.message(self, m) + if TS in m.properties: + self.samples+=1 + latency = MILLISECOND * (time.time() - float(m.properties[TS])/TIME_SEC) + if latency > 0: + self.total += latency + if latency < self.min: + self.min = latency + if latency > self.max: + self.max = latency + + def header(self): +# Throughput.header(self) + return "%s\tl-min\tl-max\tl-avg" % Throughput.header(self) + + def report(self): + output = Throughput.report(self) + if (self.samples > 0): + output += "\t%.2f\t%.2f\t%.2f" %(self.min, self.max, self.total/self.samples) + return output + + +# Report batch and overall statistics +class ReporterBase: + def __init__(self, batch, wantHeader): + self.batchSize = batch + self.batchCount = 0 + self.headerPrinted = not wantHeader + self.overall = None + self.batch = None + + def create(self): + return + + # Count message in the statistics + def message(self, m): + if self.overall == None: + self.overall = self.create() + self.overall.message(m) + if self.batchSize: + if self.batch == None: + self.batch = self.create() + self.batch.message(m) + self.batchCount+=1 + if self.batchCount == self.batchSize: + self.header() + print self.batch.report() + self.create() + self.batchCount = 0 + + # Print overall report. + def report(self): + if self.overall == None: + self.overall = self.create() + self.header() + print self.overall.report() + + def header(self): + if not self.headerPrinted: + if self.overall == None: + self.overall = self.create() + print self.overall.header() + self.headerPrinted = True + + +class Reporter(ReporterBase): + def __init__(self, batchSize, wantHeader, Stats): + ReporterBase.__init__(self, batchSize, wantHeader) + self.__stats = Stats + + def create(self): + ClassName = self.__stats.__class__ + return ClassName() diff --git a/qpid/cpp/bindings/qpid/perl/CMakeLists.txt b/qpid/cpp/bindings/qpid/perl/CMakeLists.txt index c8257b74aa..540c0da2de 100644 --- a/qpid/cpp/bindings/qpid/perl/CMakeLists.txt +++ b/qpid/cpp/bindings/qpid/perl/CMakeLists.txt @@ -24,6 +24,10 @@ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/perl.i PROPERTIES CPLUSP set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/perl.i PROPERTIES SWIG_FLAGS "-I${qpid-cpp_SOURCE_DIR}/include;-I${qpid-cpp_SOURCE_DIR}/include;-I${qpid-cpp_SOURCE_DIR}/bindings") +list(APPEND SWIG_MODULE_cqpid_perl_EXTRA_DEPS + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/qpid/qpid.i + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/qpid/swig_perl_typemaps.i +) swig_add_module(cqpid_perl perl ${CMAKE_CURRENT_SOURCE_DIR}/perl.i) swig_link_libraries(cqpid_perl qpidmessaging qpidtypes qmf2 ${PERL_LIBRARY}) diff --git a/qpid/cpp/bindings/qpid/python/CMakeLists.txt b/qpid/cpp/bindings/qpid/python/CMakeLists.txt index 2693475dea..15f9bbb9f7 100644 --- a/qpid/cpp/bindings/qpid/python/CMakeLists.txt +++ b/qpid/cpp/bindings/qpid/python/CMakeLists.txt @@ -24,8 +24,12 @@ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/python.i PROPERTIES CPLU set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/python.i PROPERTIES SWIG_FLAGS "-I${qpid-cpp_SOURCE_DIR}/include;-I${qpid-cpp_SOURCE_DIR}/bindings") -swig_add_module(cqpid_python python ${CMAKE_CURRENT_SOURCE_DIR}/python.i) -swig_link_libraries(cqpid_python qpidmessaging qpidtypes qmf2 ${PYTHON_LIBRARIES}) +list(APPEND SWIG_MODULE_qpid_messaging_python_EXTRA_DEPS + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/qpid/qpid.i + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/qpid/swig_python_typemaps.i +) +swig_add_module(qpid_messaging python ${CMAKE_CURRENT_SOURCE_DIR}/python.i) +swig_link_libraries(qpid_messaging qpidmessaging qpidtypes ${PYTHON_LIBRARIES}) set_source_files_properties(${swig_generated_file_fullname} PROPERTIES COMPILE_FLAGS "-fno-strict-aliasing") include_directories(${PYTHON_INCLUDE_PATH} @@ -35,18 +39,17 @@ include_directories(${PYTHON_INCLUDE_PATH} ##------------------------------------ ## Install the complete Python binding ##------------------------------------ -install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m py_compile cqpid.py +install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -m py_compile qpid_messaging.py WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") -install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile cqpid.py +install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile qpid_messaging.py WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cqpid.py - ${CMAKE_CURRENT_BINARY_DIR}/cqpid.pyc - ${CMAKE_CURRENT_BINARY_DIR}/cqpid.pyo +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qpid_messaging.py + ${CMAKE_CURRENT_BINARY_DIR}/qpid_messaging.pyc + ${CMAKE_CURRENT_BINARY_DIR}/qpid_messaging.pyo DESTINATION ${PYTHON_SITEARCH_PACKAGES} COMPONENT ${QPID_COMPONENT_CLIENT} ) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/_cqpid_python.so - RENAME _cqpid.so +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/_qpid_messaging.so DESTINATION ${PYTHON_SITEARCH_PACKAGES} COMPONENT ${QPID_COMPONENT_CLIENT} ) diff --git a/qpid/cpp/bindings/qpid/python/ChangeLog b/qpid/cpp/bindings/qpid/python/ChangeLog index 2c1e689f06..ff6704cdd6 100644 --- a/qpid/cpp/bindings/qpid/python/ChangeLog +++ b/qpid/cpp/bindings/qpid/python/ChangeLog @@ -1 +1,5 @@ -Version 0.24: +Version 0.26: + * QPID-4952: Changed the module name to qpid_messaging. + * QPID-5140: Added get/set method to MessageProperties. + * QPID-4924: Added examples from pure Python libraries. + * QPID-4924: Added the console example to interact with server. diff --git a/qpid/cpp/bindings/qpid/python/Makefile.am b/qpid/cpp/bindings/qpid/python/Makefile.am deleted file mode 100644 index d27cc8b3a2..0000000000 --- a/qpid/cpp/bindings/qpid/python/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -if HAVE_PYTHON_DEVEL - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/bindings -I$(top_builddir)/include -I$(top_srcdir)/src/qmf -I$(top_srcdir)/src -I$(top_builddir)/src - -generated_file_list = \ - cqpid.cpp \ - cqpid.py - -EXTRA_DIST = CMakeLists.txt python.i -BUILT_SOURCES = $(generated_file_list) -SWIG_FLAGS = -w362,401 - -$(generated_file_list): $(srcdir)/python.i - $(SWIG) -c++ -python $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I$(top_srcdir)/src/qmf -I/usr/include -o cqpid.cpp $(srcdir)/python.i - -pylibdir = $(pyexecdir) - -pylib_LTLIBRARIES = _cqpid.la -cqpiddir = $(pythondir) -cqpid_PYTHON = cqpid.py - -_cqpid_la_LDFLAGS = -avoid-version -module -shared -_cqpid_la_LIBADD = $(PYTHON_LIBS) -L$(top_builddir)/src/.libs -lqpidmessaging -lqpidtypes $(top_builddir)/src/libqpidmessaging.la $(top_builddir)/src/libqpidtypes.la -_cqpid_la_CXXFLAGS = $(INCLUDES) $(PYTHON_CFLAGS) -fno-strict-aliasing -nodist__cqpid_la_SOURCES = cqpid.cpp - -CLEANFILES = $(generated_file_list) - -endif # HAVE_PYTHON_DEVEL - diff --git a/qpid/cpp/bindings/qpid/python/extra_dist/CMakeLists.txt b/qpid/cpp/bindings/qpid/python/extra_dist/CMakeLists.txt index dbb0102db1..8ddd7869ae 100644 --- a/qpid/cpp/bindings/qpid/python/extra_dist/CMakeLists.txt +++ b/qpid/cpp/bindings/qpid/python/extra_dist/CMakeLists.txt @@ -49,10 +49,10 @@ SET_SOURCE_FILES_PROPERTIES (${CMAKE_CURRENT_SOURCE_DIR}/python.i SET_SOURCE_FILES_PROPERTIES (${CMAKE_CURRENT_SOURCE_DIR}/python.i PROPERTIES SWIG_FLAGS "-I${QPID_INCLUDE_DIR}") -SWIG_ADD_MODULE (cqpid_python python +SWIG_ADD_MODULE (qpid_messaging_python python ${CMAKE_CURRENT_SOURCE_DIR}/python.i) -SWIG_LINK_LIBRARIES (cqpid_python +SWIG_LINK_LIBRARIES (qpid_messaging_python qpidmessaging qpidtypes ${PYTHON_LIBRARIES}) @@ -61,9 +61,9 @@ SWIG_LINK_LIBRARIES (cqpid_python ## Install the bindings ## -------------------- -INSTALL (CODE "EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -m py_compile cqpid.py +INSTALL (CODE "EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -m py_compile qpid_messaging.py WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") -INSTALL (CODE "EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile cqpid.py +INSTALL (CODE "EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -O -m py_compile qpid_messaging.py WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})") SET_SOURCE_FILES_PROPERTIES (${swig_generated_file_fullname} @@ -75,12 +75,12 @@ INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ) -INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/cqpid.py - ${CMAKE_CURRENT_BINARY_DIR}/cqpid.pyc - ${CMAKE_CURRENT_BINARY_DIR}/cqpid.pyo +INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/qpid_messaging.py + ${CMAKE_CURRENT_BINARY_DIR}/qpid_messaging.pyc + ${CMAKE_CURRENT_BINARY_DIR}/qpid_messaging.pyo DESTINATION ${PYTHON_SITEARCH_PACKAGES}) -INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/_cqpid_python.so - RENAME _cqpid.so +INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/_qpid_messaging_python.so + RENAME _qpid_messaging.so DESTINATION ${PYTHON_SITEARCH_PACKAGES}) diff --git a/qpid/cpp/bindings/qpid/python/python.i b/qpid/cpp/bindings/qpid/python/python.i index 148cad5e63..624cee35bc 100644 --- a/qpid/cpp/bindings/qpid/python/python.i +++ b/qpid/cpp/bindings/qpid/python/python.i @@ -17,7 +17,8 @@ * under the License. */ -%module cqpid +%module qpid_messaging + %include "std_string.i" %include "qpid/swig_python_typemaps.i" @@ -29,7 +30,7 @@ /* * Exceptions * - * The convention below is that exceptions in _cqpid.so have the same + * The convention below is that exceptions in _qpid_messaging.so have the same * names as in the C++ library. They get renamed to their Python * equivalents when brought into the Python wrapping */ @@ -39,12 +40,12 @@ static PyObject* exception; %} %init %{ exception = PyErr_NewException( - (char *) ("_cqpid." #exception), parent, NULL); + (char *) ("_qpid_messaging." #exception), parent, NULL); Py_INCREF(exception); PyModule_AddObject(m, #exception, exception); %} %pythoncode %{ - exception = _cqpid. ## exception + exception = _qpid_messaging. ## exception %} %enddef @@ -139,8 +140,9 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) /* This only renames the non-const version (I believe). Then again, I * don't even know why there is a non-const version of the method. */ %rename(opened) qpid::messaging::Connection::isOpen(); +%rename(_close) qpid::messaging::Connection::close(); %rename(receiver) qpid::messaging::Session::createReceiver; -%rename(sender) qpid::messaging::Session::createSender; +%rename(_sender) qpid::messaging::Session::createSender; %rename(_acknowledge_all) qpid::messaging::Session::acknowledge(bool); %rename(_acknowledge_msg) qpid::messaging::Session::acknowledge( Message &, bool); @@ -163,26 +165,28 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) %extend qpid::messaging::Connection { %pythoncode %{ - # Handle the different options by converting underscores to hyphens. - # Also, the sasl_mechanisms option in Python has no direct - # equivalent in C++, so we will translate them to sasl_mechanism - # when possible. def __init__(self, url=None, **options): if url: - args = [url] + args = [str(url)] else: args = [] - if options : - if "sasl_mechanisms" in options : - if ' ' in options.get("sasl_mechanisms",'') : - raise Exception( - "C++ Connection objects are unable to handle " - "multiple sasl-mechanisms") - options["sasl_mechanism"] = options.pop("sasl_mechanisms") - args.append(options) - this = _cqpid.new_Connection(*args) + if options: + # remove null valued options + clean_opts = {} + for k, v in options.iteritems(): + if v: + clean_opts[k] = v + args.append(clean_opts) + this = _qpid_messaging.new_Connection(*args) try: self.this.append(this) except: self.this = this + + def attached(self): + return self.opened() + + def close(self, timeout=None): + #timeout not supported in c++ + self._close() %} /* Return a pre-existing session with the given name, if one @@ -236,18 +240,29 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) __swig_getmethods__["connection"] = getConnection if _newclass: connection = property(getConnection) + + def sender(self, target, **options) : + s = self._sender(target) + s._setDurable(options.get("durable")) + return s %} } %extend qpid::messaging::Receiver { %pythoncode %{ + def _get_source(self): + return self.getAddress().str() + __swig_getmethods__["capacity"] = getCapacity __swig_setmethods__["capacity"] = setCapacity if _newclass: capacity = property(getCapacity, setCapacity) __swig_getmethods__["session"] = getSession if _newclass: session = property(getSession) + + __swig_getmethods__["source"] = _get_source + if _newclass: source = property(_get_source) %} %pythoncode %{ @@ -263,25 +278,68 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) %extend qpid::messaging::Sender { %pythoncode %{ + def _get_target(self): + return self.getAddress().str() + + def _setDurable(self, d): + self.durable = d + def send(self, object, sync=True) : if isinstance(object, Message): message = object else: message = Message(object) + if self.durable and message.durable is None: + message.durable = self.durable return self._send(message, sync) - + __swig_getmethods__["capacity"] = getCapacity __swig_setmethods__["capacity"] = setCapacity if _newclass: capacity = property(getCapacity, setCapacity) __swig_getmethods__["session"] = getSession if _newclass: session = property(getSession) + + __swig_getmethods__["target"] = _get_target + if _newclass: source = property(_get_target) + %} } %extend qpid::messaging::Message { %pythoncode %{ + class MessageProperties: + def __init__(self, msg): + self.msg = msg + self.properties = self.msg.getProperties() + + def __len__(self): + return self.properties.__len__() + + def __getitem__(self, key): + return self.properties[key]; + + def get(self, key): + return self.__getitem__(key) + + def __setitem__(self, key, value): + self.properties[key] = value + self.msg.setProperty(key, value) + + def set(self, key, value): + self.__setitem__(key, value) + + def __delitem__(self, key): + del self.properties[key] + self.msg.setProperties(self.properties) + + def __iter__(self): + return self.properties.iteritems() + + def __repr__(self): + return str(self.properties) + # UNSPECIFIED was module level before, but I do not # know how to insert python code at the top of the module. # (A bare "%pythoncode" inserts at the end. @@ -290,10 +348,10 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) subject=None, user_id=None, reply_to=None, correlation_id=None, durable=None, priority=None, ttl=None, properties=None): - this = _cqpid.new_Message('') + this = _qpid_messaging.new_Message('') try: self.this.append(this) except: self.this = this - if content : + if not content is None: self.content = content if content_type != UNSPECIFIED : self.content_type = content_type @@ -314,34 +372,46 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) if ttl is not None : self.ttl = ttl if properties is not None : - # Can't set properties via (inst).getProperties, because - # the typemaps make a copy of the underlying properties. - # Instead, set via setProperty for the time-being - for k, v in properties.iteritems() : - self.setProperty(k, v) + self.setProperties(properties) + + def _get_msg_props(self): + try: + return self._msg_props + except AttributeError: + self._msg_props = Message.MessageProperties(self) + return self._msg_props def _get_content(self) : + obj = self.getContentObject() + if obj: + return obj if self.content_type == "amqp/list" : return decodeList(self) if self.content_type == "amqp/map" : return decodeMap(self) return self.getContent() def _set_content(self, content) : - if isinstance(content, basestring) : + if isinstance(content, str) : self.setContent(content) + elif isinstance(content, unicode) : + if not self.content_type: self.content_type = "text/plain" + self.setContent(str(content)) elif isinstance(content, list) or isinstance(content, dict) : encode(content, self) else : - # Not a type we can handle. Try setting it anyway, - # although this will probably lead to a swig error - self.setContent(content) + self.setContentObject(content) __swig_getmethods__["content"] = _get_content __swig_setmethods__["content"] = _set_content if _newclass: content = property(_get_content, _set_content) - __swig_getmethods__["content_type"] = getContentType + def _get_content_type(self) : + ct = self.getContentType() + if ct == "": return None + else: return ct + + __swig_getmethods__["content_type"] = _get_content_type __swig_setmethods__["content_type"] = setContentType - if _newclass: content_type = property(getContentType, setContentType) + if _newclass: content_type = property(_get_content_type, setContentType) __swig_getmethods__["id"] = getMessageId __swig_setmethods__["id"] = setMessageId @@ -379,8 +449,8 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) __swig_setmethods__["durable"] = setDurable if _newclass: durable = property(getDurable, setDurable) - __swig_getmethods__["properties"] = getProperties - if _newclass: properties = property(getProperties) + __swig_getmethods__["properties"] = _get_msg_props + if _newclass: properties = property(_get_msg_props) def getReplyTo(self) : return self._getReplyTo().str() @@ -389,7 +459,7 @@ QPID_EXCEPTION(UnauthorizedAccess, SessionError) __swig_getmethods__["reply_to"] = getReplyTo __swig_setmethods__["reply_to"] = setReplyTo if _newclass: reply_to = property(getReplyTo, setReplyTo) - + def __repr__(self): args = [] for name in ["id", "subject", "user_id", "reply_to", diff --git a/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt b/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt index a56fac7c8a..60c60445b7 100644 --- a/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt +++ b/qpid/cpp/bindings/qpid/ruby/CMakeLists.txt @@ -39,6 +39,10 @@ include_directories(${RUBY_INCLUDE_DIRS} ${qpid-cpp_SOURCE_DIR}/include ${qpid-cpp_SOURCE_DIR}/bindings) +list(APPEND SWIG_MODULE_cqpid_ruby_EXTRA_DEPS + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/qpid/qpid.i + ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/qpid/swig_ruby_typemaps.i +) swig_add_module(cqpid_ruby ruby ${CMAKE_CURRENT_SOURCE_DIR}/ruby.i) swig_link_libraries(cqpid_ruby qpidmessaging qpidtypes qmf2 ${RUBY_LIBRARY}) diff --git a/qpid/cpp/bindings/qpid/ruby/ChangeLog b/qpid/cpp/bindings/qpid/ruby/ChangeLog index 03813053d2..f9906c2d51 100644 --- a/qpid/cpp/bindings/qpid/ruby/ChangeLog +++ b/qpid/cpp/bindings/qpid/ruby/ChangeLog @@ -1,4 +1,10 @@ -Verison 0.22: +Version 0.26: + * QPID-4834: Ruby client examples incorrectly handles '--connection-options' option + +Version 0.24: + * No language-specific changes. + +Version 0.22: * Qpid::Messaging::Address can use an address string on creation. * Qpid::Messaging::Message can use an address string for reply_to. * Removed errors.rb and the KeyError and SessionNameException errors. diff --git a/qpid/cpp/bindings/qpid/ruby/Makefile.am b/qpid/cpp/bindings/qpid/ruby/Makefile.am deleted file mode 100644 index 398449c7ed..0000000000 --- a/qpid/cpp/bindings/qpid/ruby/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -if HAVE_RUBY_DEVEL - -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/bindings -I$(top_builddir)/include -I$(top_srcdir)/src -I$(top_builddir)/src - -EXTRA_DIST = CMakeLists.txt ruby.i -BUILT_SOURCES = cqpid.cpp -SWIG_FLAGS = -w362,401 - -rubylibdir = $(RUBY_LIB) - -cqpid.cpp: $(srcdir)/ruby.i - $(SWIG) -ruby -c++ $(SWIG_FLAGS) $(INCLUDES) $(QPID_CXXFLAGS) -I/usr/include -o cqpid.cpp $(srcdir)/ruby.i - -rubylibarchdir = $(RUBY_LIB_ARCH) -rubylibarch_LTLIBRARIES = cqpid.la - -cqpid_la_LDFLAGS = -avoid-version -module -shared -shrext ".$(RUBY_DLEXT)" -cqpid_la_LIBADD = $(RUBY_LIBS) -L$(top_builddir)/src/.libs -lqpidmessaging -lqpidtypes \ - $(top_builddir)/src/libqpidmessaging.la $(top_builddir)/src/libqpidtypes.la -cqpid_la_CXXFLAGS = $(INCLUDES) -I$(RUBY_INC) -I$(RUBY_INC_ARCH) -fno-strict-aliasing -nodist_cqpid_la_SOURCES = cqpid.cpp - -CLEANFILES = cqpid.cpp - -endif # HAVE_RUBY_DEVEL diff --git a/qpid/cpp/bindings/qpid/ruby/examples/spout.rb b/qpid/cpp/bindings/qpid/ruby/examples/spout.rb index f7170f146b..6a0751e682 100644 --- a/qpid/cpp/bindings/qpid/ruby/examples/spout.rb +++ b/qpid/cpp/bindings/qpid/ruby/examples/spout.rb @@ -26,6 +26,7 @@ options = { :broker => "127.0.0.1", :address => "", :timeout => 0, + :durable => false, :count => 1, :properties => {}, :content => nil, @@ -51,6 +52,11 @@ opts = OptionParser.new do |opts| options[:timeout] = Qpid::Messaging::Duration.new timeout * 1000 end + opts.on("-d", "--durable", + "make the message durable (def. #{options[:durable]})") do + options[:durable] = true + end + opts.on("-c", "--count VALUE", Integer, "stop after count messages have been sent, zero disables") do |count| options[:count] = count @@ -85,8 +91,9 @@ opts = OptionParser.new do |opts| options[:content] = content end - opts.on(nil, "--connection-options VALUE", + opts.on("--connection-options VALUE", "connection options string in the form {name1:value1, name2:value2}") do |conopts| + options[:connection_options] = conopts end end @@ -100,7 +107,27 @@ end # now get the non-arg options options[:address] = ARGV[0] unless ARGV[0].nil? -connection = Qpid::Messaging::Connection.new :url => options[:broker], :options => options[:connection_options] +# process the connection options +unless options[:connection_options].nil? + fields = options[:connection_options].gsub(/^{(.*)}$/, '\1') + # remove any surrounding braces + if /{.*}/ =~ fields + fields = fields[1..-2] + end + # break up the options separated by commas + keysvalues = {} + fields.split(",").each do |field| + if /.+:.+/ =~ field + (key, value) = field.split(":") + keysvalues[key] = value + end + end + # now store the options + options[:connection_options] = keysvalues +end + +connection = Qpid::Messaging::Connection.new(:url => options[:broker], + :options => options[:connection_options]) connection.open session = connection.create_session sender = session.create_sender options[:address] @@ -114,6 +141,7 @@ options[:properties].each_key {|key| message[key] = options[:properties][key]} elsif options[:content] message.content = options[:content] end + message.durable = options[:durable] message.content = options[:content] unless options[:content].nil? message.properties["spout-id"] = "#{count}" message.reply_to = options[:replyto] unless options[:replyto].nil? || options[:replyto].empty? |
