summaryrefslogtreecommitdiff
path: root/qpid/cpp/bindings
diff options
context:
space:
mode:
authorKim van der Riet <kpvdr@apache.org>2013-09-20 18:59:30 +0000
committerKim van der Riet <kpvdr@apache.org>2013-09-20 18:59:30 +0000
commitc70bf3ea28cdf6bafd8571690d3e5c466a0658a2 (patch)
tree68b24940e433f3f9c278b054d9ea1622389bd332 /qpid/cpp/bindings
parentfcdf1723c7b5cdf0772054a93edb6e7d97c4bb1e (diff)
downloadqpid-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')
-rw-r--r--qpid/cpp/bindings/CMakeLists.txt8
-rw-r--r--qpid/cpp/bindings/qmf/python/CMakeLists.txt66
-rw-r--r--qpid/cpp/bindings/qmf/python/Makefile.am51
-rw-r--r--qpid/cpp/bindings/qmf/python/python.i143
-rw-r--r--qpid/cpp/bindings/qmf/python/qmf.py1680
-rw-r--r--qpid/cpp/bindings/qmf/ruby/CMakeLists.txt51
-rw-r--r--qpid/cpp/bindings/qmf/ruby/Makefile.am45
-rw-r--r--qpid/cpp/bindings/qmf/ruby/qmf.rb1528
-rw-r--r--qpid/cpp/bindings/qmf/ruby/ruby.i106
-rw-r--r--qpid/cpp/bindings/qmf/tests/Makefile.am27
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/agent_ruby.rb279
-rw-r--r--qpid/cpp/bindings/qmf/tests/python_agent.py326
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/python_console.py311
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/ruby_console.rb174
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/ruby_console_test.rb397
-rwxr-xr-xqpid/cpp/bindings/qmf/tests/run_interop_tests136
-rw-r--r--qpid/cpp/bindings/qmf/tests/test_base.rb82
-rw-r--r--qpid/cpp/bindings/qmf2/Makefile.am32
-rw-r--r--qpid/cpp/bindings/qmf2/examples/cpp/CMakeLists.txt15
-rw-r--r--qpid/cpp/bindings/qmf2/examples/cpp/Makefile.am39
-rw-r--r--qpid/cpp/bindings/qmf2/python/Makefile.am49
-rw-r--r--qpid/cpp/bindings/qmf2/ruby/Makefile.am44
-rw-r--r--qpid/cpp/bindings/qpid/Makefile.am79
-rw-r--r--qpid/cpp/bindings/qpid/dotnet/Makefile.am159
-rwxr-xr-xqpid/cpp/bindings/qpid/examples/perl/spout.pl5
-rwxr-xr-xqpid/cpp/bindings/qpid/examples/python/console99
-rwxr-xr-xqpid/cpp/bindings/qpid/examples/python/drain102
-rwxr-xr-x[-rw-r--r--]qpid/cpp/bindings/qpid/examples/python/hello (renamed from qpid/cpp/bindings/qmf/Makefile.am)42
-rwxr-xr-xqpid/cpp/bindings/qpid/examples/python/hello_xml81
-rwxr-xr-xqpid/cpp/bindings/qpid/examples/python/server100
-rwxr-xr-xqpid/cpp/bindings/qpid/examples/python/spout139
-rw-r--r--qpid/cpp/bindings/qpid/examples/python/statistics.py139
-rw-r--r--qpid/cpp/bindings/qpid/perl/CMakeLists.txt4
-rw-r--r--qpid/cpp/bindings/qpid/python/CMakeLists.txt21
-rw-r--r--qpid/cpp/bindings/qpid/python/ChangeLog6
-rw-r--r--qpid/cpp/bindings/qpid/python/Makefile.am49
-rw-r--r--qpid/cpp/bindings/qpid/python/extra_dist/CMakeLists.txt18
-rw-r--r--qpid/cpp/bindings/qpid/python/python.i142
-rw-r--r--qpid/cpp/bindings/qpid/ruby/CMakeLists.txt4
-rw-r--r--qpid/cpp/bindings/qpid/ruby/ChangeLog8
-rw-r--r--qpid/cpp/bindings/qpid/ruby/Makefile.am44
-rw-r--r--qpid/cpp/bindings/qpid/ruby/examples/spout.rb32
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?