diff options
author | Andrew Stitcher <astitcher@apache.org> | 2013-07-26 21:31:09 +0000 |
---|---|---|
committer | Andrew Stitcher <astitcher@apache.org> | 2013-07-26 21:31:09 +0000 |
commit | 5fdef74d79857287d64b87c748929afa2d75f497 (patch) | |
tree | 57428afc495b567997447f8c1b0e25725b62d482 | |
parent | 407e0855dfdd568b15e57ea87be1a19a8b632d27 (diff) | |
download | qpid-python-5fdef74d79857287d64b87c748929afa2d75f497.tar.gz |
QPID-4940: Remove obsolete qmf code
- Remove qmf1 engine code
- Remove qmf1 language bindings
- Remove qmf1 agent code (it depends on engine)
- Fix up cmake to build
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1507464 13f79535-47bb-0310-9956-ffa450edef68
62 files changed, 1 insertions, 15557 deletions
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 97693b6fe1..ac92e4916e 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -64,8 +64,7 @@ set_absolute_install_path (QPIDC_CONF_FILE ${QPID_INSTALL_CONFDIR}/qpidc.conf) set_absolute_install_path (QPIDD_CONF_FILE ${QPID_INSTALL_CONFDIR}/qpidd.conf) install(FILES LICENSE NOTICE DESTINATION ${QPID_INSTALL_DOCDIR}) -install(FILES include/qmf/qmfengine.i - include/qmf/qmf2.i +install(FILES include/qmf/qmf2.i DESTINATION ${QPID_INSTALL_INCLUDEDIR}/qmf) if (WIN32) diff --git a/cpp/bindings/CMakeLists.txt b/cpp/bindings/CMakeLists.txt index 14e30ed6ca..af11f175a9 100644 --- a/cpp/bindings/CMakeLists.txt +++ b/cpp/bindings/CMakeLists.txt @@ -81,7 +81,6 @@ if (SWIG_FOUND) add_subdirectory(qpid/python) add_subdirectory(qmf2/python) - add_subdirectory(qmf/python) endif (PYTHONLIBS_FOUND) if (RUBY_FOUND) @@ -93,7 +92,6 @@ 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) diff --git a/cpp/bindings/qmf/python/CMakeLists.txt b/cpp/bindings/qmf/python/CMakeLists.txt deleted file mode 100644 index 14ba888c78..0000000000 --- a/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/cpp/bindings/qmf/python/python.i b/cpp/bindings/qmf/python/python.i deleted file mode 100644 index 118d0d3dbd..0000000000 --- a/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/cpp/bindings/qmf/python/qmf.py b/cpp/bindings/qmf/python/qmf.py deleted file mode 100644 index 06d3070841..0000000000 --- a/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/cpp/bindings/qmf/ruby/CMakeLists.txt b/cpp/bindings/qmf/ruby/CMakeLists.txt deleted file mode 100644 index 37ce73293f..0000000000 --- a/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/cpp/bindings/qmf/ruby/qmf.rb b/cpp/bindings/qmf/ruby/qmf.rb deleted file mode 100644 index d05127db4b..0000000000 --- a/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/cpp/bindings/qmf/ruby/ruby.i b/cpp/bindings/qmf/ruby/ruby.i deleted file mode 100644 index 2854aa0c7e..0000000000 --- a/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/cpp/bindings/qmf/tests/agent_ruby.rb b/cpp/bindings/qmf/tests/agent_ruby.rb deleted file mode 100755 index 5ee5e371d3..0000000000 --- a/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/cpp/bindings/qmf/tests/python_agent.py b/cpp/bindings/qmf/tests/python_agent.py deleted file mode 100644 index 28ba47e1bb..0000000000 --- a/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/cpp/bindings/qmf/tests/python_console.py b/cpp/bindings/qmf/tests/python_console.py deleted file mode 100755 index 1cef824fb5..0000000000 --- a/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/cpp/bindings/qmf/tests/ruby_console.rb b/cpp/bindings/qmf/tests/ruby_console.rb deleted file mode 100755 index 31670312d6..0000000000 --- a/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/cpp/bindings/qmf/tests/ruby_console_test.rb b/cpp/bindings/qmf/tests/ruby_console_test.rb deleted file mode 100755 index 972d5977b8..0000000000 --- a/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/cpp/bindings/qmf/tests/run_interop_tests b/cpp/bindings/qmf/tests/run_interop_tests deleted file mode 100755 index c370f211af..0000000000 --- a/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/cpp/bindings/qmf/tests/test_base.rb b/cpp/bindings/qmf/tests/test_base.rb deleted file mode 100644 index 7d4609097c..0000000000 --- a/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/cpp/include/qmf/engine/Agent.h b/cpp/include/qmf/engine/Agent.h deleted file mode 100644 index 71abf82254..0000000000 --- a/cpp/include/qmf/engine/Agent.h +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef _QmfEngineAgent_ -#define _QmfEngineAgent_ - -/* - * 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 <qmf/engine/Schema.h> -#include <qmf/engine/ObjectId.h> -#include <qmf/engine/Object.h> -#include <qmf/engine/Event.h> -#include <qmf/engine/Query.h> -#include <qmf/engine/Value.h> -#include <qmf/engine/Message.h> - -namespace qmf { -namespace engine { - - /** - * AgentEvent - * - * This structure represents a QMF event coming from the agent to - * the application. - */ - struct AgentEvent { - enum EventKind { - GET_QUERY = 1, - START_SYNC = 2, - END_SYNC = 3, - METHOD_CALL = 4, - DECLARE_QUEUE = 5, - DELETE_QUEUE = 6, - BIND = 7, - UNBIND = 8, - SETUP_COMPLETE = 9 - }; - - EventKind kind; - uint32_t sequence; // Protocol sequence (for all kinds) - char* authUserId; // Authenticated user ID (for all kinds) - char* authToken; // Authentication token if issued (for all kinds) - char* name; // Name of the method/sync query - // (METHOD_CALL, START_SYNC, END_SYNC, DECLARE_QUEUE, BIND, UNBIND) - Object* object; // Object involved in method call (METHOD_CALL) - ObjectId* objectId; // ObjectId for method call (METHOD_CALL) - Query* query; // Query parameters (GET_QUERY, START_SYNC) - Value* arguments; // Method parameters (METHOD_CALL) - char* exchange; // Exchange for bind (BIND, UNBIND) - char* bindingKey; // Key for bind (BIND, UNBIND) - const SchemaObjectClass* objectClass; // (METHOD_CALL) - }; - - class AgentImpl; - - /** - * Agent - Protocol engine for the QMF agent - */ - class Agent { - public: - Agent(char* label, bool internalStore=true); - ~Agent(); - - /** - * Configure the directory path for storing persistent data. - *@param path Null-terminated string containing a directory path where files can be - * created, written, and read. If NULL, no persistent storage will be - * attempted. - */ - void setStoreDir(const char* path); - - /** - * Configure the directory path for files transferred over QMF. - *@param path Null-terminated string containing a directory path where files can be - * created, deleted, written, and read. If NULL, file transfers shall not - * be permitted. - */ - void setTransferDir(const char* path); - - /** - * Pass messages received from the AMQP session to the Agent engine. - *@param message AMQP messages received on the agent session. - */ - void handleRcvMessage(Message& message); - - /** - * Get the next message to be sent to the AMQP network. - *@param item The Message structure describing the message to be produced. - *@return true if the Message is valid, false if there are no messages to send. - */ - bool getXmtMessage(Message& item) const; - - /** - * Remove and discard one message from the head of the transmit queue. - */ - void popXmt(); - - /** - * Get the next application event from the agent engine. - *@param event The event iff the return value is true - *@return true if event is valid, false if there are no events to process - */ - bool getEvent(AgentEvent& event) const; - - /** - * Remove and discard one event from the head of the event queue. - */ - void popEvent(); - - /** - * A new AMQP session has been established for Agent communication. - */ - void newSession(); - - /** - * Start the QMF Agent protocol. This should be invoked after a SETUP_COMPLETE event - * is received from the Agent engine. - */ - void startProtocol(); - - /** - * This method is called periodically so the agent can supply a heartbeat. - */ - void heartbeat(); - - /** - * Respond to a method request. - *@param sequence The sequence number from the method request event. - *@param status The method's completion status. - *@param text Status text ("OK" or an error message) - *@param arguments The list of output arguments from the method call. - */ - void methodResponse(uint32_t sequence, uint32_t status, char* text, const Value& arguments); - - /** - * Send a content indication to the QMF bus. This is only needed for objects that are - * managed by the application. This is *NOT* needed for objects managed by the Agent - * (inserted using addObject). - *@param sequence The sequence number of the GET request or the SYNC_START request. - *@param object The object (annotated with "changed" flags) for publication. - *@param prop If true, changed object properties are transmitted. - *@param stat If true, changed object statistics are transmitted. - */ - void queryResponse(uint32_t sequence, Object& object, bool prop = true, bool stat = true); - - /** - * Indicate the completion of a query. This is not used for SYNC_START requests. - *@param sequence The sequence number of the GET request. - */ - void queryComplete(uint32_t sequence); - - /** - * Register a schema class with the Agent. - *@param cls A SchemaObejctClass object that defines data managed by the agent. - */ - void registerClass(SchemaObjectClass* cls); - - /** - * Register a schema class with the Agent. - *@param cls A SchemaEventClass object that defines events sent by the agent. - */ - void registerClass(SchemaEventClass* cls); - - /** - * Give an object to the Agent for storage and management. Once added, the agent takes - * responsibility for the life cycle of the object. - *@param obj The object to be managed by the Agent. - *@param persistId A unique non-zero value if the object-id is to be persistent. - *@return The objectId of the managed object. - */ - const ObjectId* addObject(Object& obj, uint64_t persistId); - // const ObjectId* addObject(Object& obj, uint32_t persistIdLo, uint32_t persistIdHi); - - /** - * Allocate an object-id for an object that will be managed by the application. - *@param persistId A unique non-zero value if the object-id is to be persistent. - *@return The objectId structure for the allocated ID. - */ - const ObjectId* allocObjectId(uint64_t persistId); - const ObjectId* allocObjectId(uint32_t persistIdLo, uint32_t persistIdHi); - - /** - * Raise an event into the QMF network.. - *@param event The event object for the event to be raised. - */ - void raiseEvent(Event& event); - - private: - AgentImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/ConnectionSettings.h b/cpp/include/qmf/engine/ConnectionSettings.h deleted file mode 100644 index 36312400b1..0000000000 --- a/cpp/include/qmf/engine/ConnectionSettings.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef _QmfEngineConnectionSettings_ -#define _QmfEngineConnectionSettings_ - -/* - * 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 "qmf/engine/QmfEngineImportExport.h" -#include "qpid/sys/IntegerTypes.h" - -namespace qmf { -namespace engine { - - class ConnectionSettingsImpl; - class Value; - - /** - * Settings for AMQP connections to the broker. - * - * \ingroup qmfapi - */ - class ConnectionSettings { - public: - - /** - * Create a set of default connection settings. - * - * If no further attributes are set, the settings will cause a connection to be made to - * the default broker (on localhost or at a host/port supplied by service discovery) and - * authentication will be the best-available (GSSAPI/Kerberos, Anonymous, Plain with prompts - * for username and password). - */ - QMFE_EXTERN ConnectionSettings(); - - /** - * Create a set of connection settings by URL. - * - * @param url Universal resource locator describing the broker address and additional attributes. - * - * The URL is of the form: - * amqp[s]://host[:port][?key=value[&key=value]*] - * - * For example: - * amqp://localhost - * amqp://broker?transport=rdma&authmech=GSSAPI&authservice=qpidd - * amqps://broker?authmech=PLAIN&authuser=guest&authpass=guest - */ - QMFE_EXTERN ConnectionSettings(const char* url); - - /** - * Copy Constructor. - */ - ConnectionSettings(const ConnectionSettings& from); - - /** - * Destroy the connection settings object. - */ - QMFE_EXTERN ~ConnectionSettings(); - - /** - * Set an attribute to control connection setup. - * - * @param key A null-terminated string that is an attribute name. - * - * @param value Reference to a value to be stored as the attribute. The type of the value - * is specific to the key. - * - * @return True if success, False if invalid attribute - */ - QMFE_EXTERN bool setAttr(const char* key, const Value& value); - - /** - * Get the value of an attribute. - * - * @param key A null-terminated attribute name. - * - * @return The value associated with the attribute name. - */ - QMFE_EXTERN Value getAttr(const char* key) const; - - /** - * Get the attribute string (the portion of the URL following the '?') for the settings. - * - * @return A pointer to the attribute string. If the content of this string needs to be - * available beyond the scope of the calling function, it should be copied. The - * returned pointer may become invalid if the set of attributes is changed. - */ - QMFE_EXTERN const char* getAttrString() const; - - /** - * Shortcuts for setting the transport for the connection. - * - * @param port The port value for the connection address. - */ - QMFE_EXTERN void transportTcp(uint16_t port = 5672); - QMFE_EXTERN void transportSsl(uint16_t port = 5671); - QMFE_EXTERN void transportRdma(uint16_t port = 5672); - - /** - * Shortcuts for setting authentication mechanisms. - * - * @param username Null-terminated authentication user name. - * - * @param password Null-terminated authentication password. - * - * @param serviceName Null-terminated GSSAPI service name (Kerberos service principal) - * - * @param minSsf Minimum security factor for connections. 0 = encryption not required. - * - * @param maxSsf Maximum security factor for connections. 0 = encryption not permitted. - */ - QMFE_EXTERN void authAnonymous(const char* username = 0); - QMFE_EXTERN void authPlain(const char* username = 0, const char* password = 0); - QMFE_EXTERN void authGssapi(const char* serviceName, uint32_t minSsf = 0, uint32_t maxSsf = 256); - - /** - * Shortcut for setting connection retry attributes. - * - * @param delayMin Minimum delay (in seconds) between connection attempts. - * - * @param delaxMax Maximum delay (in seconds) between connection attempts. - * - * @param delayFactor Factor to multiply the delay by between failed connection attempts. - */ - QMFE_EXTERN void setRetry(int delayMin = 1, int delayMax = 128, int delayFactor = 2); - - private: - friend class ResilientConnectionImpl; - ConnectionSettingsImpl* impl; - }; - -} -} - -#endif diff --git a/cpp/include/qmf/engine/Console.h b/cpp/include/qmf/engine/Console.h deleted file mode 100644 index bd40c63c6c..0000000000 --- a/cpp/include/qmf/engine/Console.h +++ /dev/null @@ -1,239 +0,0 @@ -#ifndef _QmfEngineConsole_ -#define _QmfEngineConsole_ - -/* - * 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 <qmf/engine/ResilientConnection.h> -#include <qmf/engine/Schema.h> -#include <qmf/engine/ObjectId.h> -#include <qmf/engine/Object.h> -#include <qmf/engine/Event.h> -#include <qmf/engine/Query.h> -#include <qmf/engine/Value.h> -#include <qmf/engine/Message.h> - -namespace qmf { -namespace engine { - - class Console; - class ConsoleImpl; - class BrokerProxyImpl; - class AgentProxy; - struct AgentProxyImpl; - struct MethodResponseImpl; - struct QueryResponseImpl; - struct QueryContext; - - /** - * - */ - class MethodResponse { - public: - MethodResponse(const MethodResponse& from); - ~MethodResponse(); - uint32_t getStatus() const; - const Value* getException() const; - const Value* getArgs() const; - - private: - friend struct MethodResponseImpl; - friend class ConsoleImpl; - MethodResponse(MethodResponseImpl* impl); - MethodResponseImpl* impl; - }; - - /** - * - */ - class QueryResponse { - public: - ~QueryResponse(); - uint32_t getStatus() const; - const Value* getException() const; - uint32_t getObjectCount() const; - const Object* getObject(uint32_t idx) const; - - private: - friend struct QueryResponseImpl; - friend struct QueryContext; - QueryResponse(QueryResponseImpl* impl); - QueryResponseImpl *impl; - }; - - /** - * - */ - struct ConsoleEvent { - enum EventKind { - AGENT_ADDED = 1, - AGENT_DELETED = 2, - NEW_PACKAGE = 3, - NEW_CLASS = 4, - OBJECT_UPDATE = 5, - EVENT_RECEIVED = 7, - AGENT_HEARTBEAT = 8 - }; - - EventKind kind; - AgentProxy* agent; // (AGENT_[ADDED|DELETED|HEARTBEAT]) - char* name; // (NEW_PACKAGE) - const SchemaClassKey* classKey; // (NEW_CLASS) - Object* object; // (OBJECT_UPDATE) - void* context; // (OBJECT_UPDATE) - Event* event; // (EVENT_RECEIVED) - uint64_t timestamp; // (AGENT_HEARTBEAT) - QueryResponse* queryResponse; // (QUERY_COMPLETE) - bool hasProps; - bool hasStats; - }; - - /** - * - */ - struct BrokerEvent { - enum EventKind { - BROKER_INFO = 10, - DECLARE_QUEUE = 11, - DELETE_QUEUE = 12, - BIND = 13, - UNBIND = 14, - SETUP_COMPLETE = 15, - STABLE = 16, - QUERY_COMPLETE = 17, - METHOD_RESPONSE = 18 - }; - - EventKind kind; - char* name; // ([DECLARE|DELETE]_QUEUE, [UN]BIND) - char* exchange; // ([UN]BIND) - char* bindingKey; // ([UN]BIND) - void* context; // (QUERY_COMPLETE, METHOD_RESPONSE) - QueryResponse* queryResponse; // (QUERY_COMPLETE) - MethodResponse* methodResponse; // (METHOD_RESPONSE) - }; - - /** - * - */ - class AgentProxy { - public: - AgentProxy(const AgentProxy& from); - ~AgentProxy(); - const char* getLabel() const; - uint32_t getBrokerBank() const; - uint32_t getAgentBank() const; - - private: - friend struct StaticContext; - friend struct QueryContext; - friend struct AgentProxyImpl; - friend class BrokerProxyImpl; - AgentProxy(AgentProxyImpl* impl); - AgentProxyImpl* impl; - }; - - /** - * - */ - class BrokerProxy { - public: - BrokerProxy(Console& console); - ~BrokerProxy(); - - void sessionOpened(SessionHandle& sh); - void sessionClosed(); - void startProtocol(); - - void handleRcvMessage(Message& message); - bool getXmtMessage(Message& item) const; - void popXmt(); - - bool getEvent(BrokerEvent& event) const; - void popEvent(); - - uint32_t agentCount() const; - const AgentProxy* getAgent(uint32_t idx) const; - void sendQuery(const Query& query, void* context, const AgentProxy* agent = 0); - - private: - friend class ConsoleImpl; - friend struct StaticContext; - BrokerProxyImpl* impl; - }; - - // TODO - move this to a public header - struct ConsoleSettings { - bool rcvObjects; - bool rcvEvents; - bool rcvHeartbeats; - bool userBindings; - - ConsoleSettings() : - rcvObjects(true), - rcvEvents(true), - rcvHeartbeats(true), - userBindings(false) {} - }; - - class Console { - public: - Console(const ConsoleSettings& settings = ConsoleSettings()); - ~Console(); - - bool getEvent(ConsoleEvent& event) const; - void popEvent(); - - void addConnection(BrokerProxy& broker, void* context); - void delConnection(BrokerProxy& broker); - - uint32_t packageCount() const; - const char* getPackageName(uint32_t idx) const; - - uint32_t classCount(const char* packageName) const; - const SchemaClassKey* getClass(const char* packageName, uint32_t idx) const; - - ClassKind getClassKind(const SchemaClassKey* key) const; - const SchemaObjectClass* getObjectClass(const SchemaClassKey* key) const; - const SchemaEventClass* getEventClass(const SchemaClassKey* key) const; - - void bindPackage(const char* packageName); - void bindClass(const SchemaClassKey* key); - void bindClass(const char* packageName, const char* className); - - void bindEvent(const SchemaClassKey *key); - void bindEvent(const char* packageName, const char* eventName); - - /* - void startSync(const Query& query, void* context, SyncQuery& sync); - void touchSync(SyncQuery& sync); - void endSync(SyncQuery& sync); - */ - - private: - friend class BrokerProxyImpl; - friend struct AgentProxyImpl; - friend struct StaticContext; - ConsoleImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/Event.h b/cpp/include/qmf/engine/Event.h deleted file mode 100644 index 647b88dbf8..0000000000 --- a/cpp/include/qmf/engine/Event.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _QmfEngineEvent_ -#define _QmfEngineEvent_ - -/* - * 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. - */ - -namespace qmf { -namespace engine { - - class SchemaEventClass; - class Value; - struct EventImpl; - - class Event { - public: - Event(const SchemaEventClass* type); - Event(const Event& from); - ~Event(); - - const SchemaEventClass* getClass() const; - Value* getValue(const char* key) const; - - private: - friend struct EventImpl; - friend class AgentImpl; - Event(EventImpl* impl); - EventImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/Message.h b/cpp/include/qmf/engine/Message.h deleted file mode 100644 index 1e95cc6afe..0000000000 --- a/cpp/include/qmf/engine/Message.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _QmfEngineMessage_ -#define _QmfEngineMessage_ - -/* - * 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 "qpid/sys/IntegerTypes.h" - -namespace qmf { -namespace engine { - - struct Message { - char* body; - uint32_t length; - char* destination; - char* routingKey; - char* replyExchange; - char* replyKey; - char* userId; - }; - -} -} - -#endif diff --git a/cpp/include/qmf/engine/Object.h b/cpp/include/qmf/engine/Object.h deleted file mode 100644 index ad67cfdb95..0000000000 --- a/cpp/include/qmf/engine/Object.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _QmfEngineObject_ -#define _QmfEngineObject_ - -/* - * 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 <qmf/engine/Schema.h> -#include <qmf/engine/ObjectId.h> -#include <qmf/engine/Value.h> - -namespace qmf { -namespace engine { - - struct ObjectImpl; - class Object { - public: - Object(const SchemaObjectClass* type); - Object(const Object& from); - virtual ~Object(); - - void destroy(); - const ObjectId* getObjectId() const; - void setObjectId(ObjectId* oid); - const SchemaObjectClass* getClass() const; - Value* getValue(const char* key) const; - void invokeMethod(const char* methodName, const Value* inArgs, void* context) const; - bool isDeleted() const; - void merge(const Object& from); - - private: - friend struct ObjectImpl; - friend class AgentImpl; - Object(ObjectImpl* impl); - ObjectImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/ObjectId.h b/cpp/include/qmf/engine/ObjectId.h deleted file mode 100644 index 51eb2bc9e7..0000000000 --- a/cpp/include/qmf/engine/ObjectId.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _QmfEngineObjectId_ -#define _QmfEngineObjectId_ - -/* - * 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 <qpid/sys/IntegerTypes.h> - -namespace qmf { -namespace engine { - - // TODO: Add to/from string and << operator - - struct ObjectIdImpl; - class ObjectId { - public: - ObjectId(); - ObjectId(const ObjectId& from); - ~ObjectId(); - - uint64_t getObjectNum() const; - uint32_t getObjectNumHi() const; - uint32_t getObjectNumLo() const; - bool isDurable() const; - const char* str() const; - uint8_t getFlags() const; - uint16_t getSequence() const; - uint32_t getBrokerBank() const; - uint32_t getAgentBank() const; - - bool operator==(const ObjectId& other) const; - bool operator<(const ObjectId& other) const; - bool operator>(const ObjectId& other) const; - bool operator<=(const ObjectId& other) const; - bool operator>=(const ObjectId& other) const; - ObjectId& operator=(const ObjectId &other); - - private: - friend struct ObjectIdImpl; - friend struct ObjectImpl; - friend class BrokerProxyImpl; - friend struct QueryImpl; - friend struct ValueImpl; - friend class AgentImpl; - ObjectId(ObjectIdImpl* impl); - ObjectIdImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/QmfEngineImportExport.h b/cpp/include/qmf/engine/QmfEngineImportExport.h deleted file mode 100644 index cf8fffdb17..0000000000 --- a/cpp/include/qmf/engine/QmfEngineImportExport.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef QMF_ENGINE_IMPORT_EXPORT_H -#define QMF_ENGINE_IMPORT_EXPORT_H - -/* - * 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 defined(WIN32) && !defined(QPID_DECLARE_STATIC) -# if defined(QMF_EXPORT) || defined (qmfengine_EXPORTS) -# define QMFE_EXTERN __declspec(dllexport) -# else -# define QMFE_EXTERN __declspec(dllimport) -# endif -# ifdef _MSC_VER -# define QMFE_CLASS_EXTERN -# define QMFE_INLINE_EXTERN QMFE_EXTERN -# else -# define QMFE_CLASS_EXTERN QMFE_EXTERN -# define QMFE_INLINE_EXTERN -# endif -#else -# define QMFE_EXTERN -# define QMFE_CLASS_EXTERN -# define QMFE_INLINE_EXTERN -#endif - -#endif diff --git a/cpp/include/qmf/engine/Query.h b/cpp/include/qmf/engine/Query.h deleted file mode 100644 index 3ed08c5d8e..0000000000 --- a/cpp/include/qmf/engine/Query.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef _QmfEngineQuery_ -#define _QmfEngineQuery_ - -/* - * 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 <qmf/engine/ObjectId.h> -#include <qmf/engine/Value.h> - -namespace qmf { -namespace engine { - - class Object; - struct QueryElementImpl; - struct QueryImpl; - struct QueryExpressionImpl; - class SchemaClassKey; - - enum ValueOper { - O_EQ = 1, - O_NE = 2, - O_LT = 3, - O_LE = 4, - O_GT = 5, - O_GE = 6, - O_RE_MATCH = 7, - O_RE_NOMATCH = 8, - O_PRESENT = 9, - O_NOT_PRESENT = 10 - }; - - struct QueryOperand { - virtual ~QueryOperand() {} - virtual bool evaluate(const Object* object) const = 0; - }; - - struct QueryElement : public QueryOperand { - QueryElement(const char* attrName, const Value* value, ValueOper oper); - QueryElement(QueryElementImpl* impl); - virtual ~QueryElement(); - bool evaluate(const Object* object) const; - - QueryElementImpl* impl; - }; - - enum ExprOper { - E_NOT = 1, - E_AND = 2, - E_OR = 3, - E_XOR = 4 - }; - - struct QueryExpression : public QueryOperand { - QueryExpression(ExprOper oper, const QueryOperand* operand1, const QueryOperand* operand2); - QueryExpression(QueryExpressionImpl* impl); - virtual ~QueryExpression(); - bool evaluate(const Object* object) const; - - QueryExpressionImpl* impl; - }; - - class Query { - public: - Query(const char* className, const char* packageName); - Query(const SchemaClassKey* key); - Query(const ObjectId* oid); - Query(const Query& from); - ~Query(); - - void setSelect(const QueryOperand* criterion); - void setLimit(uint32_t maxResults); - void setOrderBy(const char* attrName, bool decreasing); - - const char* getPackage() const; - const char* getClass() const; - const ObjectId* getObjectId() const; - - bool haveSelect() const; - bool haveLimit() const; - bool haveOrderBy() const; - const QueryOperand* getSelect() const; - uint32_t getLimit() const; - const char* getOrderBy() const; - bool getDecreasing() const; - - private: - friend struct QueryImpl; - friend class BrokerProxyImpl; - Query(QueryImpl* impl); - QueryImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/ResilientConnection.h b/cpp/include/qmf/engine/ResilientConnection.h deleted file mode 100644 index c03d08cb96..0000000000 --- a/cpp/include/qmf/engine/ResilientConnection.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef _QmfEngineResilientConnection_ -#define _QmfEngineResilientConnection_ - -/* - * 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 <qmf/engine/Message.h> -#include <qmf/engine/ConnectionSettings.h> -#include <string> - -namespace qmf { -namespace engine { - - class ResilientConnectionImpl; - - /** - * Represents events that occur, unsolicited, from ResilientConnection. - */ - struct ResilientConnectionEvent { - enum EventKind { - CONNECTED = 1, - DISCONNECTED = 2, - SESSION_CLOSED = 3, - RECV = 4 - }; - - EventKind kind; - void* sessionContext; // SESSION_CLOSED, RECV - char* errorText; // DISCONNECTED, SESSION_CLOSED - Message message; // RECV - }; - - class SessionHandle { - friend class ResilientConnectionImpl; - void* impl; - }; - - /** - * ResilientConnection represents a Qpid connection that is resilient. - * - * Upon creation, ResilientConnection attempts to establish a connection to the - * messaging broker. If it fails, it will continue to retry at an interval that - * increases over time (to a maximum interval). If an extablished connection is - * dropped, a reconnect will be attempted. - */ - class ResilientConnection { - public: - - /** - * Create a new resilient connection. - *@param settings Settings that define how the connection is to be made. - *@param delayMin Minimum delay (in seconds) between retries. - *@param delayMax Maximum delay (in seconds) between retries. - *@param delayFactor Factor to multiply retry delay by after each failure. - */ - ResilientConnection(const ConnectionSettings& settings); - ~ResilientConnection(); - - /** - * Get the connected status of the resilient connection. - *@return true iff the connection is established. - */ - bool isConnected() const; - - /** - * Get the next event (if present) from the connection. - *@param event Returned event if one is available. - *@return true if event is valid, false if there are no more events to handle. - */ - bool getEvent(ResilientConnectionEvent& event); - - /** - * Discard the event on the front of the queue. This should be invoked after processing - * the event from getEvent. - */ - void popEvent(); - - /** - * Create a new AMQP session. - *@param name Unique name for the session. - *@param sessionContext Optional user-context value that will be provided in events - * pertaining to this session. - *@param handle Output handle to be stored and used in subsequent calls pertaining to - * this session. - *@return true iff the session was successfully created. - */ - bool createSession(const char* name, void* sessionContext, SessionHandle& handle); - - /** - * Destroy a created session. - *@param handle SessionHandle returned by createSession. - */ - void destroySession(SessionHandle handle); - - /** - * Send a message into the AMQP broker via a session. - *@param handle The session handle of the session to transmit through. - *@param message The QMF message to transmit. - */ - void sendMessage(SessionHandle handle, Message& message); - - /** - * Declare an exclusive, auto-delete queue for a session. - *@param handle The session handle for the owner of the queue. - *@param queue The name of the queue. - */ - void declareQueue(SessionHandle handle, char* queue); - - /** - * Delete a queue. - *@param handle The session handle for the owner of the queue. - *@param queue The name of the queue. - */ - void deleteQueue(SessionHandle handle, char* queue); - - /** - * Bind a queue to an exchange. - *@param handle The session handle of the session to use for binding. - *@param exchange The name of the exchange for binding. - *@param queue The name of the queue for binding. - *@param key The binding key. - */ - void bind(SessionHandle handle, char* exchange, char* queue, char* key); - - /** - * Remove a binding. - *@param handle The session handle of the session to use for un-binding. - *@param exchange The name of the exchange. - *@param queue The name of the queue. - *@param key The binding key. - */ - void unbind(SessionHandle handle, char* exchange, char* queue, char* key); - - /** - * Establish a file descriptor for event notification. - *@param fd A file descriptor into which the connection shall write a character each - * time an event is enqueued. This fd may be in a pair, the other fd of which - * is used in a select loop to control execution. - */ - void setNotifyFd(int fd); - - /** - * Send a byte into the notify file descriptor. - * - * This can be used to wake up the event processing portion of the engine from either the - * wrapped implementation or the engine itself. - */ - void notify(); - - private: - ResilientConnectionImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/Schema.h b/cpp/include/qmf/engine/Schema.h deleted file mode 100644 index f53e84324a..0000000000 --- a/cpp/include/qmf/engine/Schema.h +++ /dev/null @@ -1,212 +0,0 @@ -#ifndef _QmfEngineSchema_ -#define _QmfEngineSchema_ - -/* - * 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 <qmf/engine/Typecode.h> -#include <qpid/sys/IntegerTypes.h> - -namespace qmf { -namespace engine { - - enum Access { ACCESS_READ_CREATE = 1, ACCESS_READ_WRITE = 2, ACCESS_READ_ONLY = 3 }; - enum Direction { DIR_IN = 1, DIR_OUT = 2, DIR_IN_OUT = 3 }; - enum ClassKind { CLASS_OBJECT = 1, CLASS_EVENT = 2 }; - enum Severity { SEV_EMERG = 0, SEV_ALERT = 1, SEV_CRIT = 2, SEV_ERROR = 3, SEV_WARN = 4, SEV_NOTICE = 5, SEV_INFORM = 6, SEV_DEBUG = 7 }; - - struct SchemaArgumentImpl; - struct SchemaMethodImpl; - struct SchemaPropertyImpl; - struct SchemaStatisticImpl; - struct SchemaObjectClassImpl; - struct SchemaEventClassImpl; - struct SchemaClassKeyImpl; - - /** - */ - class SchemaArgument { - public: - SchemaArgument(const char* name, Typecode typecode); - SchemaArgument(const SchemaArgument& from); - ~SchemaArgument(); - void setDirection(Direction dir); - void setUnit(const char* val); - void setDesc(const char* desc); - const char* getName() const; - Typecode getType() const; - Direction getDirection() const; - const char* getUnit() const; - const char* getDesc() const; - - private: - friend struct SchemaArgumentImpl; - friend struct SchemaMethodImpl; - friend struct SchemaEventClassImpl; - SchemaArgument(SchemaArgumentImpl* impl); - SchemaArgumentImpl* impl; - }; - - /** - */ - class SchemaMethod { - public: - SchemaMethod(const char* name); - SchemaMethod(const SchemaMethod& from); - ~SchemaMethod(); - void addArgument(const SchemaArgument* argument); - void setDesc(const char* desc); - const char* getName() const; - const char* getDesc() const; - int getArgumentCount() const; - const SchemaArgument* getArgument(int idx) const; - - private: - friend struct SchemaMethodImpl; - friend struct SchemaObjectClassImpl; - friend class AgentImpl; - SchemaMethod(SchemaMethodImpl* impl); - SchemaMethodImpl* impl; - }; - - /** - */ - class SchemaProperty { - public: - SchemaProperty(const char* name, Typecode typecode); - SchemaProperty(const SchemaProperty& from); - ~SchemaProperty(); - void setAccess(Access access); - void setIndex(bool val); - void setOptional(bool val); - void setUnit(const char* val); - void setDesc(const char* desc); - const char* getName() const; - Typecode getType() const; - Access getAccess() const; - bool isIndex() const; - bool isOptional() const; - const char* getUnit() const; - const char* getDesc() const; - - private: - friend struct SchemaPropertyImpl; - friend struct SchemaObjectClassImpl; - SchemaProperty(SchemaPropertyImpl* impl); - SchemaPropertyImpl* impl; - }; - - /** - */ - class SchemaStatistic { - public: - SchemaStatistic(const char* name, Typecode typecode); - SchemaStatistic(const SchemaStatistic& from); - ~SchemaStatistic(); - void setUnit(const char* val); - void setDesc(const char* desc); - const char* getName() const; - Typecode getType() const; - const char* getUnit() const; - const char* getDesc() const; - - private: - friend struct SchemaStatisticImpl; - friend struct SchemaObjectClassImpl; - SchemaStatistic(SchemaStatisticImpl* impl); - SchemaStatisticImpl* impl; - }; - - /** - */ - class SchemaClassKey { - public: - SchemaClassKey(const SchemaClassKey& from); - ~SchemaClassKey(); - - const char* getPackageName() const; - const char* getClassName() const; - const uint8_t* getHash() const; - const char* asString() const; - - bool operator==(const SchemaClassKey& other) const; - bool operator<(const SchemaClassKey& other) const; - - private: - friend struct SchemaClassKeyImpl; - friend class BrokerProxyImpl; - friend class ConsoleImpl; - SchemaClassKey(SchemaClassKeyImpl* impl); - SchemaClassKeyImpl* impl; - }; - - /** - */ - class SchemaObjectClass { - public: - SchemaObjectClass(const char* package, const char* name); - SchemaObjectClass(const SchemaObjectClass& from); - ~SchemaObjectClass(); - void addProperty(const SchemaProperty* property); - void addStatistic(const SchemaStatistic* statistic); - void addMethod(const SchemaMethod* method); - - const SchemaClassKey* getClassKey() const; - int getPropertyCount() const; - int getStatisticCount() const; - int getMethodCount() const; - const SchemaProperty* getProperty(int idx) const; - const SchemaStatistic* getStatistic(int idx) const; - const SchemaMethod* getMethod(int idx) const; - - private: - friend struct SchemaObjectClassImpl; - friend class BrokerProxyImpl; - friend class AgentImpl; - SchemaObjectClass(SchemaObjectClassImpl* impl); - SchemaObjectClassImpl* impl; - }; - - /** - */ - class SchemaEventClass { - public: - SchemaEventClass(const char* package, const char* name, Severity severity); - SchemaEventClass(const SchemaEventClass& from); - ~SchemaEventClass(); - void addArgument(const SchemaArgument* argument); - void setDesc(const char* desc); - - const SchemaClassKey* getClassKey() const; - Severity getSeverity() const; - int getArgumentCount() const; - const SchemaArgument* getArgument(int idx) const; - - private: - friend struct SchemaEventClassImpl; - friend class BrokerProxyImpl; - friend class AgentImpl; - SchemaEventClass(SchemaEventClassImpl* impl); - SchemaEventClassImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/Typecode.h b/cpp/include/qmf/engine/Typecode.h deleted file mode 100644 index 613f96a483..0000000000 --- a/cpp/include/qmf/engine/Typecode.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _QmfEngineTypecode_ -#define _QmfEngineTypecode_ - -/* - * 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. - */ - -namespace qmf { -namespace engine { - - enum Typecode { - TYPE_UINT8 = 1, - TYPE_UINT16 = 2, - TYPE_UINT32 = 3, - TYPE_UINT64 = 4, - TYPE_SSTR = 6, - TYPE_LSTR = 7, - TYPE_ABSTIME = 8, - TYPE_DELTATIME = 9, - TYPE_REF = 10, - TYPE_BOOL = 11, - TYPE_FLOAT = 12, - TYPE_DOUBLE = 13, - TYPE_UUID = 14, - TYPE_MAP = 15, - TYPE_INT8 = 16, - TYPE_INT16 = 17, - TYPE_INT32 = 18, - TYPE_INT64 = 19, - TYPE_OBJECT = 20, - TYPE_LIST = 21, - TYPE_ARRAY = 22 - }; -} -} - -#endif - diff --git a/cpp/include/qmf/engine/Value.h b/cpp/include/qmf/engine/Value.h deleted file mode 100644 index 5b45061b78..0000000000 --- a/cpp/include/qmf/engine/Value.h +++ /dev/null @@ -1,122 +0,0 @@ -#ifndef _QmfEngineValue_ -#define _QmfEngineValue_ - -/* - * 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 <qmf/engine/ObjectId.h> -#include <qmf/engine/Typecode.h> - -namespace qmf { -namespace engine { - - class Object; - struct ValueImpl; - - class Value { - public: - // Value(); - Value(const Value& from); - Value(Typecode t, Typecode arrayType = TYPE_UINT8); - ~Value(); - - Typecode getType() const; - bool isNull() const; - void setNull(); - - bool isObjectId() const; - const ObjectId& asObjectId() const; - void setObjectId(const ObjectId& oid); - - bool isUint() const; - uint32_t asUint() const; - void setUint(uint32_t val); - - bool isInt() const; - int32_t asInt() const; - void setInt(int32_t val); - - bool isUint64() const; - uint64_t asUint64() const; - void setUint64(uint64_t val); - - bool isInt64() const; - int64_t asInt64() const; - void setInt64(int64_t val); - - bool isString() const; - const char* asString() const; - void setString(const char* val); - - bool isBool() const; - bool asBool() const; - void setBool(bool val); - - bool isFloat() const; - float asFloat() const; - void setFloat(float val); - - bool isDouble() const; - double asDouble() const; - void setDouble(double val); - - bool isUuid() const; - const uint8_t* asUuid() const; - void setUuid(const uint8_t* val); - - bool isObject() const; - const Object* asObject() const; - void setObject(Object* val); - - bool isMap() const; - bool keyInMap(const char* key) const; - Value* byKey(const char* key); - const Value* byKey(const char* key) const; - void deleteKey(const char* key); - void insert(const char* key, Value* val); - uint32_t keyCount() const; - const char* key(uint32_t idx) const; - - bool isList() const; - uint32_t listItemCount() const; - Value* listItem(uint32_t idx); - void appendToList(Value* val); - void deleteListItem(uint32_t idx); - - bool isArray() const; - Typecode arrayType() const; - uint32_t arrayItemCount() const; - Value* arrayItem(uint32_t idx); - void appendToArray(Value* val); - void deleteArrayItem(uint32_t idx); - - private: - friend struct ValueImpl; - friend class BrokerProxyImpl; - friend struct ObjectImpl; - friend struct EventImpl; - friend class AgentImpl; - Value(ValueImpl* impl); - ValueImpl* impl; - }; -} -} - -#endif - diff --git a/cpp/include/qmf/qmfengine.i b/cpp/include/qmf/qmfengine.i deleted file mode 100644 index eb350115a3..0000000000 --- a/cpp/include/qmf/qmfengine.i +++ /dev/null @@ -1,59 +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 "qmf/engine/Agent.h" -#include "qmf/engine/Console.h" -#include "qmf/engine/ResilientConnection.h" - -%} - -%include <qmf/engine/QmfEngineImportExport.h> -%include <qmf/engine/Query.h> -%include <qmf/engine/Message.h> -%include <qmf/engine/Agent.h> -%include <qmf/engine/Console.h> -%include <qmf/engine/ConnectionSettings.h> -%include <qmf/engine/ResilientConnection.h> -%include <qmf/engine/Typecode.h> -%include <qmf/engine/Schema.h> -%include <qmf/engine/Value.h> -%include <qmf/engine/ObjectId.h> -%include <qmf/engine/Object.h> -%include <qmf/engine/Event.h> - - -%inline { - -using namespace std; -using namespace qmf::engine; - -namespace qmf { -namespace engine { - -} -} -} - - -%{ - -%}; - diff --git a/cpp/include/qpid/agent/ManagementAgent.h b/cpp/include/qpid/agent/ManagementAgent.h deleted file mode 100644 index 10bc6527a9..0000000000 --- a/cpp/include/qpid/agent/ManagementAgent.h +++ /dev/null @@ -1,205 +0,0 @@ -#ifndef _qpid_agent_ManagementAgent_ -#define _qpid_agent_ManagementAgent_ - -// -// 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 "qpid/agent/QmfAgentImportExport.h" -#include "qpid/management/ManagementObject.h" -#include "qpid/management/ManagementEvent.h" -#include "qpid/management/Manageable.h" -#include "qpid/management/ConnectionSettings.h" - -namespace qpid { -namespace management { - -class Notifyable { -public: - virtual ~Notifyable() {} - virtual void notify() = 0; -}; - -class ManagementAgent -{ - public: - - class Singleton { - public: - QMF_AGENT_EXTERN Singleton(bool disableManagement = false); - QMF_AGENT_EXTERN ~Singleton(); - QMF_AGENT_EXTERN static ManagementAgent* getInstance(); - }; - - typedef enum { - SEV_EMERG = 0, - SEV_ALERT = 1, - SEV_CRIT = 2, - SEV_ERROR = 3, - SEV_WARN = 4, - SEV_NOTE = 5, - SEV_INFO = 6, - SEV_DEBUG = 7, - SEV_DEFAULT = 8 - } severity_t; - - ManagementAgent() {} - virtual ~ManagementAgent() {} - - virtual int getMaxThreads() = 0; - - // Set the name of the agent - // - // vendor - Vendor name or domain (i.e. "apache.org") - // product - Product name (i.e. "qpid") - // instance - A unique identifier for this instance of the agent. - // If empty, the agent will create a GUID for the instance. - // Note: the ":" character is reserved - do no use it in the vendor or product name. - // - virtual void setName(const std::string& vendor, - const std::string& product, - const std::string& instance="") = 0; - - // Retrieve the name of the agent as assigned by setName() - // - virtual void getName(std::string& vendor, - std::string& product, - std::string& instance) = 0; - - // Obtain the fully qualified name of the agent - // - virtual const std::string& getAddress() = 0; - - // Connect to a management broker - // - // brokerHost - Hostname or IP address (dotted-quad) of broker. - // - // brokerPort - TCP port of broker. - // - // intervalSeconds - The interval (in seconds) that this agent shall use - // between broadcast updates to the broker. - // - // useExternalThread - If true, the thread of control used for callbacks - // must be supplied by the user of the object (via the - // pollCallbacks method). - // - // If false, callbacks shall be invoked on the management - // agent's thread. In this case, the callback implementations - // MUST be thread safe. - // - // storeFile - File where this process has read and write access. This - // file shall be used to store persistent state. - // - virtual void init(const std::string& brokerHost = "localhost", - uint16_t brokerPort = 5672, - uint16_t intervalSeconds = 10, - bool useExternalThread = false, - const std::string& storeFile = "", - const std::string& uid = "", - const std::string& pwd = "", - const std::string& mech = "PLAIN", - const std::string& proto = "tcp") = 0; - - virtual void init(const management::ConnectionSettings& settings, - uint16_t intervalSeconds = 10, - bool useExternalThread = false, - const std::string& storeFile = "") = 0; - - - // Register a schema with the management agent. This is normally called by the - // package initializer generated by the management code generator. - // - virtual void - registerClass(const std::string& packageName, - const std::string& className, - uint8_t* md5Sum, - management::ManagementObject::writeSchemaCall_t schemaCall) = 0; - - virtual void - registerEvent(const std::string& packageName, - const std::string& eventName, - uint8_t* md5Sum, - management::ManagementEvent::writeSchemaCall_t schemaCall) = 0; - - // Add a management object to the agent. Once added, this object shall be visible - // in the greater management context. - // - // Please note that ManagementObject instances are not explicitly deleted from - // the management agent. When the core object represented by a management object - // is deleted, the "resourceDestroy" method on the management object must be called. - // It will then be reclaimed in due course by the management agent. - // - // Once a ManagementObject instance is added to the agent, the agent then owns the - // instance. The caller MUST NOT free the resources of the instance at any time. - // When it is no longer needed, invoke its "resourceDestroy" method and discard the - // pointer. This allows the management agent to report the deletion of the object - // in an orderly way. - // - virtual ObjectId addObject(ManagementObject* objectPtr, uint64_t persistId = 0) = 0; - virtual ObjectId addObject(ManagementObject* objectPtr, - const std::string& key, - bool persistent = true) = 0; - - // - // - virtual void raiseEvent(const ManagementEvent& event, - severity_t severity = SEV_DEFAULT) = 0; - - // If "useExternalThread" was set to true in init, this method must - // be called to provide a thread for any pending method calls that have arrived. - // The method calls for ManagementObject instances shall be invoked synchronously - // during the execution of this method. - // - // callLimit may optionally be used to limit the number of callbacks invoked. - // if 0, no limit is imposed. - // - // The return value is the number of callbacks that remain queued after this - // call is complete. It can be used to determine whether or not further calls - // to pollCallbacks are necessary to clear the backlog. If callLimit is zero, - // the return value will also be zero. - // - virtual uint32_t pollCallbacks(uint32_t callLimit = 0) = 0; - - // In the "useExternalThread" scenario, there are three ways that an application can - // use to be notified that there is work to do. Of course the application may periodically - // call pollCallbacks if it wishes, but this will cause long latencies in the responses - // to method calls. - // - // The notification methods are: - // - // 1) Register a C-style callback by providing a pointer to a function - // 2) Register a C++-style callback by providing an object of a class that is derived - // from Notifyable - // 3) Call getSignalFd() to get a file descriptor that can be used in a select - // call. The file descriptor shall become readable when the agent has work to - // do. Note that this mechanism is specific to Posix-based operating environments. - // getSignalFd will probably not function correctly on Windows. - // - // If a callback is registered, the callback function will be called on the agent's - // thread. The callback function must perform no work other than to signal the application - // thread to call pollCallbacks. - // - typedef void (*cb_t)(void*); - virtual void setSignalCallback(cb_t callback, void* context) = 0; - virtual void setSignalCallback(Notifyable& notifyable) = 0; - virtual int getSignalFd() = 0; -}; - -}} - -#endif /*!_qpid_agent_ManagementAgent_*/ diff --git a/cpp/include/qpid/agent/QmfAgentImportExport.h b/cpp/include/qpid/agent/QmfAgentImportExport.h deleted file mode 100644 index 3f923ac4b2..0000000000 --- a/cpp/include/qpid/agent/QmfAgentImportExport.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef QMF_AGENT_IMPORT_EXPORT_H -#define QMF_AGENT_IMPORT_EXPORT_H - -/* - * 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 "qpid/ImportExport.h" - -#if defined(QMF_EXPORT) || defined (qmf_EXPORTS) -# define QMF_AGENT_EXTERN QPID_EXPORT -# define QMF_AGENT_CLASS_EXTERN QPID_CLASS_EXPORT -# define QMF_AGENT_INLINE_EXTERN QPID_INLINE_EXPORT -#else -# define QMF_AGENT_EXTERN QPID_IMPORT -# define QMF_AGENT_CLASS_EXTERN QPID_CLASS_IMPORT -# define QMF_AGENT_INLINE_EXTERN QPID_INLINE_IMPORT -#endif - -#endif diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index c1d16404ef..5d5dd034b1 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -1373,30 +1373,6 @@ if (UNIX) install (CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}/${QPID_LOCALSTATE_DIR}/spool/qpidd)") endif (UNIX) -set (qmf_SOURCES - qpid/agent/ManagementAgentImpl.cpp - qpid/agent/ManagementAgentImpl.h - ) -set (qmf_HEADERS - ../include/qpid/agent/ManagementAgent.h - ../include/qpid/agent/QmfAgentImportExport.h - ../include/qmf/BrokerImportExport.h - ) - -add_msvc_version (qmf library dll) -add_library (qmf SHARED ${qmf_SOURCES}) -target_link_libraries (qmf qmfengine) -set_target_properties (qmf PROPERTIES - VERSION ${qmf_version} - SOVERSION ${qmf_version_major}) -install (TARGETS qmf OPTIONAL - DESTINATION ${QPID_INSTALL_LIBDIR} - COMPONENT ${QPID_COMPONENT_QMF}) -install (FILES ${qmf_HEADERS} - DESTINATION ${QPID_INSTALL_INCLUDEDIR}/qpid/agent - COMPONENT ${QPID_COMPONENT_QMF}) -install_pdb (qmf ${QPID_COMPONENT_QMF}) - if (NOT WIN32) set (qmf2_platform_headers ../include/qmf/posix/EventNotifier.h @@ -1487,68 +1463,6 @@ endif (NOT WIN32) COMPONENT ${QPID_COMPONENT_QMF}) install_pdb (qmf2 ${QPID_COMPONENT_QMF}) -set (qmfengine_SOURCES - qmf/engine/Agent.cpp - qmf/engine/BrokerProxyImpl.cpp - qmf/engine/BrokerProxyImpl.h - qmf/engine/ConnectionSettingsImpl.cpp - qmf/engine/ConnectionSettingsImpl.h - qmf/engine/ConsoleImpl.cpp - qmf/engine/ConsoleImpl.h - qmf/engine/EventImpl.cpp - qmf/engine/EventImpl.h - qmf/engine/MessageImpl.cpp - qmf/engine/MessageImpl.h - qmf/engine/ObjectIdImpl.cpp - qmf/engine/ObjectIdImpl.h - qmf/engine/ObjectImpl.cpp - qmf/engine/ObjectImpl.h - qmf/engine/Protocol.cpp - qmf/engine/Protocol.h - qmf/engine/QueryImpl.cpp - qmf/engine/QueryImpl.h - qmf/engine/SequenceManager.cpp - qmf/engine/SequenceManager.h - qmf/engine/SchemaImpl.cpp - qmf/engine/SchemaImpl.h - qmf/engine/ValueImpl.cpp - qmf/engine/ValueImpl.h - ) - -set (qmfengine_HEADERS - ../include/qmf/engine/Agent.h - ../include/qmf/engine/ConnectionSettings.h - ../include/qmf/engine/Console.h - ../include/qmf/engine/Event.h - ../include/qmf/engine/Message.h - ../include/qmf/engine/Object.h - ../include/qmf/engine/ObjectId.h - ../include/qmf/engine/QmfEngineImportExport.h - ../include/qmf/engine/Query.h - ../include/qmf/engine/ResilientConnection.h - ../include/qmf/engine/Schema.h - ../include/qmf/engine/Typecode.h - ../include/qmf/engine/Value.h - ) -install (FILES ${qmfengine_HEADERS} - DESTINATION ${QPID_INSTALL_INCLUDEDIR}/qmf/engine - COMPONENT ${QPID_COMPONENT_QMF}) - -if (NOT WIN32) - list(APPEND qmfengine_SOURCES qmf/engine/ResilientConnection.cpp) -endif (NOT WIN32) -add_msvc_version (qmfengine library dll) - -add_library (qmfengine SHARED ${qmfengine_SOURCES}) -target_link_libraries (qmfengine qpidclient) -set_target_properties (qmfengine PROPERTIES - VERSION ${qmfengine_version} - SOVERSION ${qmfengine_version_major}) -install (TARGETS qmfengine OPTIONAL - DESTINATION ${QPID_INSTALL_LIBDIR} - COMPONENT ${QPID_COMPONENT_QMF}) -install_pdb (qmfengine ${QPID_COMPONENT_QMF}) - set (qmfconsole_SOURCES qpid/console/Agent.cpp qpid/console/Broker.cpp diff --git a/cpp/src/qmf/engine/Agent.cpp b/cpp/src/qmf/engine/Agent.cpp deleted file mode 100644 index 1f08dded94..0000000000 --- a/cpp/src/qmf/engine/Agent.cpp +++ /dev/null @@ -1,915 +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 "qmf/engine/Agent.h" -#include "qmf/engine/MessageImpl.h" -#include "qmf/engine/SchemaImpl.h" -#include "qmf/engine/Typecode.h" -#include "qmf/engine/EventImpl.h" -#include "qmf/engine/ObjectImpl.h" -#include "qmf/engine/ObjectIdImpl.h" -#include "qmf/engine/QueryImpl.h" -#include "qmf/engine/ValueImpl.h" -#include "qmf/engine/Protocol.h" -#include <qpid/framing/Buffer.h> -#include <qpid/framing/Uuid.h> -#include <qpid/framing/FieldTable.h> -#include <qpid/framing/FieldValue.h> -#include <qpid/sys/Mutex.h> -#include <qpid/log/Statement.h> -#include <qpid/sys/Time.h> -#include <string.h> -#include <string> -#include <deque> -#include <map> -#include <iostream> -#include <fstream> -#include <boost/shared_ptr.hpp> -#include <boost/noncopyable.hpp> - -using namespace std; -using namespace qmf::engine; -using namespace qpid::framing; -using namespace qpid::sys; - -namespace qmf { -namespace engine { - - struct AgentEventImpl { - typedef boost::shared_ptr<AgentEventImpl> Ptr; - AgentEvent::EventKind kind; - uint32_t sequence; - string authUserId; - string authToken; - string name; - Object* object; - boost::shared_ptr<ObjectId> objectId; - boost::shared_ptr<Query> query; - boost::shared_ptr<Value> arguments; - string exchange; - string bindingKey; - const SchemaObjectClass* objectClass; - - AgentEventImpl(AgentEvent::EventKind k) : - kind(k), sequence(0), object(0), objectClass(0) {} - ~AgentEventImpl() {} - AgentEvent copy(); - }; - - struct AgentQueryContext { - typedef boost::shared_ptr<AgentQueryContext> Ptr; - uint32_t sequence; - string exchange; - string key; - const SchemaMethod* schemaMethod; - AgentQueryContext() : schemaMethod(0) {} - }; - - class AgentImpl : public boost::noncopyable { - public: - AgentImpl(char* label, bool internalStore); - ~AgentImpl(); - - void setStoreDir(const char* path); - void setTransferDir(const char* path); - void handleRcvMessage(Message& message); - bool getXmtMessage(Message& item) const; - void popXmt(); - bool getEvent(AgentEvent& event) const; - void popEvent(); - void newSession(); - void startProtocol(); - void heartbeat(); - void methodResponse(uint32_t sequence, uint32_t status, char* text, const Value& arguments); - void queryResponse(uint32_t sequence, Object& object, bool prop, bool stat); - void queryComplete(uint32_t sequence); - void registerClass(SchemaObjectClass* cls); - void registerClass(SchemaEventClass* cls); - const ObjectId* addObject(Object& obj, uint64_t persistId); - const ObjectId* allocObjectId(uint64_t persistId); - const ObjectId* allocObjectId(uint32_t persistIdLo, uint32_t persistIdHi); - void raiseEvent(Event& event); - - private: - mutable Mutex lock; - Mutex addLock; - string label; - string queueName; - string storeDir; - string transferDir; - bool internalStore; - uint64_t nextTransientId; - Uuid systemId; - uint32_t requestedBrokerBank; - uint32_t requestedAgentBank; - uint32_t assignedBrokerBank; - uint32_t assignedAgentBank; - AgentAttachment attachment; - uint16_t bootSequence; - uint64_t nextObjectId; - uint32_t nextContextNum; - deque<AgentEventImpl::Ptr> eventQueue; - deque<MessageImpl::Ptr> xmtQueue; - map<uint32_t, AgentQueryContext::Ptr> contextMap; - bool attachComplete; - - static const char* QMF_EXCHANGE; - static const char* DIR_EXCHANGE; - static const char* BROKER_KEY; - static const uint32_t MERR_UNKNOWN_METHOD = 2; - static const uint32_t MERR_UNKNOWN_PACKAGE = 8; - static const uint32_t MERR_UNKNOWN_CLASS = 9; - static const uint32_t MERR_INTERNAL_ERROR = 10; -# define MA_BUFFER_SIZE 65536 - char outputBuffer[MA_BUFFER_SIZE]; - - struct AgentClassKey { - string name; - uint8_t hash[16]; - AgentClassKey(const string& n, const uint8_t* h) : name(n) { - memcpy(hash, h, 16); - } - AgentClassKey(Buffer& buffer) { - buffer.getShortString(name); - buffer.getBin128(hash); - } - string repr() { - return name; - } - }; - - struct AgentClassKeyComp { - bool operator() (const AgentClassKey& lhs, const AgentClassKey& rhs) const - { - if (lhs.name != rhs.name) - return lhs.name < rhs.name; - else - for (int i = 0; i < 16; i++) - if (lhs.hash[i] != rhs.hash[i]) - return lhs.hash[i] < rhs.hash[i]; - return false; - } - }; - - typedef map<AgentClassKey, SchemaObjectClass*, AgentClassKeyComp> ObjectClassMap; - typedef map<AgentClassKey, SchemaEventClass*, AgentClassKeyComp> EventClassMap; - - struct ClassMaps { - ObjectClassMap objectClasses; - EventClassMap eventClasses; - }; - - map<string, ClassMaps> packages; - - AgentEventImpl::Ptr eventDeclareQueue(const string& queueName); - AgentEventImpl::Ptr eventBind(const string& exchange, const string& queue, const string& key); - AgentEventImpl::Ptr eventSetupComplete(); - AgentEventImpl::Ptr eventQuery(uint32_t num, const string& userId, const string& package, const string& cls, - boost::shared_ptr<ObjectId> oid); - AgentEventImpl::Ptr eventMethod(uint32_t num, const string& userId, const string& method, - boost::shared_ptr<ObjectId> oid, boost::shared_ptr<Value> argMap, - const SchemaObjectClass* objectClass); - void sendBufferLH(Buffer& buf, const string& destination, const string& routingKey); - - void sendPackageIndicationLH(const string& packageName); - void sendClassIndicationLH(ClassKind kind, const string& packageName, const AgentClassKey& key); - void sendCommandCompleteLH(const string& exchange, const string& key, uint32_t seq, - uint32_t code = 0, const string& text = "OK"); - void sendMethodErrorLH(uint32_t sequence, const string& key, uint32_t code, const string& text=""); - void handleAttachResponse(Buffer& inBuffer); - void handlePackageRequest(Buffer& inBuffer); - void handleClassQuery(Buffer& inBuffer); - void handleSchemaRequest(Buffer& inBuffer, uint32_t sequence, - const string& replyToExchange, const string& replyToKey); - void handleGetQuery(Buffer& inBuffer, uint32_t sequence, const string& replyTo, const string& userId); - void handleMethodRequest(Buffer& inBuffer, uint32_t sequence, const string& replyTo, const string& userId); - void handleConsoleAddedIndication(); - }; -} -} - -const char* AgentImpl::QMF_EXCHANGE = "qpid.management"; -const char* AgentImpl::DIR_EXCHANGE = "amq.direct"; -const char* AgentImpl::BROKER_KEY = "broker"; - -#define STRING_REF(s) {if (!s.empty()) item.s = const_cast<char*>(s.c_str());} - -AgentEvent AgentEventImpl::copy() -{ - AgentEvent item; - - ::memset(&item, 0, sizeof(AgentEvent)); - item.kind = kind; - item.sequence = sequence; - item.object = object; - item.objectId = objectId.get(); - item.query = query.get(); - item.arguments = arguments.get(); - item.objectClass = objectClass; - - STRING_REF(authUserId); - STRING_REF(authToken); - STRING_REF(name); - STRING_REF(exchange); - STRING_REF(bindingKey); - - return item; -} - -AgentImpl::AgentImpl(char* _label, bool i) : - label(_label), queueName("qmfa-"), internalStore(i), nextTransientId(1), - requestedBrokerBank(0), requestedAgentBank(0), - assignedBrokerBank(0), assignedAgentBank(0), - bootSequence(1), nextObjectId(1), nextContextNum(1), attachComplete(false) -{ - queueName += Uuid(true).str(); -} - -AgentImpl::~AgentImpl() -{ -} - -void AgentImpl::setStoreDir(const char* path) -{ - Mutex::ScopedLock _lock(lock); - if (path) - storeDir = path; - else - storeDir.clear(); -} - -void AgentImpl::setTransferDir(const char* path) -{ - Mutex::ScopedLock _lock(lock); - if (path) - transferDir = path; - else - transferDir.clear(); -} - -void AgentImpl::handleRcvMessage(Message& message) -{ - Buffer inBuffer(message.body, message.length); - uint8_t opcode; - uint32_t sequence; - string replyToExchange(message.replyExchange ? message.replyExchange : ""); - string replyToKey(message.replyKey ? message.replyKey : ""); - string userId(message.userId ? message.userId : ""); - - while (Protocol::checkHeader(inBuffer, &opcode, &sequence)) { - if (opcode == Protocol::OP_ATTACH_RESPONSE) handleAttachResponse(inBuffer); - else if (opcode == Protocol::OP_SCHEMA_REQUEST) handleSchemaRequest(inBuffer, sequence, replyToExchange, replyToKey); - else if (opcode == Protocol::OP_CONSOLE_ADDED_INDICATION) handleConsoleAddedIndication(); - else if (opcode == Protocol::OP_GET_QUERY) handleGetQuery(inBuffer, sequence, replyToKey, userId); - else if (opcode == Protocol::OP_METHOD_REQUEST) handleMethodRequest(inBuffer, sequence, replyToKey, userId); - else { - QPID_LOG(error, "AgentImpl::handleRcvMessage invalid opcode=" << opcode); - break; - } - } -} - -bool AgentImpl::getXmtMessage(Message& item) const -{ - Mutex::ScopedLock _lock(lock); - if (xmtQueue.empty()) - return false; - item = xmtQueue.front()->copy(); - return true; -} - -void AgentImpl::popXmt() -{ - Mutex::ScopedLock _lock(lock); - if (!xmtQueue.empty()) - xmtQueue.pop_front(); -} - -bool AgentImpl::getEvent(AgentEvent& event) const -{ - Mutex::ScopedLock _lock(lock); - if (eventQueue.empty()) - return false; - event = eventQueue.front()->copy(); - return true; -} - -void AgentImpl::popEvent() -{ - Mutex::ScopedLock _lock(lock); - if (!eventQueue.empty()) - eventQueue.pop_front(); -} - -void AgentImpl::newSession() -{ - Mutex::ScopedLock _lock(lock); - eventQueue.clear(); - xmtQueue.clear(); - eventQueue.push_back(eventDeclareQueue(queueName)); - eventQueue.push_back(eventBind("amq.direct", queueName, queueName)); - eventQueue.push_back(eventSetupComplete()); -} - -void AgentImpl::startProtocol() -{ - Mutex::ScopedLock _lock(lock); - char rawbuffer[512]; - Buffer buffer(rawbuffer, 512); - - Protocol::encodeHeader(buffer, Protocol::OP_ATTACH_REQUEST); - buffer.putShortString(label); - systemId.encode(buffer); - buffer.putLong(requestedBrokerBank); - buffer.putLong(requestedAgentBank); - sendBufferLH(buffer, QMF_EXCHANGE, BROKER_KEY); - QPID_LOG(trace, "SENT AttachRequest: reqBroker=" << requestedBrokerBank << - " reqAgent=" << requestedAgentBank); -} - -void AgentImpl::heartbeat() -{ - Mutex::ScopedLock _lock(lock); - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - - Protocol::encodeHeader(buffer, Protocol::OP_HEARTBEAT_INDICATION); - buffer.putLongLong(uint64_t(Duration(EPOCH, now()))); - stringstream key; - key << "console.heartbeat." << assignedBrokerBank << "." << assignedAgentBank; - sendBufferLH(buffer, QMF_EXCHANGE, key.str()); - QPID_LOG(trace, "SENT HeartbeatIndication"); -} - -void AgentImpl::methodResponse(uint32_t sequence, uint32_t status, char* text, const Value& argMap) -{ - Mutex::ScopedLock _lock(lock); - map<uint32_t, AgentQueryContext::Ptr>::iterator iter = contextMap.find(sequence); - if (iter == contextMap.end()) - return; - AgentQueryContext::Ptr context = iter->second; - contextMap.erase(iter); - - char* buf(outputBuffer); - uint32_t bufLen(114 + strlen(text)); // header(8) + status(4) + mstring(2 + size) + margin(100) - bool allocated(false); - - if (status == 0) { - for (vector<const SchemaArgument*>::const_iterator aIter = context->schemaMethod->impl->arguments.begin(); - aIter != context->schemaMethod->impl->arguments.end(); aIter++) { - const SchemaArgument* schemaArg = *aIter; - if (schemaArg->getDirection() == DIR_OUT || schemaArg->getDirection() == DIR_IN_OUT) { - if (argMap.keyInMap(schemaArg->getName())) { - const Value* val = argMap.byKey(schemaArg->getName()); - bufLen += val->impl->encodedSize(); - } else { - Value val(schemaArg->getType()); - bufLen += val.impl->encodedSize(); - } - } - } - } - - if (bufLen > MA_BUFFER_SIZE) { - buf = (char*) malloc(bufLen); - allocated = true; - } - - Buffer buffer(buf, bufLen); - Protocol::encodeHeader(buffer, Protocol::OP_METHOD_RESPONSE, context->sequence); - buffer.putLong(status); - buffer.putMediumString(text); - if (status == 0) { - for (vector<const SchemaArgument*>::const_iterator aIter = context->schemaMethod->impl->arguments.begin(); - aIter != context->schemaMethod->impl->arguments.end(); aIter++) { - const SchemaArgument* schemaArg = *aIter; - if (schemaArg->getDirection() == DIR_OUT || schemaArg->getDirection() == DIR_IN_OUT) { - if (argMap.keyInMap(schemaArg->getName())) { - const Value* val = argMap.byKey(schemaArg->getName()); - val->impl->encode(buffer); - } else { - Value val(schemaArg->getType()); - val.impl->encode(buffer); - } - } - } - } - sendBufferLH(buffer, context->exchange, context->key); - if (allocated) - free(buf); - QPID_LOG(trace, "SENT MethodResponse seq=" << context->sequence << " status=" << status << " text=" << text); -} - -void AgentImpl::queryResponse(uint32_t sequence, Object& object, bool prop, bool stat) -{ - Mutex::ScopedLock _lock(lock); - map<uint32_t, AgentQueryContext::Ptr>::iterator iter = contextMap.find(sequence); - if (iter == contextMap.end()) - return; - AgentQueryContext::Ptr context = iter->second; - - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_OBJECT_INDICATION, context->sequence); - - object.impl->encodeSchemaKey(buffer); - object.impl->encodeManagedObjectData(buffer); - if (prop) - object.impl->encodeProperties(buffer); - if (stat) - object.impl->encodeStatistics(buffer); - - sendBufferLH(buffer, context->exchange, context->key); - QPID_LOG(trace, "SENT ContentIndication seq=" << context->sequence); -} - -void AgentImpl::queryComplete(uint32_t sequence) -{ - Mutex::ScopedLock _lock(lock); - map<uint32_t, AgentQueryContext::Ptr>::iterator iter = contextMap.find(sequence); - if (iter == contextMap.end()) - return; - - AgentQueryContext::Ptr context = iter->second; - contextMap.erase(iter); - sendCommandCompleteLH(context->exchange, context->key, context->sequence, 0, "OK"); -} - -void AgentImpl::registerClass(SchemaObjectClass* cls) -{ - Mutex::ScopedLock _lock(lock); - bool newPackage = false; - - map<string, ClassMaps>::iterator iter = packages.find(cls->getClassKey()->getPackageName()); - if (iter == packages.end()) { - packages[cls->getClassKey()->getPackageName()] = ClassMaps(); - iter = packages.find(cls->getClassKey()->getPackageName()); - newPackage = true; - } - - AgentClassKey key(cls->getClassKey()->getClassName(), cls->getClassKey()->getHash()); - iter->second.objectClasses[key] = cls; - - // Indicate this new schema if connected. - - if (attachComplete) { - - if (newPackage) { - sendPackageIndicationLH(iter->first); - } - sendClassIndicationLH(CLASS_OBJECT, iter->first, key); - } -} - -void AgentImpl::registerClass(SchemaEventClass* cls) -{ - Mutex::ScopedLock _lock(lock); - bool newPackage = false; - - map<string, ClassMaps>::iterator iter = packages.find(cls->getClassKey()->getPackageName()); - if (iter == packages.end()) { - packages[cls->getClassKey()->getPackageName()] = ClassMaps(); - iter = packages.find(cls->getClassKey()->getPackageName()); - newPackage = true; - } - - AgentClassKey key(cls->getClassKey()->getClassName(), cls->getClassKey()->getHash()); - iter->second.eventClasses[key] = cls; - - // Indicate this new schema if connected. - - if (attachComplete) { - - if (newPackage) { - sendPackageIndicationLH(iter->first); - } - sendClassIndicationLH(CLASS_EVENT, iter->first, key); - } -} - -const ObjectId* AgentImpl::addObject(Object&, uint64_t) -{ - Mutex::ScopedLock _lock(lock); - return 0; -} - -const ObjectId* AgentImpl::allocObjectId(uint64_t persistId) -{ - Mutex::ScopedLock _lock(lock); - uint16_t sequence = persistId ? 0 : bootSequence; - uint64_t objectNum = persistId ? persistId : nextObjectId++; - - ObjectId* oid = ObjectIdImpl::factory(&attachment, 0, sequence, objectNum); - return oid; -} - -const ObjectId* AgentImpl::allocObjectId(uint32_t persistIdLo, uint32_t persistIdHi) -{ - return allocObjectId(((uint64_t) persistIdHi) << 32 | (uint64_t) persistIdLo); -} - -void AgentImpl::raiseEvent(Event& event) -{ - Mutex::ScopedLock _lock(lock); - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_EVENT_INDICATION); - - event.impl->encodeSchemaKey(buffer); - buffer.putLongLong(uint64_t(Duration(EPOCH, now()))); - event.impl->encode(buffer); - string key(event.impl->getRoutingKey(assignedBrokerBank, assignedAgentBank)); - - sendBufferLH(buffer, QMF_EXCHANGE, key); - QPID_LOG(trace, "SENT EventIndication"); -} - -AgentEventImpl::Ptr AgentImpl::eventDeclareQueue(const string& name) -{ - AgentEventImpl::Ptr event(new AgentEventImpl(AgentEvent::DECLARE_QUEUE)); - event->name = name; - - return event; -} - -AgentEventImpl::Ptr AgentImpl::eventBind(const string& exchange, const string& queue, - const string& key) -{ - AgentEventImpl::Ptr event(new AgentEventImpl(AgentEvent::BIND)); - event->name = queue; - event->exchange = exchange; - event->bindingKey = key; - - return event; -} - -AgentEventImpl::Ptr AgentImpl::eventSetupComplete() -{ - AgentEventImpl::Ptr event(new AgentEventImpl(AgentEvent::SETUP_COMPLETE)); - return event; -} - -AgentEventImpl::Ptr AgentImpl::eventQuery(uint32_t num, const string& userId, const string& package, - const string& cls, boost::shared_ptr<ObjectId> oid) -{ - AgentEventImpl::Ptr event(new AgentEventImpl(AgentEvent::GET_QUERY)); - event->sequence = num; - event->authUserId = userId; - if (oid.get()) - event->query.reset(new Query(oid.get())); - else - event->query.reset(new Query(cls.c_str(), package.c_str())); - return event; -} - -AgentEventImpl::Ptr AgentImpl::eventMethod(uint32_t num, const string& userId, const string& method, - boost::shared_ptr<ObjectId> oid, boost::shared_ptr<Value> argMap, - const SchemaObjectClass* objectClass) -{ - AgentEventImpl::Ptr event(new AgentEventImpl(AgentEvent::METHOD_CALL)); - event->sequence = num; - event->authUserId = userId; - event->name = method; - event->objectId = oid; - event->arguments = argMap; - event->objectClass = objectClass; - return event; -} - -void AgentImpl::sendBufferLH(Buffer& buf, const string& destination, const string& routingKey) -{ - uint32_t length = buf.getPosition(); - MessageImpl::Ptr message(new MessageImpl); - - buf.reset(); - buf.getRawData(message->body, length); - message->destination = destination; - message->routingKey = routingKey; - message->replyExchange = "amq.direct"; - message->replyKey = queueName; - - xmtQueue.push_back(message); -} - -void AgentImpl::sendPackageIndicationLH(const string& packageName) -{ - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_PACKAGE_INDICATION); - buffer.putShortString(packageName); - sendBufferLH(buffer, QMF_EXCHANGE, BROKER_KEY); - QPID_LOG(trace, "SENT PackageIndication: package_name=" << packageName); -} - -void AgentImpl::sendClassIndicationLH(ClassKind kind, const string& packageName, const AgentClassKey& key) -{ - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_CLASS_INDICATION); - buffer.putOctet((int) kind); - buffer.putShortString(packageName); - buffer.putShortString(key.name); - buffer.putBin128(const_cast<uint8_t*>(key.hash)); // const_cast needed for older Qpid libraries - sendBufferLH(buffer, QMF_EXCHANGE, BROKER_KEY); - QPID_LOG(trace, "SENT ClassIndication: package_name=" << packageName << " class_name=" << key.name); -} - -void AgentImpl::sendCommandCompleteLH(const string& exchange, const string& replyToKey, - uint32_t sequence, uint32_t code, const string& text) -{ - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_COMMAND_COMPLETE, sequence); - buffer.putLong(code); - buffer.putShortString(text); - sendBufferLH(buffer, exchange, replyToKey); - QPID_LOG(trace, "SENT CommandComplete: seq=" << sequence << " code=" << code << " text=" << text); -} - -void AgentImpl::sendMethodErrorLH(uint32_t sequence, const string& key, uint32_t code, const string& text) -{ - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_METHOD_RESPONSE, sequence); - buffer.putLong(code); - - string fulltext; - switch (code) { - case MERR_UNKNOWN_PACKAGE: fulltext = "Unknown Package"; break; - case MERR_UNKNOWN_CLASS: fulltext = "Unknown Class"; break; - case MERR_UNKNOWN_METHOD: fulltext = "Unknown Method"; break; - case MERR_INTERNAL_ERROR: fulltext = "Internal Error"; break; - default: fulltext = "Unspecified Error"; break; - } - - if (!text.empty()) { - fulltext += " ("; - fulltext += text; - fulltext += ")"; - } - - buffer.putMediumString(fulltext); - sendBufferLH(buffer, DIR_EXCHANGE, key); - QPID_LOG(trace, "SENT MethodResponse: errorCode=" << code << " text=" << fulltext); -} - -void AgentImpl::handleAttachResponse(Buffer& inBuffer) -{ - Mutex::ScopedLock _lock(lock); - - assignedBrokerBank = inBuffer.getLong(); - assignedAgentBank = inBuffer.getLong(); - - QPID_LOG(trace, "RCVD AttachResponse: broker=" << assignedBrokerBank << " agent=" << assignedAgentBank); - - if ((assignedBrokerBank != requestedBrokerBank) || - (assignedAgentBank != requestedAgentBank)) { - if (requestedAgentBank == 0) { - QPID_LOG(notice, "Initial object-id bank assigned: " << assignedBrokerBank << "." << - assignedAgentBank); - } else { - QPID_LOG(warning, "Collision in object-id! New bank assigned: " << assignedBrokerBank << - "." << assignedAgentBank); - } - //storeData(); // TODO - requestedBrokerBank = assignedBrokerBank; - requestedAgentBank = assignedAgentBank; - } - - attachment.setBanks(assignedBrokerBank, assignedAgentBank); - - // Bind to qpid.management to receive commands - stringstream key; - key << "agent." << assignedBrokerBank << "." << assignedAgentBank; - eventQueue.push_back(eventBind(QMF_EXCHANGE, queueName, key.str())); - - // Send package indications for all local packages - for (map<string, ClassMaps>::iterator pIter = packages.begin(); - pIter != packages.end(); - pIter++) { - sendPackageIndicationLH(pIter->first); - - // Send class indications for all local classes - ClassMaps cMap = pIter->second; - for (ObjectClassMap::iterator cIter = cMap.objectClasses.begin(); - cIter != cMap.objectClasses.end(); cIter++) - sendClassIndicationLH(CLASS_OBJECT, pIter->first, cIter->first); - for (EventClassMap::iterator cIter = cMap.eventClasses.begin(); - cIter != cMap.eventClasses.end(); cIter++) - sendClassIndicationLH(CLASS_EVENT, pIter->first, cIter->first); - } - - attachComplete = true; -} - -void AgentImpl::handlePackageRequest(Buffer&) -{ - Mutex::ScopedLock _lock(lock); -} - -void AgentImpl::handleClassQuery(Buffer&) -{ - Mutex::ScopedLock _lock(lock); -} - -void AgentImpl::handleSchemaRequest(Buffer& inBuffer, uint32_t sequence, - const string& replyExchange, const string& replyKey) -{ - Mutex::ScopedLock _lock(lock); - string rExchange(replyExchange); - string rKey(replyKey); - string packageName; - inBuffer.getShortString(packageName); - AgentClassKey key(inBuffer); - - if (rExchange.empty()) - rExchange = QMF_EXCHANGE; - if (rKey.empty()) - rKey = BROKER_KEY; - - QPID_LOG(trace, "RCVD SchemaRequest: package=" << packageName << " class=" << key.name); - - map<string, ClassMaps>::iterator pIter = packages.find(packageName); - if (pIter == packages.end()) { - sendCommandCompleteLH(rExchange, rKey, sequence, 1, "package not found"); - return; - } - - ClassMaps cMap = pIter->second; - ObjectClassMap::iterator ocIter = cMap.objectClasses.find(key); - if (ocIter != cMap.objectClasses.end()) { - SchemaObjectClass* oImpl = ocIter->second; - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_SCHEMA_RESPONSE, sequence); - oImpl->impl->encode(buffer); - sendBufferLH(buffer, rExchange, rKey); - QPID_LOG(trace, "SENT SchemaResponse: (object) package=" << packageName << " class=" << key.name); - return; - } - - EventClassMap::iterator ecIter = cMap.eventClasses.find(key); - if (ecIter != cMap.eventClasses.end()) { - SchemaEventClass* eImpl = ecIter->second; - Buffer buffer(outputBuffer, MA_BUFFER_SIZE); - Protocol::encodeHeader(buffer, Protocol::OP_SCHEMA_RESPONSE, sequence); - eImpl->impl->encode(buffer); - sendBufferLH(buffer, rExchange, rKey); - QPID_LOG(trace, "SENT SchemaResponse: (event) package=" << packageName << " class=" << key.name); - return; - } - - sendCommandCompleteLH(rExchange, rKey, sequence, 1, "class not found"); -} - -void AgentImpl::handleGetQuery(Buffer& inBuffer, uint32_t sequence, const string& replyTo, const string& userId) -{ - Mutex::ScopedLock _lock(lock); - FieldTable ft; - FieldTable::ValuePtr value; - map<string, ClassMaps>::const_iterator pIter = packages.end(); - string pname; - string cname; - string oidRepr; - boost::shared_ptr<ObjectId> oid; - - ft.decode(inBuffer); - - QPID_LOG(trace, "RCVD GetQuery: seq=" << sequence << " map=" << ft); - - value = ft.get("_package"); - if (value.get() && value->convertsTo<string>()) { - pname = value->get<string>(); - pIter = packages.find(pname); - if (pIter == packages.end()) { - sendCommandCompleteLH(DIR_EXCHANGE, replyTo, sequence); - return; - } - } - - value = ft.get("_class"); - if (value.get() && value->convertsTo<string>()) { - cname = value->get<string>(); - // TODO - check for validity of class (in package or any package) - if (pIter == packages.end()) { - } else { - - } - } - - value = ft.get("_objectid"); - if (value.get() && value->convertsTo<string>()) { - oidRepr = value->get<string>(); - oid.reset(new ObjectId()); - oid->impl->fromString(oidRepr); - } - - AgentQueryContext::Ptr context(new AgentQueryContext); - uint32_t contextNum = nextContextNum++; - context->sequence = sequence; - context->exchange = DIR_EXCHANGE; - context->key = replyTo; - contextMap[contextNum] = context; - - eventQueue.push_back(eventQuery(contextNum, userId, pname, cname, oid)); -} - -void AgentImpl::handleMethodRequest(Buffer& buffer, uint32_t sequence, const string& replyTo, const string& userId) -{ - Mutex::ScopedLock _lock(lock); - string pname; - string method; - boost::shared_ptr<ObjectId> oid(ObjectIdImpl::factory(buffer)); - buffer.getShortString(pname); - AgentClassKey classKey(buffer); - buffer.getShortString(method); - - QPID_LOG(trace, "RCVD MethodRequest seq=" << sequence << " method=" << method); - - map<string, ClassMaps>::const_iterator pIter = packages.find(pname); - if (pIter == packages.end()) { - sendMethodErrorLH(sequence, replyTo, MERR_UNKNOWN_PACKAGE, pname); - return; - } - - ObjectClassMap::const_iterator cIter = pIter->second.objectClasses.find(classKey); - if (cIter == pIter->second.objectClasses.end()) { - sendMethodErrorLH(sequence, replyTo, MERR_UNKNOWN_CLASS, classKey.repr()); - return; - } - - const SchemaObjectClass* schema = cIter->second; - vector<const SchemaMethod*>::const_iterator mIter = schema->impl->methods.begin(); - for (; mIter != schema->impl->methods.end(); mIter++) { - if ((*mIter)->getName() == method) - break; - } - - if (mIter == schema->impl->methods.end()) { - sendMethodErrorLH(sequence, replyTo, MERR_UNKNOWN_METHOD, method); - return; - } - - const SchemaMethod* schemaMethod = *mIter; - boost::shared_ptr<Value> argMap(new Value(TYPE_MAP)); - Value* value; - for (vector<const SchemaArgument*>::const_iterator aIter = schemaMethod->impl->arguments.begin(); - aIter != schemaMethod->impl->arguments.end(); aIter++) { - const SchemaArgument* schemaArg = *aIter; - if (schemaArg->getDirection() == DIR_IN || schemaArg->getDirection() == DIR_IN_OUT) - value = ValueImpl::factory(schemaArg->getType(), buffer); - else - value = ValueImpl::factory(schemaArg->getType()); - argMap->insert(schemaArg->getName(), value); - } - - AgentQueryContext::Ptr context(new AgentQueryContext); - uint32_t contextNum = nextContextNum++; - context->sequence = sequence; - context->exchange = DIR_EXCHANGE; - context->key = replyTo; - context->schemaMethod = schemaMethod; - contextMap[contextNum] = context; - - eventQueue.push_back(eventMethod(contextNum, userId, method, oid, argMap, schema)); -} - -void AgentImpl::handleConsoleAddedIndication() -{ - Mutex::ScopedLock _lock(lock); -} - -//================================================================== -// Wrappers -//================================================================== - -Agent::Agent(char* label, bool internalStore) { impl = new AgentImpl(label, internalStore); } -Agent::~Agent() { delete impl; } -void Agent::setStoreDir(const char* path) { impl->setStoreDir(path); } -void Agent::setTransferDir(const char* path) { impl->setTransferDir(path); } -void Agent::handleRcvMessage(Message& message) { impl->handleRcvMessage(message); } -bool Agent::getXmtMessage(Message& item) const { return impl->getXmtMessage(item); } -void Agent::popXmt() { impl->popXmt(); } -bool Agent::getEvent(AgentEvent& event) const { return impl->getEvent(event); } -void Agent::popEvent() { impl->popEvent(); } -void Agent::newSession() { impl->newSession(); } -void Agent::startProtocol() { impl->startProtocol(); } -void Agent::heartbeat() { impl->heartbeat(); } -void Agent::methodResponse(uint32_t sequence, uint32_t status, char* text, const Value& arguments) { impl->methodResponse(sequence, status, text, arguments); } -void Agent::queryResponse(uint32_t sequence, Object& object, bool prop, bool stat) { impl->queryResponse(sequence, object, prop, stat); } -void Agent::queryComplete(uint32_t sequence) { impl->queryComplete(sequence); } -void Agent::registerClass(SchemaObjectClass* cls) { impl->registerClass(cls); } -void Agent::registerClass(SchemaEventClass* cls) { impl->registerClass(cls); } -const ObjectId* Agent::addObject(Object& obj, uint64_t persistId) { return impl->addObject(obj, persistId); } -const ObjectId* Agent::allocObjectId(uint64_t persistId) { return impl->allocObjectId(persistId); } -const ObjectId* Agent::allocObjectId(uint32_t persistIdLo, uint32_t persistIdHi) { return impl->allocObjectId(persistIdLo, persistIdHi); } -void Agent::raiseEvent(Event& event) { impl->raiseEvent(event); } - diff --git a/cpp/src/qmf/engine/BrokerProxyImpl.cpp b/cpp/src/qmf/engine/BrokerProxyImpl.cpp deleted file mode 100644 index 5fc71979fd..0000000000 --- a/cpp/src/qmf/engine/BrokerProxyImpl.cpp +++ /dev/null @@ -1,827 +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 "qmf/engine/BrokerProxyImpl.h" -#include "qmf/engine/ConsoleImpl.h" -#include "qmf/engine/Protocol.h" -#include "qpid/Address.h" -#include "qpid/sys/SystemInfo.h" -#include <qpid/log/Statement.h> -#include <qpid/StringUtils.h> -#include <string.h> -#include <iostream> -#include <fstream> - -using namespace std; -using namespace qmf::engine; -using namespace qpid::framing; -using namespace qpid::sys; - -namespace { - const char* QMF_EXCHANGE = "qpid.management"; - const char* DIR_EXCHANGE = "amq.direct"; - const char* BROKER_KEY = "broker"; - const char* BROKER_PACKAGE = "org.apache.qpid.broker"; - const char* AGENT_CLASS = "agent"; - const char* BROKER_AGENT_KEY = "agent.1.0"; -} - -const Object* QueryResponseImpl::getObject(uint32_t idx) const -{ - vector<ObjectPtr>::const_iterator iter = results.begin(); - - while (idx > 0) { - if (iter == results.end()) - return 0; - iter++; - idx--; - } - - return iter->get(); -} - -#define STRING_REF(s) {if (!s.empty()) item.s = const_cast<char*>(s.c_str());} - -BrokerEvent BrokerEventImpl::copy() -{ - BrokerEvent item; - - ::memset(&item, 0, sizeof(BrokerEvent)); - item.kind = kind; - - STRING_REF(name); - STRING_REF(exchange); - STRING_REF(bindingKey); - item.context = context; - item.queryResponse = queryResponse.get(); - item.methodResponse = methodResponse.get(); - - return item; -} - -BrokerProxyImpl::BrokerProxyImpl(BrokerProxy& pub, Console& _console) : publicObject(pub), console(_console) -{ - stringstream qn; - qpid::Address addr; - - SystemInfo::getLocalHostname(addr); - qn << "qmfc-" << SystemInfo::getProcessName() << "-" << addr << "-" << SystemInfo::getProcessId(); - queueName = qn.str(); - - seqMgr.setUnsolicitedContext(SequenceContext::Ptr(new StaticContext(*this))); -} - -void BrokerProxyImpl::sessionOpened(SessionHandle& /*sh*/) -{ - Mutex::ScopedLock _lock(lock); - agentList.clear(); - eventQueue.clear(); - xmtQueue.clear(); - eventQueue.push_back(eventDeclareQueue(queueName)); - eventQueue.push_back(eventBind(DIR_EXCHANGE, queueName, queueName)); - eventQueue.push_back(eventSetupComplete()); - - // TODO: Store session handle -} - -void BrokerProxyImpl::sessionClosed() -{ - Mutex::ScopedLock _lock(lock); - agentList.clear(); - eventQueue.clear(); - xmtQueue.clear(); -} - -void BrokerProxyImpl::startProtocol() -{ - AgentProxyPtr agent(AgentProxyImpl::factory(console, publicObject, 0, "Agent embedded in broker")); - { - Mutex::ScopedLock _lock(lock); - char rawbuffer[512]; - Buffer buffer(rawbuffer, 512); - - agentList[0] = agent; - - requestsOutstanding = 1; - topicBound = false; - uint32_t sequence(seqMgr.reserve()); - Protocol::encodeHeader(buffer, Protocol::OP_BROKER_REQUEST, sequence); - sendBufferLH(buffer, QMF_EXCHANGE, BROKER_KEY); - QPID_LOG(trace, "SENT BrokerRequest seq=" << sequence); - } - - console.impl->eventAgentAdded(agent); -} - -void BrokerProxyImpl::sendBufferLH(Buffer& buf, const string& destination, const string& routingKey) -{ - uint32_t length = buf.getPosition(); - MessageImpl::Ptr message(new MessageImpl); - - buf.reset(); - buf.getRawData(message->body, length); - message->destination = destination; - message->routingKey = routingKey; - message->replyExchange = DIR_EXCHANGE; - message->replyKey = queueName; - - xmtQueue.push_back(message); -} - -void BrokerProxyImpl::handleRcvMessage(Message& message) -{ - Buffer inBuffer(message.body, message.length); - uint8_t opcode; - uint32_t sequence; - - while (Protocol::checkHeader(inBuffer, &opcode, &sequence)) - seqMgr.dispatch(opcode, sequence, message.routingKey ? string(message.routingKey) : string(), inBuffer); -} - -bool BrokerProxyImpl::getXmtMessage(Message& item) const -{ - Mutex::ScopedLock _lock(lock); - if (xmtQueue.empty()) - return false; - item = xmtQueue.front()->copy(); - return true; -} - -void BrokerProxyImpl::popXmt() -{ - Mutex::ScopedLock _lock(lock); - if (!xmtQueue.empty()) - xmtQueue.pop_front(); -} - -bool BrokerProxyImpl::getEvent(BrokerEvent& event) const -{ - Mutex::ScopedLock _lock(lock); - if (eventQueue.empty()) - return false; - event = eventQueue.front()->copy(); - return true; -} - -void BrokerProxyImpl::popEvent() -{ - Mutex::ScopedLock _lock(lock); - if (!eventQueue.empty()) - eventQueue.pop_front(); -} - -uint32_t BrokerProxyImpl::agentCount() const -{ - Mutex::ScopedLock _lock(lock); - return agentList.size(); -} - -const AgentProxy* BrokerProxyImpl::getAgent(uint32_t idx) const -{ - Mutex::ScopedLock _lock(lock); - for (map<uint32_t, AgentProxyPtr>::const_iterator iter = agentList.begin(); - iter != agentList.end(); iter++) - if (idx-- == 0) - return iter->second.get(); - return 0; -} - -void BrokerProxyImpl::sendQuery(const Query& query, void* context, const AgentProxy* agent) -{ - SequenceContext::Ptr queryContext(new QueryContext(*this, context)); - Mutex::ScopedLock _lock(lock); - bool sent = false; - if (agent != 0) { - if (sendGetRequestLH(queryContext, query, agent)) - sent = true; - } else { - // TODO (optimization) only send queries to agents that have the requested class+package - for (map<uint32_t, AgentProxyPtr>::const_iterator iter = agentList.begin(); - iter != agentList.end(); iter++) { - if (sendGetRequestLH(queryContext, query, iter->second.get())) - sent = true; - } - } - - if (!sent) { - queryContext->reserve(); - queryContext->release(); - } -} - -bool BrokerProxyImpl::sendGetRequestLH(SequenceContext::Ptr queryContext, const Query& query, const AgentProxy* agent) -{ - if (query.impl->singleAgent()) { - if (query.impl->agentBank() != agent->getAgentBank()) - return false; - } - stringstream key; - Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE); - uint32_t sequence(seqMgr.reserve(queryContext)); - agent->impl->addSequence(sequence); - - Protocol::encodeHeader(outBuffer, Protocol::OP_GET_QUERY, sequence); - query.impl->encode(outBuffer); - key << "agent.1." << agent->impl->agentBank; - sendBufferLH(outBuffer, QMF_EXCHANGE, key.str()); - QPID_LOG(trace, "SENT GetQuery seq=" << sequence << " key=" << key.str()); - return true; -} - -string BrokerProxyImpl::encodeMethodArguments(const SchemaMethod* schema, const Value* argmap, Buffer& buffer) -{ - int argCount = schema->getArgumentCount(); - - if (argmap == 0 || !argmap->isMap()) - return string("Arguments must be in a map value"); - - for (int aIdx = 0; aIdx < argCount; aIdx++) { - const SchemaArgument* arg(schema->getArgument(aIdx)); - if (arg->getDirection() == DIR_IN || arg->getDirection() == DIR_IN_OUT) { - if (argmap->keyInMap(arg->getName())) { - const Value* argVal(argmap->byKey(arg->getName())); - if (argVal->getType() != arg->getType()) - return string("Argument is the wrong type: ") + arg->getName(); - argVal->impl->encode(buffer); - } else { - Value defaultValue(arg->getType()); - defaultValue.impl->encode(buffer); - } - } - } - - return string(); -} - -string BrokerProxyImpl::encodedSizeMethodArguments(const SchemaMethod* schema, const Value* argmap, uint32_t& size) -{ - int argCount = schema->getArgumentCount(); - - if (argmap == 0 || !argmap->isMap()) - return string("Arguments must be in a map value"); - - for (int aIdx = 0; aIdx < argCount; aIdx++) { - const SchemaArgument* arg(schema->getArgument(aIdx)); - if (arg->getDirection() == DIR_IN || arg->getDirection() == DIR_IN_OUT) { - if (argmap->keyInMap(arg->getName())) { - const Value* argVal(argmap->byKey(arg->getName())); - if (argVal->getType() != arg->getType()) - return string("Argument is the wrong type: ") + arg->getName(); - size += argVal->impl->encodedSize(); - } else { - Value defaultValue(arg->getType()); - size += defaultValue.impl->encodedSize(); - } - } - } - - return string(); -} - -void BrokerProxyImpl::sendMethodRequest(ObjectId* oid, const SchemaObjectClass* cls, - const string& methodName, const Value* args, void* userContext) -{ - int methodCount = cls->getMethodCount(); - int idx; - for (idx = 0; idx < methodCount; idx++) { - const SchemaMethod* method = cls->getMethod(idx); - if (string(method->getName()) == methodName) { - Mutex::ScopedLock _lock(lock); - SequenceContext::Ptr methodContext(new MethodContext(*this, userContext, method)); - stringstream key; - char* buf(outputBuffer); - uint32_t bufLen(1024); - bool allocated(false); - - string argErrorString = encodedSizeMethodArguments(method, args, bufLen); - if (!argErrorString.empty()) { - MethodResponsePtr argError(MethodResponseImpl::factory(1, argErrorString)); - eventQueue.push_back(eventMethodResponse(userContext, argError)); - return; - } - - if (bufLen > MA_BUFFER_SIZE) { - buf = (char*) malloc(bufLen); - allocated = true; - } - - Buffer outBuffer(buf, bufLen); - uint32_t sequence(seqMgr.reserve(methodContext)); - - Protocol::encodeHeader(outBuffer, Protocol::OP_METHOD_REQUEST, sequence); - oid->impl->encode(outBuffer); - cls->getClassKey()->impl->encode(outBuffer); - outBuffer.putShortString(methodName); - - encodeMethodArguments(method, args, outBuffer); - key << "agent.1." << oid->impl->getAgentBank(); - sendBufferLH(outBuffer, QMF_EXCHANGE, key.str()); - QPID_LOG(trace, "SENT MethodRequest seq=" << sequence << " method=" << methodName << " key=" << key.str()); - - if (allocated) - free(buf); - - return; - } - } - - MethodResponsePtr error(MethodResponseImpl::factory(1, string("Unknown method: ") + methodName)); - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(eventMethodResponse(userContext, error)); -} - -void BrokerProxyImpl::addBinding(const string& exchange, const string& key) -{ - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(eventBind(exchange, queueName, key)); -} - -BrokerEventImpl::Ptr BrokerProxyImpl::eventDeclareQueue(const string& queueName) -{ - BrokerEventImpl::Ptr event(new BrokerEventImpl(BrokerEvent::DECLARE_QUEUE)); - event->name = queueName; - return event; -} - -BrokerEventImpl::Ptr BrokerProxyImpl::eventBind(const string& exchange, const string& queue, const string& key) -{ - BrokerEventImpl::Ptr event(new BrokerEventImpl(BrokerEvent::BIND)); - event->name = queue; - event->exchange = exchange; - event->bindingKey = key; - - return event; -} - -BrokerEventImpl::Ptr BrokerProxyImpl::eventSetupComplete() -{ - BrokerEventImpl::Ptr event(new BrokerEventImpl(BrokerEvent::SETUP_COMPLETE)); - return event; -} - -BrokerEventImpl::Ptr BrokerProxyImpl::eventStable() -{ - QPID_LOG(trace, "Console Link to Broker Stable"); - BrokerEventImpl::Ptr event(new BrokerEventImpl(BrokerEvent::STABLE)); - return event; -} - -BrokerEventImpl::Ptr BrokerProxyImpl::eventQueryComplete(void* context, QueryResponsePtr response) -{ - BrokerEventImpl::Ptr event(new BrokerEventImpl(BrokerEvent::QUERY_COMPLETE)); - event->context = context; - event->queryResponse = response; - return event; -} - -BrokerEventImpl::Ptr BrokerProxyImpl::eventMethodResponse(void* context, MethodResponsePtr response) -{ - BrokerEventImpl::Ptr event(new BrokerEventImpl(BrokerEvent::METHOD_RESPONSE)); - event->context = context; - event->methodResponse = response; - return event; -} - -void BrokerProxyImpl::handleBrokerResponse(Buffer& inBuffer, uint32_t seq) -{ - brokerId.decode(inBuffer); - QPID_LOG(trace, "RCVD BrokerResponse seq=" << seq << " brokerId=" << brokerId); - Mutex::ScopedLock _lock(lock); - Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE); - uint32_t sequence(seqMgr.reserve()); - incOutstandingLH(); - Protocol::encodeHeader(outBuffer, Protocol::OP_PACKAGE_REQUEST, sequence); - sendBufferLH(outBuffer, QMF_EXCHANGE, BROKER_KEY); - QPID_LOG(trace, "SENT PackageRequest seq=" << sequence); -} - -void BrokerProxyImpl::handlePackageIndication(Buffer& inBuffer, uint32_t seq) -{ - string package; - - inBuffer.getShortString(package); - QPID_LOG(trace, "RCVD PackageIndication seq=" << seq << " package=" << package); - console.impl->learnPackage(package); - - Mutex::ScopedLock _lock(lock); - Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE); - uint32_t sequence(seqMgr.reserve()); - incOutstandingLH(); - Protocol::encodeHeader(outBuffer, Protocol::OP_CLASS_QUERY, sequence); - outBuffer.putShortString(package); - sendBufferLH(outBuffer, QMF_EXCHANGE, BROKER_KEY); - QPID_LOG(trace, "SENT ClassQuery seq=" << sequence << " package=" << package); -} - -void BrokerProxyImpl::handleCommandComplete(Buffer& inBuffer, uint32_t seq) -{ - string text; - uint32_t code = inBuffer.getLong(); - inBuffer.getShortString(text); - QPID_LOG(trace, "RCVD CommandComplete seq=" << seq << " code=" << code << " text=" << text); -} - -void BrokerProxyImpl::handleClassIndication(Buffer& inBuffer, uint32_t seq) -{ - uint8_t kind = inBuffer.getOctet(); - auto_ptr<SchemaClassKey> classKey(SchemaClassKeyImpl::factory(inBuffer)); - - QPID_LOG(trace, "RCVD ClassIndication seq=" << seq << " kind=" << (int) kind << " key=" << classKey->impl->str()); - - if (!console.impl->haveClass(classKey.get())) { - Mutex::ScopedLock _lock(lock); - incOutstandingLH(); - Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE); - uint32_t sequence(seqMgr.reserve()); - Protocol::encodeHeader(outBuffer, Protocol::OP_SCHEMA_REQUEST, sequence); - classKey->impl->encode(outBuffer); - sendBufferLH(outBuffer, QMF_EXCHANGE, BROKER_KEY); - QPID_LOG(trace, "SENT SchemaRequest seq=" << sequence <<" key=" << classKey->impl->str()); - } -} - -MethodResponsePtr BrokerProxyImpl::handleMethodResponse(Buffer& inBuffer, uint32_t seq, const SchemaMethod* schema) -{ - MethodResponsePtr response(MethodResponseImpl::factory(inBuffer, schema)); - - QPID_LOG(trace, "RCVD MethodResponse seq=" << seq << " status=" << response->getStatus() << " text=" << - response->getException()->asString()); - - return response; -} - -void BrokerProxyImpl::handleHeartbeatIndication(Buffer& inBuffer, uint32_t seq, const string& routingKey) -{ - vector<string> tokens = qpid::split(routingKey, "."); - uint32_t agentBank; - uint64_t timestamp; - - if (routingKey.empty() || tokens.size() != 4) - agentBank = 0; - else - agentBank = ::atoi(tokens[3].c_str()); - - timestamp = inBuffer.getLongLong(); - map<uint32_t, AgentProxyPtr>::const_iterator iter = agentList.find(agentBank); - if (iter != agentList.end()) { - console.impl->eventAgentHeartbeat(iter->second, timestamp); - } - QPID_LOG(trace, "RCVD HeartbeatIndication seq=" << seq << " agentBank=" << agentBank); -} - -void BrokerProxyImpl::handleEventIndication(Buffer& inBuffer, uint32_t seq) -{ - auto_ptr<SchemaClassKey> classKey(SchemaClassKeyImpl::factory(inBuffer)); - const SchemaEventClass *schema = console.impl->getEventClass(classKey.get()); - if (schema == 0) { - QPID_LOG(trace, "No Schema Found for EventIndication. seq=" << seq << " key=" << classKey->impl->str()); - return; - } - - EventPtr eptr(EventImpl::factory(schema, inBuffer)); - - console.impl->eventEventReceived(eptr); - QPID_LOG(trace, "RCVD EventIndication seq=" << seq << " key=" << classKey->impl->str()); -} - -void BrokerProxyImpl::handleSchemaResponse(Buffer& inBuffer, uint32_t seq) -{ - SchemaObjectClass* oClassPtr; - SchemaEventClass* eClassPtr; - uint8_t kind = inBuffer.getOctet(); - const SchemaClassKey* key; - if (kind == CLASS_OBJECT) { - oClassPtr = SchemaObjectClassImpl::factory(inBuffer); - console.impl->learnClass(oClassPtr); - key = oClassPtr->getClassKey(); - QPID_LOG(trace, "RCVD SchemaResponse seq=" << seq << " kind=object key=" << key->impl->str()); - - // - // If we have just learned about the org.apache.qpid.broker:agent class, send a get - // request for the current list of agents so we can have it on-hand before we declare - // this session "stable". - // - if (key->impl->getClassName() == AGENT_CLASS && key->impl->getPackageName() == BROKER_PACKAGE) { - Mutex::ScopedLock _lock(lock); - incOutstandingLH(); - Buffer outBuffer(outputBuffer, MA_BUFFER_SIZE); - uint32_t sequence(seqMgr.reserve()); - Protocol::encodeHeader(outBuffer, Protocol::OP_GET_QUERY, sequence); - FieldTable ft; - ft.setString("_class", AGENT_CLASS); - ft.setString("_package", BROKER_PACKAGE); - ft.encode(outBuffer); - sendBufferLH(outBuffer, QMF_EXCHANGE, BROKER_AGENT_KEY); - QPID_LOG(trace, "SENT GetQuery seq=" << sequence << " key=" << BROKER_AGENT_KEY); - } - } else if (kind == CLASS_EVENT) { - eClassPtr = SchemaEventClassImpl::factory(inBuffer); - console.impl->learnClass(eClassPtr); - key = eClassPtr->getClassKey(); - QPID_LOG(trace, "RCVD SchemaResponse seq=" << seq << " kind=event key=" << key->impl->str()); - } - else { - QPID_LOG(error, "BrokerProxyImpl::handleSchemaResponse received unknown class kind: " << (int) kind); - } -} - -ObjectPtr BrokerProxyImpl::handleObjectIndication(Buffer& inBuffer, uint32_t seq, bool prop, bool stat) -{ - auto_ptr<SchemaClassKey> classKey(SchemaClassKeyImpl::factory(inBuffer)); - QPID_LOG(trace, "RCVD ObjectIndication seq=" << seq << " key=" << classKey->impl->str()); - - SchemaObjectClass* schema = console.impl->getSchema(classKey.get()); - if (schema == 0) { - QPID_LOG(trace, "No Schema Found for ObjectIndication. seq=" << seq << " key=" << classKey->impl->str()); - return ObjectPtr(); - } - - ObjectPtr optr(ObjectImpl::factory(schema, this, inBuffer, prop, stat, true)); - if (prop && classKey->impl->getPackageName() == BROKER_PACKAGE && classKey->impl->getClassName() == AGENT_CLASS) { - // - // We've intercepted information about a remote agent... update the agent list accordingly - // - updateAgentList(optr); - } - return optr; -} - -void BrokerProxyImpl::updateAgentList(ObjectPtr obj) -{ - Value* value = obj->getValue("agentBank"); - Mutex::ScopedLock _lock(lock); - if (value != 0 && value->isUint()) { - uint32_t agentBank = value->asUint(); - if (obj->isDeleted()) { - map<uint32_t, AgentProxyPtr>::iterator iter = agentList.find(agentBank); - if (iter != agentList.end()) { - AgentProxyPtr agent(iter->second); - console.impl->eventAgentDeleted(agent); - agentList.erase(agentBank); - QPID_LOG(trace, "Agent at bank " << agentBank << " removed from agent list"); - - // - // Release all sequence numbers for requests in-flight to this agent. - // Since the agent is no longer connected, these requests would not - // otherwise complete. - // - agent->impl->releaseInFlight(seqMgr); - } - } else { - Value* str = obj->getValue("label"); - string label; - if (str != 0 && str->isString()) - label = str->asString(); - map<uint32_t, AgentProxyPtr>::const_iterator iter = agentList.find(agentBank); - if (iter == agentList.end()) { - AgentProxyPtr agent(AgentProxyImpl::factory(console, publicObject, agentBank, label)); - agentList[agentBank] = agent; - console.impl->eventAgentAdded(agent); - QPID_LOG(trace, "Agent '" << label << "' found at bank " << agentBank); - } - } - } -} - -void BrokerProxyImpl::incOutstandingLH() -{ - requestsOutstanding++; -} - -void BrokerProxyImpl::decOutstanding() -{ - Mutex::ScopedLock _lock(lock); - requestsOutstanding--; - if (requestsOutstanding == 0 && !topicBound) { - topicBound = true; - for (vector<pair<string, string> >::const_iterator iter = console.impl->bindingList.begin(); - iter != console.impl->bindingList.end(); iter++) { - string exchange(iter->first.empty() ? QMF_EXCHANGE : iter->first); - string key(iter->second); - eventQueue.push_back(eventBind(exchange, queueName, key)); - } - eventQueue.push_back(eventStable()); - } -} - -MethodResponseImpl::MethodResponseImpl(const MethodResponseImpl& from) : - status(from.status), schema(from.schema) -{ - if (from.exception.get()) - exception.reset(new Value(*(from.exception))); - if (from.arguments.get()) - arguments.reset(new Value(*(from.arguments))); -} - -MethodResponseImpl::MethodResponseImpl(Buffer& buf, const SchemaMethod* s) : schema(s) -{ - string text; - - status = buf.getLong(); - buf.getMediumString(text); - exception.reset(new Value(TYPE_LSTR)); - exception->setString(text.c_str()); - - if (status != 0) - return; - - arguments.reset(new Value(TYPE_MAP)); - int argCount(schema->getArgumentCount()); - for (int idx = 0; idx < argCount; idx++) { - const SchemaArgument* arg = schema->getArgument(idx); - if (arg->getDirection() == DIR_OUT || arg->getDirection() == DIR_IN_OUT) { - Value* value(ValueImpl::factory(arg->getType(), buf)); - arguments->insert(arg->getName(), value); - } - } -} - -MethodResponseImpl::MethodResponseImpl(uint32_t s, const string& text) : schema(0) -{ - status = s; - exception.reset(new Value(TYPE_LSTR)); - exception->setString(text.c_str()); -} - -MethodResponse* MethodResponseImpl::factory(Buffer& buf, const SchemaMethod* schema) -{ - MethodResponseImpl* impl(new MethodResponseImpl(buf, schema)); - return new MethodResponse(impl); -} - -MethodResponse* MethodResponseImpl::factory(uint32_t status, const std::string& text) -{ - MethodResponseImpl* impl(new MethodResponseImpl(status, text)); - return new MethodResponse(impl); -} - -bool StaticContext::handleMessage(uint8_t opcode, uint32_t sequence, const string& routingKey, Buffer& buffer) -{ - ObjectPtr object; - bool completeContext = false; - - if (opcode == Protocol::OP_BROKER_RESPONSE) { - broker.handleBrokerResponse(buffer, sequence); - completeContext = true; - } - else if (opcode == Protocol::OP_COMMAND_COMPLETE) { - broker.handleCommandComplete(buffer, sequence); - completeContext = true; - } - else if (opcode == Protocol::OP_SCHEMA_RESPONSE) { - broker.handleSchemaResponse(buffer, sequence); - completeContext = true; - } - else if (opcode == Protocol::OP_PACKAGE_INDICATION) - broker.handlePackageIndication(buffer, sequence); - else if (opcode == Protocol::OP_CLASS_INDICATION) - broker.handleClassIndication(buffer, sequence); - else if (opcode == Protocol::OP_HEARTBEAT_INDICATION) - broker.handleHeartbeatIndication(buffer, sequence, routingKey); - else if (opcode == Protocol::OP_EVENT_INDICATION) - broker.handleEventIndication(buffer, sequence); - else if (opcode == Protocol::OP_PROPERTY_INDICATION) { - object = broker.handleObjectIndication(buffer, sequence, true, false); - broker.console.impl->eventObjectUpdate(object, true, false); - } - else if (opcode == Protocol::OP_STATISTIC_INDICATION) { - object = broker.handleObjectIndication(buffer, sequence, false, true); - broker.console.impl->eventObjectUpdate(object, false, true); - } - else if (opcode == Protocol::OP_OBJECT_INDICATION) { - object = broker.handleObjectIndication(buffer, sequence, true, true); - broker.console.impl->eventObjectUpdate(object, true, true); - } - else { - QPID_LOG(trace, "StaticContext::handleMessage invalid opcode: " << opcode); - completeContext = true; - } - - return completeContext; -} - -void QueryContext::reserve() -{ - Mutex::ScopedLock _lock(lock); - requestsOutstanding++; -} - -void QueryContext::release() -{ - { - Mutex::ScopedLock _lock(lock); - if (--requestsOutstanding > 0) - return; - } - - Mutex::ScopedLock _block(broker.lock); - broker.eventQueue.push_back(broker.eventQueryComplete(userContext, queryResponse)); -} - -bool QueryContext::handleMessage(uint8_t opcode, uint32_t sequence, const string& /*routingKey*/, Buffer& buffer) -{ - bool completeContext = false; - ObjectPtr object; - - if (opcode == Protocol::OP_COMMAND_COMPLETE) { - broker.handleCommandComplete(buffer, sequence); - completeContext = true; - - // - // Visit each agent and remove the sequence from that agent's in-flight list. - // This could be made more efficient because only one agent will have this sequence - // in its list. - // - map<uint32_t, AgentProxyPtr> copy; - { - Mutex::ScopedLock _block(broker.lock); - copy = broker.agentList; - } - for (map<uint32_t, AgentProxyPtr>::iterator iter = copy.begin(); iter != copy.end(); iter++) - iter->second->impl->delSequence(sequence); - } - else if (opcode == Protocol::OP_OBJECT_INDICATION) { - object = broker.handleObjectIndication(buffer, sequence, true, true); - if (object.get() != 0) - queryResponse->impl->results.push_back(object); - } - else { - QPID_LOG(trace, "QueryContext::handleMessage invalid opcode: " << opcode); - completeContext = true; - } - - return completeContext; -} - -void MethodContext::release() -{ - Mutex::ScopedLock _block(broker.lock); - broker.eventQueue.push_back(broker.eventMethodResponse(userContext, methodResponse)); -} - -bool MethodContext::handleMessage(uint8_t opcode, uint32_t sequence, const string& /*routingKey*/, Buffer& buffer) -{ - if (opcode == Protocol::OP_METHOD_RESPONSE) - methodResponse = broker.handleMethodResponse(buffer, sequence, schema); - else - QPID_LOG(trace, "QueryContext::handleMessage invalid opcode: " << opcode); - - return true; -} - - -//================================================================== -// Wrappers -//================================================================== - -AgentProxy::AgentProxy(AgentProxyImpl* i) : impl(i) {} -AgentProxy::AgentProxy(const AgentProxy& from) : impl(new AgentProxyImpl(*(from.impl))) {} -AgentProxy::~AgentProxy() { delete impl; } -const char* AgentProxy::getLabel() const { return impl->getLabel().c_str(); } -uint32_t AgentProxy::getBrokerBank() const { return impl->getBrokerBank(); } -uint32_t AgentProxy::getAgentBank() const { return impl->getAgentBank(); } - -BrokerProxy::BrokerProxy(Console& console) : impl(new BrokerProxyImpl(*this, console)) {} -BrokerProxy::~BrokerProxy() { delete impl; } -void BrokerProxy::sessionOpened(SessionHandle& sh) { impl->sessionOpened(sh); } -void BrokerProxy::sessionClosed() { impl->sessionClosed(); } -void BrokerProxy::startProtocol() { impl->startProtocol(); } -void BrokerProxy::handleRcvMessage(Message& message) { impl->handleRcvMessage(message); } -bool BrokerProxy::getXmtMessage(Message& item) const { return impl->getXmtMessage(item); } -void BrokerProxy::popXmt() { impl->popXmt(); } -bool BrokerProxy::getEvent(BrokerEvent& event) const { return impl->getEvent(event); } -void BrokerProxy::popEvent() { impl->popEvent(); } -uint32_t BrokerProxy::agentCount() const { return impl->agentCount(); } -const AgentProxy* BrokerProxy::getAgent(uint32_t idx) const { return impl->getAgent(idx); } -void BrokerProxy::sendQuery(const Query& query, void* context, const AgentProxy* agent) { impl->sendQuery(query, context, agent); } - -MethodResponse::MethodResponse(const MethodResponse& from) : impl(new MethodResponseImpl(*(from.impl))) {} -MethodResponse::MethodResponse(MethodResponseImpl* i) : impl(i) {} -MethodResponse::~MethodResponse() {} -uint32_t MethodResponse::getStatus() const { return impl->getStatus(); } -const Value* MethodResponse::getException() const { return impl->getException(); } -const Value* MethodResponse::getArgs() const { return impl->getArgs(); } - -QueryResponse::QueryResponse(QueryResponseImpl* i) : impl(i) {} -QueryResponse::~QueryResponse() {} -uint32_t QueryResponse::getStatus() const { return impl->getStatus(); } -const Value* QueryResponse::getException() const { return impl->getException(); } -uint32_t QueryResponse::getObjectCount() const { return impl->getObjectCount(); } -const Object* QueryResponse::getObject(uint32_t idx) const { return impl->getObject(idx); } - diff --git a/cpp/src/qmf/engine/BrokerProxyImpl.h b/cpp/src/qmf/engine/BrokerProxyImpl.h deleted file mode 100644 index 0542b67dbb..0000000000 --- a/cpp/src/qmf/engine/BrokerProxyImpl.h +++ /dev/null @@ -1,241 +0,0 @@ -#ifndef _QmfEngineBrokerProxyImpl_ -#define _QmfEngineBrokerProxyImpl_ - -/* - * 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 "qmf/engine/Console.h" -#include "qmf/engine/ObjectImpl.h" -#include "qmf/engine/EventImpl.h" -#include "qmf/engine/SchemaImpl.h" -#include "qmf/engine/ValueImpl.h" -#include "qmf/engine/QueryImpl.h" -#include "qmf/engine/SequenceManager.h" -#include "qmf/engine/MessageImpl.h" -#include "qpid/framing/Buffer.h" -#include "qpid/framing/Uuid.h" -#include "qpid/sys/Mutex.h" -#include "boost/shared_ptr.hpp" -#include "boost/noncopyable.hpp" -#include <memory> -#include <string> -#include <deque> -#include <map> -#include <set> -#include <vector> - -namespace qmf { -namespace engine { - - typedef boost::shared_ptr<MethodResponse> MethodResponsePtr; - struct MethodResponseImpl { - uint32_t status; - const SchemaMethod* schema; - std::auto_ptr<Value> exception; - std::auto_ptr<Value> arguments; - - MethodResponseImpl(const MethodResponseImpl& from); - MethodResponseImpl(qpid::framing::Buffer& buf, const SchemaMethod* schema); - MethodResponseImpl(uint32_t status, const std::string& text); - static MethodResponse* factory(qpid::framing::Buffer& buf, const SchemaMethod* schema); - static MethodResponse* factory(uint32_t status, const std::string& text); - ~MethodResponseImpl() {} - uint32_t getStatus() const { return status; } - const Value* getException() const { return exception.get(); } - const Value* getArgs() const { return arguments.get(); } - }; - - typedef boost::shared_ptr<QueryResponse> QueryResponsePtr; - struct QueryResponseImpl { - uint32_t status; - std::auto_ptr<Value> exception; - std::vector<ObjectPtr> results; - - QueryResponseImpl() : status(0) {} - static QueryResponse* factory() { - QueryResponseImpl* impl(new QueryResponseImpl()); - return new QueryResponse(impl); - } - ~QueryResponseImpl() {} - uint32_t getStatus() const { return status; } - const Value* getException() const { return exception.get(); } - uint32_t getObjectCount() const { return results.size(); } - const Object* getObject(uint32_t idx) const; - }; - - struct BrokerEventImpl { - typedef boost::shared_ptr<BrokerEventImpl> Ptr; - BrokerEvent::EventKind kind; - std::string name; - std::string exchange; - std::string bindingKey; - void* context; - QueryResponsePtr queryResponse; - MethodResponsePtr methodResponse; - - BrokerEventImpl(BrokerEvent::EventKind k) : kind(k), context(0) {} - ~BrokerEventImpl() {} - BrokerEvent copy(); - }; - - typedef boost::shared_ptr<AgentProxy> AgentProxyPtr; - struct AgentProxyImpl { - Console& console; - BrokerProxy& broker; - uint32_t agentBank; - std::string label; - std::set<uint32_t> inFlightSequences; - - AgentProxyImpl(Console& c, BrokerProxy& b, uint32_t ab, const std::string& l) : console(c), broker(b), agentBank(ab), label(l) {} - static AgentProxy* factory(Console& c, BrokerProxy& b, uint32_t ab, const std::string& l) { - AgentProxyImpl* impl(new AgentProxyImpl(c, b, ab, l)); - return new AgentProxy(impl); - } - ~AgentProxyImpl() {} - const std::string& getLabel() const { return label; } - uint32_t getBrokerBank() const { return 1; } - uint32_t getAgentBank() const { return agentBank; } - void addSequence(uint32_t seq) { inFlightSequences.insert(seq); } - void delSequence(uint32_t seq) { inFlightSequences.erase(seq); } - void releaseInFlight(SequenceManager& seqMgr) { - for (std::set<uint32_t>::iterator iter = inFlightSequences.begin(); iter != inFlightSequences.end(); iter++) - seqMgr.release(*iter); - inFlightSequences.clear(); - } - }; - - class BrokerProxyImpl : public boost::noncopyable { - public: - BrokerProxyImpl(BrokerProxy& pub, Console& _console); - ~BrokerProxyImpl() {} - - void sessionOpened(SessionHandle& sh); - void sessionClosed(); - void startProtocol(); - - void sendBufferLH(qpid::framing::Buffer& buf, const std::string& destination, const std::string& routingKey); - void handleRcvMessage(Message& message); - bool getXmtMessage(Message& item) const; - void popXmt(); - - bool getEvent(BrokerEvent& event) const; - void popEvent(); - - uint32_t agentCount() const; - const AgentProxy* getAgent(uint32_t idx) const; - void sendQuery(const Query& query, void* context, const AgentProxy* agent); - bool sendGetRequestLH(SequenceContext::Ptr queryContext, const Query& query, const AgentProxy* agent); - std::string encodeMethodArguments(const SchemaMethod* schema, const Value* args, qpid::framing::Buffer& buffer); - std::string encodedSizeMethodArguments(const SchemaMethod* schema, const Value* args, uint32_t& size); - void sendMethodRequest(ObjectId* oid, const SchemaObjectClass* cls, const std::string& method, const Value* args, void* context); - - void addBinding(const std::string& exchange, const std::string& key); - void staticRelease() { decOutstanding(); } - - private: - friend struct StaticContext; - friend struct QueryContext; - friend struct MethodContext; - BrokerProxy& publicObject; - mutable qpid::sys::Mutex lock; - Console& console; - std::string queueName; - qpid::framing::Uuid brokerId; - SequenceManager seqMgr; - uint32_t requestsOutstanding; - bool topicBound; - std::map<uint32_t, AgentProxyPtr> agentList; - std::deque<MessageImpl::Ptr> xmtQueue; - std::deque<BrokerEventImpl::Ptr> eventQueue; - -# define MA_BUFFER_SIZE 65536 - char outputBuffer[MA_BUFFER_SIZE]; - - BrokerEventImpl::Ptr eventDeclareQueue(const std::string& queueName); - BrokerEventImpl::Ptr eventBind(const std::string& exchange, const std::string& queue, const std::string& key); - BrokerEventImpl::Ptr eventSetupComplete(); - BrokerEventImpl::Ptr eventStable(); - BrokerEventImpl::Ptr eventQueryComplete(void* context, QueryResponsePtr response); - BrokerEventImpl::Ptr eventMethodResponse(void* context, MethodResponsePtr response); - - void handleBrokerResponse(qpid::framing::Buffer& inBuffer, uint32_t seq); - void handlePackageIndication(qpid::framing::Buffer& inBuffer, uint32_t seq); - void handleCommandComplete(qpid::framing::Buffer& inBuffer, uint32_t seq); - void handleClassIndication(qpid::framing::Buffer& inBuffer, uint32_t seq); - MethodResponsePtr handleMethodResponse(qpid::framing::Buffer& inBuffer, uint32_t seq, const SchemaMethod* schema); - void handleHeartbeatIndication(qpid::framing::Buffer& inBuffer, uint32_t seq, const std::string& routingKey); - void handleEventIndication(qpid::framing::Buffer& inBuffer, uint32_t seq); - void handleSchemaResponse(qpid::framing::Buffer& inBuffer, uint32_t seq); - ObjectPtr handleObjectIndication(qpid::framing::Buffer& inBuffer, uint32_t seq, bool prop, bool stat); - void updateAgentList(ObjectPtr obj); - void incOutstandingLH(); - void decOutstanding(); - }; - - // - // StaticContext is used to handle: - // - // 1) Responses to console-level requests (for schema info, etc.) - // 2) Unsolicited messages from agents (events, published updates, etc.) - // - struct StaticContext : public SequenceContext { - StaticContext(BrokerProxyImpl& b) : broker(b) {} - virtual ~StaticContext() {} - void reserve() {} - void release() { broker.staticRelease(); } - bool handleMessage(uint8_t opcode, uint32_t sequence, const std::string& routingKey, qpid::framing::Buffer& buffer); - BrokerProxyImpl& broker; - }; - - // - // QueryContext is used to track and handle responses associated with a single Get Query - // - struct QueryContext : public SequenceContext { - QueryContext(BrokerProxyImpl& b, void* u) : - broker(b), userContext(u), requestsOutstanding(0), queryResponse(QueryResponseImpl::factory()) {} - virtual ~QueryContext() {} - void reserve(); - void release(); - bool handleMessage(uint8_t opcode, uint32_t sequence, const std::string& routingKey, qpid::framing::Buffer& buffer); - - mutable qpid::sys::Mutex lock; - BrokerProxyImpl& broker; - void* userContext; - uint32_t requestsOutstanding; - QueryResponsePtr queryResponse; - }; - - struct MethodContext : public SequenceContext { - MethodContext(BrokerProxyImpl& b, void* u, const SchemaMethod* s) : broker(b), userContext(u), schema(s) {} - virtual ~MethodContext() {} - void reserve() {} - void release(); - bool handleMessage(uint8_t opcode, uint32_t sequence, const std::string& routingKey, qpid::framing::Buffer& buffer); - - BrokerProxyImpl& broker; - void* userContext; - const SchemaMethod* schema; - MethodResponsePtr methodResponse; - }; - -} -} - -#endif - diff --git a/cpp/src/qmf/engine/ConnectionSettingsImpl.cpp b/cpp/src/qmf/engine/ConnectionSettingsImpl.cpp deleted file mode 100644 index 22a65f28ca..0000000000 --- a/cpp/src/qmf/engine/ConnectionSettingsImpl.cpp +++ /dev/null @@ -1,278 +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 "qmf/engine/ConnectionSettingsImpl.h" -#include "qmf/engine/Typecode.h" - -using namespace std; -using namespace qmf::engine; -using namespace qpid; - -const string attrProtocol("protocol"); -const string attrHost("host"); -const string attrPort("port"); -const string attrVirtualhost("virtualhost"); -const string attrUsername("username"); -const string attrPassword("password"); -const string attrMechanism("mechanism"); -const string attrLocale("locale"); -const string attrHeartbeat("heartbeat"); -const string attrMaxChannels("maxChannels"); -const string attrMaxFrameSize("maxFrameSize"); -const string attrBounds("bounds"); -const string attrTcpNoDelay("tcpNoDelay"); -const string attrService("service"); -const string attrMinSsf("minSsf"); -const string attrMaxSsf("maxSsf"); -const string attrRetryDelayMin("retryDelayMin"); -const string attrRetryDelayMax("retryDelayMax"); -const string attrRetryDelayFactor("retryDelayFactor"); -const string attrSendUserId("sendUserId"); - -ConnectionSettingsImpl::ConnectionSettingsImpl() : - retryDelayMin(1), retryDelayMax(64), retryDelayFactor(2), sendUserId(true) -{ -} - -ConnectionSettingsImpl::ConnectionSettingsImpl(const string& /*url*/) : - retryDelayMin(1), retryDelayMax(64), retryDelayFactor(2), sendUserId(true) -{ - // TODO: Parse the URL -} - -bool ConnectionSettingsImpl::setAttr(const string& key, const Value& value) -{ - if (key == attrProtocol) clientSettings.protocol = value.asString(); - else if (key == attrHost) clientSettings.host = value.asString(); - else if (key == attrPort) clientSettings.port = value.asUint(); - else if (key == attrVirtualhost) clientSettings.virtualhost = value.asString(); - else if (key == attrUsername) clientSettings.username = value.asString(); - else if (key == attrPassword) clientSettings.password = value.asString(); - else if (key == attrMechanism) clientSettings.mechanism = value.asString(); - else if (key == attrLocale) clientSettings.locale = value.asString(); - else if (key == attrHeartbeat) clientSettings.heartbeat = value.asUint(); - else if (key == attrMaxChannels) clientSettings.maxChannels = value.asUint(); - else if (key == attrMaxFrameSize) clientSettings.maxFrameSize = value.asUint(); - else if (key == attrBounds) clientSettings.bounds = value.asUint(); - else if (key == attrTcpNoDelay) clientSettings.tcpNoDelay = value.asBool(); - else if (key == attrService) clientSettings.service = value.asString(); - else if (key == attrMinSsf) clientSettings.minSsf = value.asUint(); - else if (key == attrMaxSsf) clientSettings.maxSsf = value.asUint(); - - else if (key == attrRetryDelayMin) retryDelayMin = value.asUint(); - else if (key == attrRetryDelayMax) retryDelayMax = value.asUint(); - else if (key == attrRetryDelayFactor) retryDelayFactor = value.asUint(); - else if (key == attrSendUserId) sendUserId = value.asBool(); - else - return false; - return true; -} - -Value ConnectionSettingsImpl::getAttr(const string& key) const -{ - Value strval(TYPE_LSTR); - Value intval(TYPE_UINT32); - Value boolval(TYPE_BOOL); - - if (key == attrProtocol) { - strval.setString(clientSettings.protocol.c_str()); - return strval; - } - - if (key == attrHost) { - strval.setString(clientSettings.host.c_str()); - return strval; - } - - if (key == attrPort) { - intval.setUint(clientSettings.port); - return intval; - } - - if (key == attrVirtualhost) { - strval.setString(clientSettings.virtualhost.c_str()); - return strval; - } - - if (key == attrUsername) { - strval.setString(clientSettings.username.c_str()); - return strval; - } - - if (key == attrPassword) { - strval.setString(clientSettings.password.c_str()); - return strval; - } - - if (key == attrMechanism) { - strval.setString(clientSettings.mechanism.c_str()); - return strval; - } - - if (key == attrLocale) { - strval.setString(clientSettings.locale.c_str()); - return strval; - } - - if (key == attrHeartbeat) { - intval.setUint(clientSettings.heartbeat); - return intval; - } - - if (key == attrMaxChannels) { - intval.setUint(clientSettings.maxChannels); - return intval; - } - - if (key == attrMaxFrameSize) { - intval.setUint(clientSettings.maxFrameSize); - return intval; - } - - if (key == attrBounds) { - intval.setUint(clientSettings.bounds); - return intval; - } - - if (key == attrTcpNoDelay) { - boolval.setBool(clientSettings.tcpNoDelay); - return boolval; - } - - if (key == attrService) { - strval.setString(clientSettings.service.c_str()); - return strval; - } - - if (key == attrMinSsf) { - intval.setUint(clientSettings.minSsf); - return intval; - } - - if (key == attrMaxSsf) { - intval.setUint(clientSettings.maxSsf); - return intval; - } - - if (key == attrRetryDelayMin) { - intval.setUint(retryDelayMin); - return intval; - } - - if (key == attrRetryDelayMax) { - intval.setUint(retryDelayMax); - return intval; - } - - if (key == attrRetryDelayFactor) { - intval.setUint(retryDelayFactor); - return intval; - } - - if (key == attrSendUserId) { - boolval.setBool(sendUserId); - return boolval; - } - - return strval; -} - -const string& ConnectionSettingsImpl::getAttrString() const -{ - // TODO: build and return attribute string - return attrString; -} - -void ConnectionSettingsImpl::transportTcp(uint16_t port) -{ - clientSettings.protocol = "tcp"; - clientSettings.port = port; -} - -void ConnectionSettingsImpl::transportSsl(uint16_t port) -{ - clientSettings.protocol = "ssl"; - clientSettings.port = port; -} - -void ConnectionSettingsImpl::transportRdma(uint16_t port) -{ - clientSettings.protocol = "rdma"; - clientSettings.port = port; -} - -void ConnectionSettingsImpl::authAnonymous(const string& username) -{ - clientSettings.mechanism = "ANONYMOUS"; - clientSettings.username = username; -} - -void ConnectionSettingsImpl::authPlain(const string& username, const string& password) -{ - clientSettings.mechanism = "PLAIN"; - clientSettings.username = username; - clientSettings.password = password; -} - -void ConnectionSettingsImpl::authGssapi(const string& serviceName, uint32_t minSsf, uint32_t maxSsf) -{ - clientSettings.mechanism = "GSSAPI"; - clientSettings.service = serviceName; - clientSettings.minSsf = minSsf; - clientSettings.maxSsf = maxSsf; -} - -void ConnectionSettingsImpl::setRetry(int delayMin, int delayMax, int delayFactor) -{ - retryDelayMin = delayMin; - retryDelayMax = delayMax; - retryDelayFactor = delayFactor; -} - -const client::ConnectionSettings& ConnectionSettingsImpl::getClientSettings() const -{ - return clientSettings; -} - -void ConnectionSettingsImpl::getRetrySettings(int* min, int* max, int* factor) const -{ - *min = retryDelayMin; - *max = retryDelayMax; - *factor = retryDelayFactor; -} - -//================================================================== -// Wrappers -//================================================================== - -ConnectionSettings::ConnectionSettings(const ConnectionSettings& from) { impl = new ConnectionSettingsImpl(*from.impl); } -ConnectionSettings::ConnectionSettings() { impl = new ConnectionSettingsImpl(); } -ConnectionSettings::ConnectionSettings(const char* url) { impl = new ConnectionSettingsImpl(url); } -ConnectionSettings::~ConnectionSettings() { delete impl; } -bool ConnectionSettings::setAttr(const char* key, const Value& value) { return impl->setAttr(key, value); } -Value ConnectionSettings::getAttr(const char* key) const { return impl->getAttr(key); } -const char* ConnectionSettings::getAttrString() const { return impl->getAttrString().c_str(); } -void ConnectionSettings::transportTcp(uint16_t port) { impl->transportTcp(port); } -void ConnectionSettings::transportSsl(uint16_t port) { impl->transportSsl(port); } -void ConnectionSettings::transportRdma(uint16_t port) { impl->transportRdma(port); } -void ConnectionSettings::authAnonymous(const char* username) { impl->authAnonymous(username); } -void ConnectionSettings::authPlain(const char* username, const char* password) { impl->authPlain(username, password); } -void ConnectionSettings::authGssapi(const char* serviceName, uint32_t minSsf, uint32_t maxSsf) { impl->authGssapi(serviceName, minSsf, maxSsf); } -void ConnectionSettings::setRetry(int delayMin, int delayMax, int delayFactor) { impl->setRetry(delayMin, delayMax, delayFactor); } - diff --git a/cpp/src/qmf/engine/ConnectionSettingsImpl.h b/cpp/src/qmf/engine/ConnectionSettingsImpl.h deleted file mode 100644 index 98bf87868b..0000000000 --- a/cpp/src/qmf/engine/ConnectionSettingsImpl.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef _QmfEngineConnectionSettingsImpl_ -#define _QmfEngineConnectionSettingsImpl_ - -/* - * 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 "qmf/engine/ConnectionSettings.h" -#include "qmf/engine/Value.h" -#include "qpid/client/ConnectionSettings.h" -#include <string> -#include <map> - -namespace qmf { -namespace engine { - - class ConnectionSettingsImpl { - qpid::client::ConnectionSettings clientSettings; - mutable std::string attrString; - int retryDelayMin; - int retryDelayMax; - int retryDelayFactor; - bool sendUserId; - - public: - ConnectionSettingsImpl(); - ConnectionSettingsImpl(const std::string& url); - ~ConnectionSettingsImpl() {} - bool setAttr(const std::string& key, const Value& value); - Value getAttr(const std::string& key) const; - const std::string& getAttrString() const; - void transportTcp(uint16_t port); - void transportSsl(uint16_t port); - void transportRdma(uint16_t port); - void authAnonymous(const std::string& username); - void authPlain(const std::string& username, const std::string& password); - void authGssapi(const std::string& serviceName, uint32_t minSsf, uint32_t maxSsf); - void setRetry(int delayMin, int delayMax, int delayFactor); - - const qpid::client::ConnectionSettings& getClientSettings() const; - void getRetrySettings(int* delayMin, int* delayMax, int* delayFactor) const; - bool getSendUserId() const { return sendUserId; } - }; - -} -} - -#endif diff --git a/cpp/src/qmf/engine/ConsoleImpl.cpp b/cpp/src/qmf/engine/ConsoleImpl.cpp deleted file mode 100644 index 4a5da31bdc..0000000000 --- a/cpp/src/qmf/engine/ConsoleImpl.cpp +++ /dev/null @@ -1,458 +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 "qmf/engine/ConsoleImpl.h" -#include "qmf/engine/MessageImpl.h" -#include "qmf/engine/SchemaImpl.h" -#include "qmf/engine/Typecode.h" -#include "qmf/engine/ObjectImpl.h" -#include "qmf/engine/ObjectIdImpl.h" -#include "qmf/engine/QueryImpl.h" -#include "qmf/engine/ValueImpl.h" -#include "qmf/engine/Protocol.h" -#include "qmf/engine/SequenceManager.h" -#include "qmf/engine/BrokerProxyImpl.h" -#include <qpid/framing/Buffer.h> -#include <qpid/framing/Uuid.h> -#include <qpid/framing/FieldTable.h> -#include <qpid/framing/FieldValue.h> -#include <qpid/log/Statement.h> -#include <qpid/sys/Time.h> -#include <qpid/sys/SystemInfo.h> -#include <string.h> -#include <iostream> -#include <fstream> - -using namespace std; -using namespace qmf::engine; -using namespace qpid::framing; -using namespace qpid::sys; - -namespace { - const char* QMF_EXCHANGE = "qpid.management"; -} - -#define STRING_REF(s) {if (!s.empty()) item.s = const_cast<char*>(s.c_str());} - -ConsoleEvent ConsoleEventImpl::copy() -{ - ConsoleEvent item; - - ::memset(&item, 0, sizeof(ConsoleEvent)); - item.kind = kind; - item.agent = agent.get(); - item.classKey = classKey; - item.object = object.get(); - item.context = context; - item.event = event.get(); - item.timestamp = timestamp; - item.hasProps = hasProps; - item.hasStats = hasStats; - - STRING_REF(name); - - return item; -} - -ConsoleImpl::ConsoleImpl(const ConsoleSettings& s) : settings(s) -{ - bindingList.push_back(pair<string, string>(string(), "schema.#")); - if (settings.rcvObjects && settings.rcvEvents && settings.rcvHeartbeats && !settings.userBindings) { - bindingList.push_back(pair<string, string>(string(), "console.#")); - } else { - if (settings.rcvObjects && !settings.userBindings) - bindingList.push_back(pair<string, string>(string(), "console.obj.#")); - else - bindingList.push_back(pair<string, string>(string(), "console.obj.*.*.org.apache.qpid.broker.agent")); - if (settings.rcvEvents) - bindingList.push_back(pair<string, string>(string(), "console.event.#")); - if (settings.rcvHeartbeats) - bindingList.push_back(pair<string, string>(string(), "console.heartbeat.#")); - } -} - -ConsoleImpl::~ConsoleImpl() -{ - // This function intentionally left blank. -} - -bool ConsoleImpl::getEvent(ConsoleEvent& event) const -{ - Mutex::ScopedLock _lock(lock); - if (eventQueue.empty()) - return false; - event = eventQueue.front()->copy(); - return true; -} - -void ConsoleImpl::popEvent() -{ - Mutex::ScopedLock _lock(lock); - if (!eventQueue.empty()) - eventQueue.pop_front(); -} - -void ConsoleImpl::addConnection(BrokerProxy& broker, void* /*context*/) -{ - Mutex::ScopedLock _lock(lock); - brokerList.push_back(broker.impl); -} - -void ConsoleImpl::delConnection(BrokerProxy& broker) -{ - Mutex::ScopedLock _lock(lock); - for (vector<BrokerProxyImpl*>::iterator iter = brokerList.begin(); - iter != brokerList.end(); iter++) - if (*iter == broker.impl) { - brokerList.erase(iter); - break; - } -} - -uint32_t ConsoleImpl::packageCount() const -{ - Mutex::ScopedLock _lock(lock); - return packages.size(); -} - -const string& ConsoleImpl::getPackageName(uint32_t idx) const -{ - const static string empty; - - Mutex::ScopedLock _lock(lock); - if (idx >= packages.size()) - return empty; - - PackageList::const_iterator iter = packages.begin(); - for (uint32_t i = 0; i < idx; i++) iter++; - return iter->first; -} - -uint32_t ConsoleImpl::classCount(const char* packageName) const -{ - Mutex::ScopedLock _lock(lock); - PackageList::const_iterator pIter = packages.find(packageName); - if (pIter == packages.end()) - return 0; - - const ObjectClassList& oList = pIter->second.first; - const EventClassList& eList = pIter->second.second; - - return oList.size() + eList.size(); -} - -const SchemaClassKey* ConsoleImpl::getClass(const char* packageName, uint32_t idx) const -{ - Mutex::ScopedLock _lock(lock); - PackageList::const_iterator pIter = packages.find(packageName); - if (pIter == packages.end()) - return 0; - - const ObjectClassList& oList = pIter->second.first; - const EventClassList& eList = pIter->second.second; - uint32_t count = 0; - - for (ObjectClassList::const_iterator oIter = oList.begin(); - oIter != oList.end(); oIter++) { - if (count == idx) - return oIter->second->getClassKey(); - count++; - } - - for (EventClassList::const_iterator eIter = eList.begin(); - eIter != eList.end(); eIter++) { - if (count == idx) - return eIter->second->getClassKey(); - count++; - } - - return 0; -} - -ClassKind ConsoleImpl::getClassKind(const SchemaClassKey* key) const -{ - Mutex::ScopedLock _lock(lock); - PackageList::const_iterator pIter = packages.find(key->getPackageName()); - if (pIter == packages.end()) - return CLASS_OBJECT; - - const EventClassList& eList = pIter->second.second; - if (eList.find(key) != eList.end()) - return CLASS_EVENT; - return CLASS_OBJECT; -} - -const SchemaObjectClass* ConsoleImpl::getObjectClass(const SchemaClassKey* key) const -{ - Mutex::ScopedLock _lock(lock); - PackageList::const_iterator pIter = packages.find(key->getPackageName()); - if (pIter == packages.end()) - return 0; - - const ObjectClassList& oList = pIter->second.first; - ObjectClassList::const_iterator iter = oList.find(key); - if (iter == oList.end()) - return 0; - return iter->second; -} - -const SchemaEventClass* ConsoleImpl::getEventClass(const SchemaClassKey* key) const -{ - Mutex::ScopedLock _lock(lock); - PackageList::const_iterator pIter = packages.find(key->getPackageName()); - if (pIter == packages.end()) - return 0; - - const EventClassList& eList = pIter->second.second; - EventClassList::const_iterator iter = eList.find(key); - if (iter == eList.end()) - return 0; - return iter->second; -} - -void ConsoleImpl::bindPackage(const char* packageName) -{ - stringstream key; - key << "console.obj.*.*." << packageName << ".#"; - Mutex::ScopedLock _lock(lock); - bindingList.push_back(pair<string, string>(string(), key.str())); - for (vector<BrokerProxyImpl*>::iterator iter = brokerList.begin(); - iter != brokerList.end(); iter++) - (*iter)->addBinding(QMF_EXCHANGE, key.str()); -} - -void ConsoleImpl::bindClass(const SchemaClassKey* classKey) -{ - stringstream key; - key << "console.obj.*.*." << classKey->getPackageName() << "." << classKey->getClassName() << ".#"; - Mutex::ScopedLock _lock(lock); - bindingList.push_back(pair<string, string>(string(), key.str())); - for (vector<BrokerProxyImpl*>::iterator iter = brokerList.begin(); - iter != brokerList.end(); iter++) - (*iter)->addBinding(QMF_EXCHANGE, key.str()); -} - -void ConsoleImpl::bindClass(const char* packageName, const char* className) -{ - stringstream key; - key << "console.obj.*.*." << packageName << "." << className << ".#"; - Mutex::ScopedLock _lock(lock); - bindingList.push_back(pair<string, string>(string(), key.str())); - for (vector<BrokerProxyImpl*>::iterator iter = brokerList.begin(); - iter != brokerList.end(); iter++) - (*iter)->addBinding(QMF_EXCHANGE, key.str()); -} - - -void ConsoleImpl::bindEvent(const SchemaClassKey* classKey) -{ - bindEvent(classKey->getPackageName(), classKey->getClassName()); -} - -void ConsoleImpl::bindEvent(const char* packageName, const char* eventName) -{ - if (!settings.userBindings) throw qpid::Exception("Console not configured for userBindings."); - if (settings.rcvEvents) throw qpid::Exception("Console already configured to receive all events."); - - stringstream key; - key << "console.event.*.*." << packageName; - if (eventName && *eventName) { - key << "." << eventName << ".#"; - } else { - key << ".#"; - } - - Mutex::ScopedLock _lock(lock); - bindingList.push_back(pair<string, string>(string(), key.str())); - for (vector<BrokerProxyImpl*>::iterator iter = brokerList.begin(); - iter != brokerList.end(); iter++) - (*iter)->addBinding(QMF_EXCHANGE, key.str()); -} - -/* -void ConsoleImpl::startSync(const Query& query, void* context, SyncQuery& sync) -{ -} - -void ConsoleImpl::touchSync(SyncQuery& sync) -{ -} - -void ConsoleImpl::endSync(SyncQuery& sync) -{ -} -*/ - -void ConsoleImpl::learnPackage(const string& packageName) -{ - Mutex::ScopedLock _lock(lock); - if (packages.find(packageName) == packages.end()) { - packages.insert(pair<string, pair<ObjectClassList, EventClassList> > - (packageName, pair<ObjectClassList, EventClassList>(ObjectClassList(), EventClassList()))); - eventNewPackage(packageName); - } -} - -void ConsoleImpl::learnClass(SchemaObjectClass* cls) -{ - Mutex::ScopedLock _lock(lock); - const SchemaClassKey* key = cls->getClassKey(); - PackageList::iterator pIter = packages.find(key->getPackageName()); - if (pIter == packages.end()) - return; - - ObjectClassList& list = pIter->second.first; - if (list.find(key) == list.end()) { - list[key] = cls; - eventNewClass(key); - } -} - -void ConsoleImpl::learnClass(SchemaEventClass* cls) -{ - Mutex::ScopedLock _lock(lock); - const SchemaClassKey* key = cls->getClassKey(); - PackageList::iterator pIter = packages.find(key->getPackageName()); - if (pIter == packages.end()) - return; - - EventClassList& list = pIter->second.second; - if (list.find(key) == list.end()) { - list[key] = cls; - eventNewClass(key); - } -} - -bool ConsoleImpl::haveClass(const SchemaClassKey* key) const -{ - Mutex::ScopedLock _lock(lock); - PackageList::const_iterator pIter = packages.find(key->getPackageName()); - if (pIter == packages.end()) - return false; - - const ObjectClassList& oList = pIter->second.first; - const EventClassList& eList = pIter->second.second; - - return oList.find(key) != oList.end() || eList.find(key) != eList.end(); -} - -SchemaObjectClass* ConsoleImpl::getSchema(const SchemaClassKey* key) const -{ - Mutex::ScopedLock _lock(lock); - PackageList::const_iterator pIter = packages.find(key->getPackageName()); - if (pIter == packages.end()) - return 0; - - const ObjectClassList& oList = pIter->second.first; - ObjectClassList::const_iterator iter = oList.find(key); - if (iter == oList.end()) - return 0; - - return iter->second; -} - -void ConsoleImpl::eventAgentAdded(boost::shared_ptr<AgentProxy> agent) -{ - ConsoleEventImpl::Ptr event(new ConsoleEventImpl(ConsoleEvent::AGENT_ADDED)); - event->agent = agent; - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(event); -} - -void ConsoleImpl::eventAgentDeleted(boost::shared_ptr<AgentProxy> agent) -{ - ConsoleEventImpl::Ptr event(new ConsoleEventImpl(ConsoleEvent::AGENT_DELETED)); - event->agent = agent; - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(event); -} - -void ConsoleImpl::eventNewPackage(const string& packageName) -{ - ConsoleEventImpl::Ptr event(new ConsoleEventImpl(ConsoleEvent::NEW_PACKAGE)); - event->name = packageName; - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(event); -} - -void ConsoleImpl::eventNewClass(const SchemaClassKey* key) -{ - ConsoleEventImpl::Ptr event(new ConsoleEventImpl(ConsoleEvent::NEW_CLASS)); - event->classKey = key; - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(event); -} - -void ConsoleImpl::eventObjectUpdate(ObjectPtr object, bool prop, bool stat) -{ - ConsoleEventImpl::Ptr event(new ConsoleEventImpl(ConsoleEvent::OBJECT_UPDATE)); - event->object = object; - event->hasProps = prop; - event->hasStats = stat; - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(event); -} - -void ConsoleImpl::eventAgentHeartbeat(boost::shared_ptr<AgentProxy> agent, uint64_t timestamp) -{ - ConsoleEventImpl::Ptr event(new ConsoleEventImpl(ConsoleEvent::AGENT_HEARTBEAT)); - event->agent = agent; - event->timestamp = timestamp; - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(event); -} - - -void ConsoleImpl::eventEventReceived(EventPtr event) -{ - ConsoleEventImpl::Ptr console_event(new ConsoleEventImpl(ConsoleEvent::EVENT_RECEIVED)); - console_event->event = event; - Mutex::ScopedLock _lock(lock); - eventQueue.push_back(console_event); -} - -//================================================================== -// Wrappers -//================================================================== - -Console::Console(const ConsoleSettings& settings) : impl(new ConsoleImpl(settings)) {} -Console::~Console() { delete impl; } -bool Console::getEvent(ConsoleEvent& event) const { return impl->getEvent(event); } -void Console::popEvent() { impl->popEvent(); } -void Console::addConnection(BrokerProxy& broker, void* context) { impl->addConnection(broker, context); } -void Console::delConnection(BrokerProxy& broker) { impl->delConnection(broker); } -uint32_t Console::packageCount() const { return impl->packageCount(); } -const char* Console::getPackageName(uint32_t idx) const { return impl->getPackageName(idx).c_str(); } -uint32_t Console::classCount(const char* packageName) const { return impl->classCount(packageName); } -const SchemaClassKey* Console::getClass(const char* packageName, uint32_t idx) const { return impl->getClass(packageName, idx); } -ClassKind Console::getClassKind(const SchemaClassKey* key) const { return impl->getClassKind(key); } -const SchemaObjectClass* Console::getObjectClass(const SchemaClassKey* key) const { return impl->getObjectClass(key); } -const SchemaEventClass* Console::getEventClass(const SchemaClassKey* key) const { return impl->getEventClass(key); } -void Console::bindPackage(const char* packageName) { impl->bindPackage(packageName); } -void Console::bindClass(const SchemaClassKey* key) { impl->bindClass(key); } -void Console::bindClass(const char* packageName, const char* className) { impl->bindClass(packageName, className); } - -void Console::bindEvent(const SchemaClassKey *key) { impl->bindEvent(key); } -void Console::bindEvent(const char* packageName, const char* eventName) { impl->bindEvent(packageName, eventName); } - -//void Console::startSync(const Query& query, void* context, SyncQuery& sync) { impl->startSync(query, context, sync); } -//void Console::touchSync(SyncQuery& sync) { impl->touchSync(sync); } -//void Console::endSync(SyncQuery& sync) { impl->endSync(sync); } - - diff --git a/cpp/src/qmf/engine/ConsoleImpl.h b/cpp/src/qmf/engine/ConsoleImpl.h deleted file mode 100644 index 0c27fdabcd..0000000000 --- a/cpp/src/qmf/engine/ConsoleImpl.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef _QmfEngineConsoleEngineImpl_ -#define _QmfEngineConsoleEngineImpl_ - -/* - * 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 "qmf/engine/Console.h" -#include "qmf/engine/MessageImpl.h" -#include "qmf/engine/SchemaImpl.h" -#include "qmf/engine/Typecode.h" -#include "qmf/engine/ObjectImpl.h" -#include "qmf/engine/ObjectIdImpl.h" -#include "qmf/engine/QueryImpl.h" -#include "qmf/engine/ValueImpl.h" -#include "qmf/engine/Protocol.h" -#include "qmf/engine/SequenceManager.h" -#include "qmf/engine/BrokerProxyImpl.h" -#include <qpid/framing/Buffer.h> -#include <qpid/framing/Uuid.h> -#include <qpid/framing/FieldTable.h> -#include <qpid/framing/FieldValue.h> -#include <qpid/sys/Mutex.h> -#include <qpid/sys/Time.h> -#include <qpid/sys/SystemInfo.h> -#include <string.h> -#include <string> -#include <deque> -#include <map> -#include <vector> -#include <iostream> -#include <fstream> -#include <boost/shared_ptr.hpp> -#include <boost/noncopyable.hpp> - -namespace qmf { -namespace engine { - - struct ConsoleEventImpl { - typedef boost::shared_ptr<ConsoleEventImpl> Ptr; - ConsoleEvent::EventKind kind; - boost::shared_ptr<AgentProxy> agent; - std::string name; - const SchemaClassKey* classKey; - boost::shared_ptr<Object> object; - void* context; - boost::shared_ptr<Event> event; - uint64_t timestamp; - bool hasProps; - bool hasStats; - - ConsoleEventImpl(ConsoleEvent::EventKind k) : - kind(k), classKey(0), context(0), timestamp(0) {} - ~ConsoleEventImpl() {} - ConsoleEvent copy(); - }; - - class ConsoleImpl : public boost::noncopyable { - public: - ConsoleImpl(const ConsoleSettings& settings = ConsoleSettings()); - ~ConsoleImpl(); - - bool getEvent(ConsoleEvent& event) const; - void popEvent(); - - void addConnection(BrokerProxy& broker, void* context); - void delConnection(BrokerProxy& broker); - - uint32_t packageCount() const; - const std::string& getPackageName(uint32_t idx) const; - - uint32_t classCount(const char* packageName) const; - const SchemaClassKey* getClass(const char* packageName, uint32_t idx) const; - - ClassKind getClassKind(const SchemaClassKey* key) const; - const SchemaObjectClass* getObjectClass(const SchemaClassKey* key) const; - const SchemaEventClass* getEventClass(const SchemaClassKey* key) const; - - void bindPackage(const char* packageName); - void bindClass(const SchemaClassKey* key); - void bindClass(const char* packageName, const char* className); - void bindEvent(const SchemaClassKey* key); - void bindEvent(const char* packageName, const char* eventName); - - /* - void startSync(const Query& query, void* context, SyncQuery& sync); - void touchSync(SyncQuery& sync); - void endSync(SyncQuery& sync); - */ - - private: - friend class BrokerProxyImpl; - friend struct StaticContext; - const ConsoleSettings& settings; - mutable qpid::sys::Mutex lock; - std::deque<ConsoleEventImpl::Ptr> eventQueue; - std::vector<BrokerProxyImpl*> brokerList; - std::vector<std::pair<std::string, std::string> > bindingList; // exchange/key (empty exchange => QMF_EXCHANGE) - - // Declare a compare class for the class maps that compares the dereferenced - // class key pointers. The default behavior would be to compare the pointer - // addresses themselves. - struct KeyCompare { - bool operator()(const SchemaClassKey* left, const SchemaClassKey* right) const { - return *left < *right; - } - }; - - typedef std::map<const SchemaClassKey*, SchemaObjectClass*, KeyCompare> ObjectClassList; - typedef std::map<const SchemaClassKey*, SchemaEventClass*, KeyCompare> EventClassList; - typedef std::map<std::string, std::pair<ObjectClassList, EventClassList> > PackageList; - - PackageList packages; - - void learnPackage(const std::string& packageName); - void learnClass(SchemaObjectClass* cls); - void learnClass(SchemaEventClass* cls); - bool haveClass(const SchemaClassKey* key) const; - SchemaObjectClass* getSchema(const SchemaClassKey* key) const; - - void eventAgentAdded(boost::shared_ptr<AgentProxy> agent); - void eventAgentDeleted(boost::shared_ptr<AgentProxy> agent); - void eventNewPackage(const std::string& packageName); - void eventNewClass(const SchemaClassKey* key); - void eventObjectUpdate(ObjectPtr object, bool prop, bool stat); - void eventAgentHeartbeat(boost::shared_ptr<AgentProxy> agent, uint64_t timestamp); - void eventEventReceived(boost::shared_ptr<Event> event); - }; -} -} - -#endif - diff --git a/cpp/src/qmf/engine/EventImpl.cpp b/cpp/src/qmf/engine/EventImpl.cpp deleted file mode 100644 index 4b034e8e83..0000000000 --- a/cpp/src/qmf/engine/EventImpl.cpp +++ /dev/null @@ -1,120 +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 <qmf/engine/EventImpl.h> -#include <qmf/engine/ValueImpl.h> - -#include <sstream> - -using namespace std; -using namespace qmf::engine; -using qpid::framing::Buffer; - -EventImpl::EventImpl(const SchemaEventClass* type) : eventClass(type), timestamp(0), severity(0) -{ - int argCount = eventClass->getArgumentCount(); - int idx; - - for (idx = 0; idx < argCount; idx++) { - const SchemaArgument* arg = eventClass->getArgument(idx); - arguments[arg->getName()] = ValuePtr(new Value(arg->getType())); - } -} - - -EventImpl::EventImpl(const SchemaEventClass* type, Buffer& buffer) : - eventClass(type), timestamp(0), severity(0) -{ - int argCount = eventClass->getArgumentCount(); - int idx; - - timestamp = buffer.getLongLong(); - severity = buffer.getOctet(); - - for (idx = 0; idx < argCount; idx++) - { - const SchemaArgument *arg = eventClass->getArgument(idx); - Value* pval = ValueImpl::factory(arg->getType(), buffer); - arguments[arg->getName()] = ValuePtr(pval); - } -} - - -Event* EventImpl::factory(const SchemaEventClass* type, Buffer& buffer) -{ - EventImpl* impl(new EventImpl(type, buffer)); - return new Event(impl); -} - - -Value* EventImpl::getValue(const char* key) const -{ - map<string, ValuePtr>::const_iterator iter; - - iter = arguments.find(key); - if (iter != arguments.end()) - return iter->second.get(); - - return 0; -} - - -void EventImpl::encodeSchemaKey(Buffer& buffer) const -{ - buffer.putShortString(eventClass->getClassKey()->getPackageName()); - buffer.putShortString(eventClass->getClassKey()->getClassName()); - buffer.putBin128(const_cast<uint8_t*>(eventClass->getClassKey()->getHash())); -} - - -void EventImpl::encode(Buffer& buffer) const -{ - buffer.putOctet((uint8_t) eventClass->getSeverity()); - - int argCount = eventClass->getArgumentCount(); - for (int idx = 0; idx < argCount; idx++) { - const SchemaArgument* arg = eventClass->getArgument(idx); - ValuePtr value = arguments[arg->getName()]; - value->impl->encode(buffer); - } -} - - -string EventImpl::getRoutingKey(uint32_t brokerBank, uint32_t agentBank) const -{ - stringstream key; - - key << "console.event." << brokerBank << "." << agentBank << "." << - eventClass->getClassKey()->getPackageName() << "." << - eventClass->getClassKey()->getClassName(); - return key.str(); -} - - -//================================================================== -// Wrappers -//================================================================== - -Event::Event(const SchemaEventClass* type) : impl(new EventImpl(type)) {} -Event::Event(EventImpl* i) : impl(i) {} -Event::Event(const Event& from) : impl(new EventImpl(*(from.impl))) {} -Event::~Event() { delete impl; } -const SchemaEventClass* Event::getClass() const { return impl->getClass(); } -Value* Event::getValue(const char* key) const { return impl->getValue(key); } - diff --git a/cpp/src/qmf/engine/EventImpl.h b/cpp/src/qmf/engine/EventImpl.h deleted file mode 100644 index 4046e71ef9..0000000000 --- a/cpp/src/qmf/engine/EventImpl.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _QmfEngineEventImpl_ -#define _QmfEngineEventImpl_ - -/* - * 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 <qmf/engine/Event.h> -#include <qmf/engine/Schema.h> -#include <qpid/framing/Buffer.h> -#include <boost/shared_ptr.hpp> -#include <map> - -namespace qmf { -namespace engine { - - typedef boost::shared_ptr<Event> EventPtr; - - struct EventImpl { - typedef boost::shared_ptr<Value> ValuePtr; - const SchemaEventClass* eventClass; - uint64_t timestamp; - uint8_t severity; - mutable std::map<std::string, ValuePtr> arguments; - - EventImpl(const SchemaEventClass* type); - EventImpl(const SchemaEventClass* type, qpid::framing::Buffer& buffer); - static Event* factory(const SchemaEventClass* type, qpid::framing::Buffer& buffer); - - const SchemaEventClass* getClass() const { return eventClass; } - Value* getValue(const char* key) const; - - void encodeSchemaKey(qpid::framing::Buffer& buffer) const; - void encode(qpid::framing::Buffer& buffer) const; - std::string getRoutingKey(uint32_t brokerBank, uint32_t agentBank) const; - }; - -} -} - -#endif - diff --git a/cpp/src/qmf/engine/MessageImpl.cpp b/cpp/src/qmf/engine/MessageImpl.cpp deleted file mode 100644 index 0047d3eb9d..0000000000 --- a/cpp/src/qmf/engine/MessageImpl.cpp +++ /dev/null @@ -1,43 +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 "qmf/engine/MessageImpl.h" -#include <string.h> - -using namespace std; -using namespace qmf::engine; - -#define STRING_REF(s) {if (!s.empty()) item.s = const_cast<char*>(s.c_str());} - -Message MessageImpl::copy() -{ - Message item; - - ::memset(&item, 0, sizeof(Message)); - item.body = const_cast<char*>(body.c_str()); - item.length = body.length(); - STRING_REF(destination); - STRING_REF(routingKey); - STRING_REF(replyExchange); - STRING_REF(replyKey); - STRING_REF(userId); - - return item; -} - diff --git a/cpp/src/qmf/engine/MessageImpl.h b/cpp/src/qmf/engine/MessageImpl.h deleted file mode 100644 index b91291d2e4..0000000000 --- a/cpp/src/qmf/engine/MessageImpl.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef _QmfEngineMessageImpl_ -#define _QmfEngineMessageImpl_ - -/* - * 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 "qmf/engine/Message.h" -#include <string> -#include <boost/shared_ptr.hpp> - -namespace qmf { -namespace engine { - - struct MessageImpl { - typedef boost::shared_ptr<MessageImpl> Ptr; - std::string body; - std::string destination; - std::string routingKey; - std::string replyExchange; - std::string replyKey; - std::string userId; - - Message copy(); - }; -} -} - -#endif diff --git a/cpp/src/qmf/engine/ObjectIdImpl.cpp b/cpp/src/qmf/engine/ObjectIdImpl.cpp deleted file mode 100644 index 9216f7bac0..0000000000 --- a/cpp/src/qmf/engine/ObjectIdImpl.cpp +++ /dev/null @@ -1,210 +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 "qmf/engine/ObjectIdImpl.h" -#include <stdlib.h> -#include <sstream> - -using namespace std; -using namespace qmf::engine; -using qpid::framing::Buffer; - -void AgentAttachment::setBanks(uint32_t broker, uint32_t agent) -{ - first = - ((uint64_t) (broker & 0x000fffff)) << 28 | - ((uint64_t) (agent & 0x0fffffff)); -} - -ObjectIdImpl::ObjectIdImpl(Buffer& buffer) : agent(0) -{ - decode(buffer); -} - -ObjectIdImpl::ObjectIdImpl(AgentAttachment* a, uint8_t flags, uint16_t seq, uint64_t object) : agent(a) -{ - first = - ((uint64_t) (flags & 0x0f)) << 60 | - ((uint64_t) (seq & 0x0fff)) << 48; - second = object; -} - -ObjectId* ObjectIdImpl::factory(Buffer& buffer) -{ - ObjectIdImpl* impl(new ObjectIdImpl(buffer)); - return new ObjectId(impl); -} - -ObjectId* ObjectIdImpl::factory(AgentAttachment* agent, uint8_t flags, uint16_t seq, uint64_t object) -{ - ObjectIdImpl* impl(new ObjectIdImpl(agent, flags, seq, object)); - return new ObjectId(impl); -} - -void ObjectIdImpl::decode(Buffer& buffer) -{ - first = buffer.getLongLong(); - second = buffer.getLongLong(); -} - -void ObjectIdImpl::encode(Buffer& buffer) const -{ - if (agent == 0) - buffer.putLongLong(first); - else - buffer.putLongLong(first | agent->first); - buffer.putLongLong(second); -} - -void ObjectIdImpl::fromString(const std::string& repr) -{ -#define FIELDS 5 -#if defined (_WIN32) && !defined (atoll) -# define atoll(X) _atoi64(X) -#endif - - std::string copy(repr.c_str()); - char* cText; - char* field[FIELDS]; - bool atFieldStart = true; - int idx = 0; - - cText = const_cast<char*>(copy.c_str()); - for (char* cursor = cText; *cursor; cursor++) { - if (atFieldStart) { - if (idx >= FIELDS) - return; // TODO error - field[idx++] = cursor; - atFieldStart = false; - } else { - if (*cursor == '-') { - *cursor = '\0'; - atFieldStart = true; - } - } - } - - if (idx != FIELDS) - return; // TODO error - - first = (atoll(field[0]) << 60) + - (atoll(field[1]) << 48) + - (atoll(field[2]) << 28) + - atoll(field[3]); - second = atoll(field[4]); - agent = 0; -} - -const string& ObjectIdImpl::asString() const -{ - stringstream val; - - val << (int) getFlags() << "-" << getSequence() << "-" << getBrokerBank() << "-" << - getAgentBank() << "-" << getObjectNum(); - repr = val.str(); - return repr; -} - -#define ACTUAL_FIRST (agent == 0 ? first : first | agent->first) -#define ACTUAL_OTHER (other.agent == 0 ? other.first : other.first | other.agent->first) - -uint8_t ObjectIdImpl::getFlags() const -{ - return (ACTUAL_FIRST & 0xF000000000000000LL) >> 60; -} - -uint16_t ObjectIdImpl::getSequence() const -{ - return (ACTUAL_FIRST & 0x0FFF000000000000LL) >> 48; -} - -uint32_t ObjectIdImpl::getBrokerBank() const -{ - return (ACTUAL_FIRST & 0x0000FFFFF0000000LL) >> 28; -} - -uint32_t ObjectIdImpl::getAgentBank() const -{ - return ACTUAL_FIRST & 0x000000000FFFFFFFLL; -} - -uint64_t ObjectIdImpl::getObjectNum() const -{ - return second; -} - -uint32_t ObjectIdImpl::getObjectNumHi() const -{ - return (uint32_t) (second >> 32); -} - -uint32_t ObjectIdImpl::getObjectNumLo() const -{ - return (uint32_t) (second & 0x00000000FFFFFFFFLL); -} - -bool ObjectIdImpl::operator==(const ObjectIdImpl& other) const -{ - return ACTUAL_FIRST == ACTUAL_OTHER && second == other.second; -} - -bool ObjectIdImpl::operator<(const ObjectIdImpl& other) const -{ - return (ACTUAL_FIRST < ACTUAL_OTHER) || ((ACTUAL_FIRST == ACTUAL_OTHER) && (second < other.second)); -} - -bool ObjectIdImpl::operator>(const ObjectIdImpl& other) const -{ - return (ACTUAL_FIRST > ACTUAL_OTHER) || ((ACTUAL_FIRST == ACTUAL_OTHER) && (second > other.second)); -} - - -//================================================================== -// Wrappers -//================================================================== - -ObjectId::ObjectId() : impl(new ObjectIdImpl()) {} -ObjectId::ObjectId(const ObjectId& from) : impl(new ObjectIdImpl(*(from.impl))) {} -ObjectId::ObjectId(ObjectIdImpl* i) : impl(i) {} -ObjectId::~ObjectId() { delete impl; } -uint64_t ObjectId::getObjectNum() const { return impl->getObjectNum(); } -uint32_t ObjectId::getObjectNumHi() const { return impl->getObjectNumHi(); } -uint32_t ObjectId::getObjectNumLo() const { return impl->getObjectNumLo(); } -bool ObjectId::isDurable() const { return impl->isDurable(); } -const char* ObjectId::str() const { return impl->asString().c_str(); } -uint8_t ObjectId::getFlags() const { return impl->getFlags(); } -uint16_t ObjectId::getSequence() const { return impl->getSequence(); } -uint32_t ObjectId::getBrokerBank() const { return impl->getBrokerBank(); } -uint32_t ObjectId::getAgentBank() const { return impl->getAgentBank(); } -bool ObjectId::operator==(const ObjectId& other) const { return *impl == *other.impl; } -bool ObjectId::operator<(const ObjectId& other) const { return *impl < *other.impl; } -bool ObjectId::operator>(const ObjectId& other) const { return *impl > *other.impl; } -bool ObjectId::operator<=(const ObjectId& other) const { return !(*impl > *other.impl); } -bool ObjectId::operator>=(const ObjectId& other) const { return !(*impl < *other.impl); } -ObjectId& ObjectId::operator=(const ObjectId& other) { - ObjectIdImpl *old; - if (this != &other) { - old = impl; - impl = new ObjectIdImpl(*(other.impl)); - if (old) - delete old; - } - return *this; -} - diff --git a/cpp/src/qmf/engine/ObjectIdImpl.h b/cpp/src/qmf/engine/ObjectIdImpl.h deleted file mode 100644 index d70c8efff4..0000000000 --- a/cpp/src/qmf/engine/ObjectIdImpl.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _QmfEngineObjectIdImpl_ -#define _QmfEngineObjectIdImpl_ - -/* - * 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 <qmf/engine/ObjectId.h> -#include <qpid/framing/Buffer.h> - -namespace qmf { -namespace engine { - - struct AgentAttachment { - uint64_t first; - - AgentAttachment() : first(0) {} - void setBanks(uint32_t broker, uint32_t bank); - uint64_t getFirst() const { return first; } - }; - - struct ObjectIdImpl { - AgentAttachment* agent; - uint64_t first; - uint64_t second; - mutable std::string repr; - - ObjectIdImpl() : agent(0), first(0), second(0) {} - ObjectIdImpl(qpid::framing::Buffer& buffer); - ObjectIdImpl(AgentAttachment* agent, uint8_t flags, uint16_t seq, uint64_t object); - - static ObjectId* factory(qpid::framing::Buffer& buffer); - static ObjectId* factory(AgentAttachment* agent, uint8_t flags, uint16_t seq, uint64_t object); - - void decode(qpid::framing::Buffer& buffer); - void encode(qpid::framing::Buffer& buffer) const; - void fromString(const std::string& repr); - const std::string& asString() const; - uint8_t getFlags() const; - uint16_t getSequence() const; - uint32_t getBrokerBank() const; - uint32_t getAgentBank() const; - uint64_t getObjectNum() const; - uint32_t getObjectNumHi() const; - uint32_t getObjectNumLo() const; - bool isDurable() const { return getSequence() == 0; } - void setValue(uint64_t f, uint64_t s) { first = f; second = s; agent = 0; } - - bool operator==(const ObjectIdImpl& other) const; - bool operator<(const ObjectIdImpl& other) const; - bool operator>(const ObjectIdImpl& other) const; - }; -} -} - -#endif - diff --git a/cpp/src/qmf/engine/ObjectImpl.cpp b/cpp/src/qmf/engine/ObjectImpl.cpp deleted file mode 100644 index 45925cb804..0000000000 --- a/cpp/src/qmf/engine/ObjectImpl.cpp +++ /dev/null @@ -1,232 +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 "qmf/engine/ObjectImpl.h" -#include "qmf/engine/ValueImpl.h" -#include "qmf/engine/BrokerProxyImpl.h" -#include <qpid/sys/Time.h> - -using namespace std; -using namespace qmf::engine; -using namespace qpid::sys; -using qpid::framing::Buffer; - -ObjectImpl::ObjectImpl(const SchemaObjectClass* type) : objectClass(type), broker(0), createTime(uint64_t(Duration(EPOCH, now()))), destroyTime(0), lastUpdatedTime(createTime) -{ - int propCount = objectClass->getPropertyCount(); - int statCount = objectClass->getStatisticCount(); - int idx; - - for (idx = 0; idx < propCount; idx++) { - const SchemaProperty* prop = objectClass->getProperty(idx); - properties[prop->getName()] = ValuePtr(new Value(prop->getType())); - } - - for (idx = 0; idx < statCount; idx++) { - const SchemaStatistic* stat = objectClass->getStatistic(idx); - statistics[stat->getName()] = ValuePtr(new Value(stat->getType())); - } -} - -ObjectImpl::ObjectImpl(const SchemaObjectClass* type, BrokerProxyImpl* b, Buffer& buffer, bool prop, bool stat, bool managed) : - objectClass(type), broker(b), createTime(0), destroyTime(0), lastUpdatedTime(0) -{ - int idx; - - if (managed) { - lastUpdatedTime = buffer.getLongLong(); - createTime = buffer.getLongLong(); - destroyTime = buffer.getLongLong(); - objectId.reset(ObjectIdImpl::factory(buffer)); - } - - if (prop) { - int propCount = objectClass->getPropertyCount(); - set<string> excludes; - parsePresenceMasks(buffer, excludes); - for (idx = 0; idx < propCount; idx++) { - const SchemaProperty* prop = objectClass->getProperty(idx); - if (excludes.count(prop->getName()) != 0) { - properties[prop->getName()] = ValuePtr(new Value(prop->getType())); - } else { - Value* pval = ValueImpl::factory(prop->getType(), buffer); - properties[prop->getName()] = ValuePtr(pval); - } - } - } - - if (stat) { - int statCount = objectClass->getStatisticCount(); - for (idx = 0; idx < statCount; idx++) { - const SchemaStatistic* stat = objectClass->getStatistic(idx); - Value* sval = ValueImpl::factory(stat->getType(), buffer); - statistics[stat->getName()] = ValuePtr(sval); - } - } -} - -Object* ObjectImpl::factory(const SchemaObjectClass* type, BrokerProxyImpl* b, Buffer& buffer, bool prop, bool stat, bool managed) -{ - ObjectImpl* impl(new ObjectImpl(type, b, buffer, prop, stat, managed)); - return new Object(impl); -} - -ObjectImpl::~ObjectImpl() -{ -} - -void ObjectImpl::destroy() -{ - destroyTime = uint64_t(Duration(EPOCH, now())); - // TODO - flag deletion -} - -Value* ObjectImpl::getValue(const string& key) const -{ - map<string, ValuePtr>::const_iterator iter; - - iter = properties.find(key); - if (iter != properties.end()) - return iter->second.get(); - - iter = statistics.find(key); - if (iter != statistics.end()) - return iter->second.get(); - - return 0; -} - -void ObjectImpl::invokeMethod(const string& methodName, const Value* inArgs, void* context) const -{ - if (broker != 0 && objectId.get() != 0) - broker->sendMethodRequest(objectId.get(), objectClass, methodName, inArgs, context); -} - -void ObjectImpl::merge(const Object& from) -{ - for (map<string, ValuePtr>::const_iterator piter = from.impl->properties.begin(); - piter != from.impl->properties.end(); piter++) - properties[piter->first] = piter->second; - for (map<string, ValuePtr>::const_iterator siter = from.impl->statistics.begin(); - siter != from.impl->statistics.end(); siter++) - statistics[siter->first] = siter->second; -} - -void ObjectImpl::parsePresenceMasks(Buffer& buffer, set<string>& excludeList) -{ - int propCount = objectClass->getPropertyCount(); - excludeList.clear(); - uint8_t bit = 0; - uint8_t mask = 0; - - for (int idx = 0; idx < propCount; idx++) { - const SchemaProperty* prop = objectClass->getProperty(idx); - if (prop->isOptional()) { - if (bit == 0) { - mask = buffer.getOctet(); - bit = 1; - } - if ((mask & bit) == 0) - excludeList.insert(string(prop->getName())); - if (bit == 0x80) - bit = 0; - else - bit = bit << 1; - } - } -} - -void ObjectImpl::encodeSchemaKey(qpid::framing::Buffer& buffer) const -{ - buffer.putShortString(objectClass->getClassKey()->getPackageName()); - buffer.putShortString(objectClass->getClassKey()->getClassName()); - buffer.putBin128(const_cast<uint8_t*>(objectClass->getClassKey()->getHash())); -} - -void ObjectImpl::encodeManagedObjectData(qpid::framing::Buffer& buffer) const -{ - buffer.putLongLong(lastUpdatedTime); - buffer.putLongLong(createTime); - buffer.putLongLong(destroyTime); - objectId->impl->encode(buffer); -} - -void ObjectImpl::encodeProperties(qpid::framing::Buffer& buffer) const -{ - int propCount = objectClass->getPropertyCount(); - uint8_t bit = 0; - uint8_t mask = 0; - ValuePtr value; - - for (int idx = 0; idx < propCount; idx++) { - const SchemaProperty* prop = objectClass->getProperty(idx); - if (prop->isOptional()) { - value = properties[prop->getName()]; - if (bit == 0) - bit = 1; - if (!value->isNull()) - mask |= bit; - if (bit == 0x80) { - buffer.putOctet(mask); - bit = 0; - mask = 0; - } else - bit = bit << 1; - } - } - if (bit != 0) { - buffer.putOctet(mask); - } - - for (int idx = 0; idx < propCount; idx++) { - const SchemaProperty* prop = objectClass->getProperty(idx); - value = properties[prop->getName()]; - if (!prop->isOptional() || !value->isNull()) { - value->impl->encode(buffer); - } - } -} - -void ObjectImpl::encodeStatistics(qpid::framing::Buffer& buffer) const -{ - int statCount = objectClass->getStatisticCount(); - for (int idx = 0; idx < statCount; idx++) { - const SchemaStatistic* stat = objectClass->getStatistic(idx); - ValuePtr value = statistics[stat->getName()]; - value->impl->encode(buffer); - } -} - -//================================================================== -// Wrappers -//================================================================== - -Object::Object(const SchemaObjectClass* type) : impl(new ObjectImpl(type)) {} -Object::Object(ObjectImpl* i) : impl(i) {} -Object::Object(const Object& from) : impl(new ObjectImpl(*(from.impl))) {} -Object::~Object() { delete impl; } -void Object::destroy() { impl->destroy(); } -const ObjectId* Object::getObjectId() const { return impl->getObjectId(); } -void Object::setObjectId(ObjectId* oid) { impl->setObjectId(oid); } -const SchemaObjectClass* Object::getClass() const { return impl->getClass(); } -Value* Object::getValue(const char* key) const { return impl->getValue(key); } -void Object::invokeMethod(const char* m, const Value* a, void* c) const { impl->invokeMethod(m, a, c); } -bool Object::isDeleted() const { return impl->isDeleted(); } -void Object::merge(const Object& from) { impl->merge(from); } - diff --git a/cpp/src/qmf/engine/ObjectImpl.h b/cpp/src/qmf/engine/ObjectImpl.h deleted file mode 100644 index 6f25867004..0000000000 --- a/cpp/src/qmf/engine/ObjectImpl.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _QmfEngineObjectImpl_ -#define _QmfEngineObjectImpl_ - -/* - * 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 <qmf/engine/Object.h> -#include <qmf/engine/ObjectIdImpl.h> -#include <map> -#include <set> -#include <string> -#include <qpid/framing/Buffer.h> -#include <boost/shared_ptr.hpp> -#include <qpid/sys/Mutex.h> - -namespace qmf { -namespace engine { - - class BrokerProxyImpl; - - typedef boost::shared_ptr<Object> ObjectPtr; - - struct ObjectImpl { - typedef boost::shared_ptr<Value> ValuePtr; - const SchemaObjectClass* objectClass; - BrokerProxyImpl* broker; - boost::shared_ptr<ObjectId> objectId; - uint64_t createTime; - uint64_t destroyTime; - uint64_t lastUpdatedTime; - mutable std::map<std::string, ValuePtr> properties; - mutable std::map<std::string, ValuePtr> statistics; - - ObjectImpl(const SchemaObjectClass* type); - ObjectImpl(const SchemaObjectClass* type, BrokerProxyImpl* b, qpid::framing::Buffer& buffer, - bool prop, bool stat, bool managed); - static Object* factory(const SchemaObjectClass* type, BrokerProxyImpl* b, qpid::framing::Buffer& buffer, - bool prop, bool stat, bool managed); - ~ObjectImpl(); - - void destroy(); - const ObjectId* getObjectId() const { return objectId.get(); } - void setObjectId(ObjectId* oid) { objectId.reset(new ObjectId(*oid)); } - const SchemaObjectClass* getClass() const { return objectClass; } - Value* getValue(const std::string& key) const; - void invokeMethod(const std::string& methodName, const Value* inArgs, void* context) const; - bool isDeleted() const { return destroyTime != 0; } - void merge(const Object& from); - - void parsePresenceMasks(qpid::framing::Buffer& buffer, std::set<std::string>& excludeList); - void encodeSchemaKey(qpid::framing::Buffer& buffer) const; - void encodeManagedObjectData(qpid::framing::Buffer& buffer) const; - void encodeProperties(qpid::framing::Buffer& buffer) const; - void encodeStatistics(qpid::framing::Buffer& buffer) const; - }; -} -} - -#endif - diff --git a/cpp/src/qmf/engine/Protocol.cpp b/cpp/src/qmf/engine/Protocol.cpp deleted file mode 100644 index 9e5f490604..0000000000 --- a/cpp/src/qmf/engine/Protocol.cpp +++ /dev/null @@ -1,52 +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 "qmf/engine/Protocol.h" -#include "qpid/framing/Buffer.h" - -using namespace std; -using namespace qmf::engine; -using namespace qpid::framing; - - -bool Protocol::checkHeader(Buffer& buf, uint8_t *opcode, uint32_t *seq) -{ - if (buf.available() < 8) - return false; - - uint8_t h1 = buf.getOctet(); - uint8_t h2 = buf.getOctet(); - uint8_t h3 = buf.getOctet(); - - *opcode = buf.getOctet(); - *seq = buf.getLong(); - - return h1 == 'A' && h2 == 'M' && h3 == '2'; -} - -void Protocol::encodeHeader(qpid::framing::Buffer& buf, uint8_t opcode, uint32_t seq) -{ - buf.putOctet('A'); - buf.putOctet('M'); - buf.putOctet('2'); - buf.putOctet(opcode); - buf.putLong (seq); -} - - diff --git a/cpp/src/qmf/engine/Protocol.h b/cpp/src/qmf/engine/Protocol.h deleted file mode 100644 index 1cdfa60c84..0000000000 --- a/cpp/src/qmf/engine/Protocol.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _QmfEngineProtocol_ -#define _QmfEngineProtocol_ - -/* - * 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 <qpid/sys/IntegerTypes.h> - -namespace qpid { - namespace framing { - class Buffer; - } -} - -namespace qmf { -namespace engine { - - class Protocol { - public: - static bool checkHeader(qpid::framing::Buffer& buf, uint8_t *opcode, uint32_t *seq); - static void encodeHeader(qpid::framing::Buffer& buf, uint8_t opcode, uint32_t seq = 0); - - const static uint8_t OP_ATTACH_REQUEST = 'A'; - const static uint8_t OP_ATTACH_RESPONSE = 'a'; - - const static uint8_t OP_BROKER_REQUEST = 'B'; - const static uint8_t OP_BROKER_RESPONSE = 'b'; - - const static uint8_t OP_CONSOLE_ADDED_INDICATION = 'x'; - const static uint8_t OP_COMMAND_COMPLETE = 'z'; - const static uint8_t OP_HEARTBEAT_INDICATION = 'h'; - - const static uint8_t OP_PACKAGE_REQUEST = 'P'; - const static uint8_t OP_PACKAGE_INDICATION = 'p'; - const static uint8_t OP_CLASS_QUERY = 'Q'; - const static uint8_t OP_CLASS_INDICATION = 'q'; - const static uint8_t OP_SCHEMA_REQUEST = 'S'; - const static uint8_t OP_SCHEMA_RESPONSE = 's'; - - const static uint8_t OP_METHOD_REQUEST = 'M'; - const static uint8_t OP_METHOD_RESPONSE = 'm'; - const static uint8_t OP_GET_QUERY = 'G'; - const static uint8_t OP_OBJECT_INDICATION = 'g'; - const static uint8_t OP_PROPERTY_INDICATION = 'c'; - const static uint8_t OP_STATISTIC_INDICATION = 'i'; - const static uint8_t OP_EVENT_INDICATION = 'e'; - }; - -} -} - -#endif - diff --git a/cpp/src/qmf/engine/QueryImpl.cpp b/cpp/src/qmf/engine/QueryImpl.cpp deleted file mode 100644 index 6f2beeee87..0000000000 --- a/cpp/src/qmf/engine/QueryImpl.cpp +++ /dev/null @@ -1,103 +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 "qmf/engine/QueryImpl.h" -#include "qmf/engine/ObjectIdImpl.h" -#include "qpid/framing/Buffer.h" -#include "qpid/framing/FieldTable.h" - -using namespace std; -using namespace qmf::engine; -using namespace qpid::framing; - -bool QueryElementImpl::evaluate(const Object* /*object*/) const -{ - // TODO: Implement this - return false; -} - -bool QueryExpressionImpl::evaluate(const Object* /*object*/) const -{ - // TODO: Implement this - return false; -} - -QueryImpl::QueryImpl(Buffer& buffer) -{ - FieldTable ft; - ft.decode(buffer); - // TODO -} - -Query* QueryImpl::factory(Buffer& buffer) -{ - QueryImpl* impl(new QueryImpl(buffer)); - return new Query(impl); -} - -void QueryImpl::encode(Buffer& buffer) const -{ - FieldTable ft; - - if (oid.get() != 0) { - ft.setString("_objectid", oid->impl->asString()); - } else { - if (!packageName.empty()) - ft.setString("_package", packageName); - ft.setString("_class", className); - } - - ft.encode(buffer); -} - - -//================================================================== -// Wrappers -//================================================================== - -QueryElement::QueryElement(const char* attrName, const Value* value, ValueOper oper) : impl(new QueryElementImpl(attrName, value, oper)) {} -QueryElement::QueryElement(QueryElementImpl* i) : impl(i) {} -QueryElement::~QueryElement() { delete impl; } -bool QueryElement::evaluate(const Object* object) const { return impl->evaluate(object); } - -QueryExpression::QueryExpression(ExprOper oper, const QueryOperand* operand1, const QueryOperand* operand2) : impl(new QueryExpressionImpl(oper, operand1, operand2)) {} -QueryExpression::QueryExpression(QueryExpressionImpl* i) : impl(i) {} -QueryExpression::~QueryExpression() { delete impl; } -bool QueryExpression::evaluate(const Object* object) const { return impl->evaluate(object); } - -Query::Query(const char* className, const char* packageName) : impl(new QueryImpl(className, packageName)) {} -Query::Query(const SchemaClassKey* key) : impl(new QueryImpl(key)) {} -Query::Query(const ObjectId* oid) : impl(new QueryImpl(oid)) {} -Query::Query(QueryImpl* i) : impl(i) {} -Query::Query(const Query& from) : impl(new QueryImpl(*(from.impl))) {} -Query::~Query() { delete impl; } -void Query::setSelect(const QueryOperand* criterion) { impl->setSelect(criterion); } -void Query::setLimit(uint32_t maxResults) { impl->setLimit(maxResults); } -void Query::setOrderBy(const char* attrName, bool decreasing) { impl->setOrderBy(attrName, decreasing); } -const char* Query::getPackage() const { return impl->getPackage().c_str(); } -const char* Query::getClass() const { return impl->getClass().c_str(); } -const ObjectId* Query::getObjectId() const { return impl->getObjectId(); } -bool Query::haveSelect() const { return impl->haveSelect(); } -bool Query::haveLimit() const { return impl->haveLimit(); } -bool Query::haveOrderBy() const { return impl->haveOrderBy(); } -const QueryOperand* Query::getSelect() const { return impl->getSelect(); } -uint32_t Query::getLimit() const { return impl->getLimit(); } -const char* Query::getOrderBy() const { return impl->getOrderBy().c_str(); } -bool Query::getDecreasing() const { return impl->getDecreasing(); } - diff --git a/cpp/src/qmf/engine/QueryImpl.h b/cpp/src/qmf/engine/QueryImpl.h deleted file mode 100644 index 8ebe0d932f..0000000000 --- a/cpp/src/qmf/engine/QueryImpl.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef _QmfEngineQueryImpl_ -#define _QmfEngineQueryImpl_ - -/* - * 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 "qmf/engine/Query.h" -#include "qmf/engine/Schema.h" -#include <string> -#include <boost/shared_ptr.hpp> - -namespace qpid { - namespace framing { - class Buffer; - } -} - -namespace qmf { -namespace engine { - - struct QueryElementImpl { - QueryElementImpl(const std::string& a, const Value* v, ValueOper o) : attrName(a), value(v), oper(o) {} - ~QueryElementImpl() {} - bool evaluate(const Object* object) const; - - std::string attrName; - const Value* value; - ValueOper oper; - }; - - struct QueryExpressionImpl { - QueryExpressionImpl(ExprOper o, const QueryOperand* operand1, const QueryOperand* operand2) : oper(o), left(operand1), right(operand2) {} - ~QueryExpressionImpl() {} - bool evaluate(const Object* object) const; - - ExprOper oper; - const QueryOperand* left; - const QueryOperand* right; - }; - - struct QueryImpl { - // Constructors mapped to public - QueryImpl(const std::string& c, const std::string& p) : packageName(p), className(c), select(0), resultLimit(0) {} - QueryImpl(const SchemaClassKey* key) : packageName(key->getPackageName()), className(key->getClassName()), select(0), resultLimit(0) {} - QueryImpl(const ObjectId* oid) : oid(new ObjectId(*oid)), select(0), resultLimit(0) {} - - // Factory constructors - QueryImpl(qpid::framing::Buffer& buffer); - - ~QueryImpl() {}; - static Query* factory(qpid::framing::Buffer& buffer); - - void setSelect(const QueryOperand* criterion) { select = criterion; } - void setLimit(uint32_t maxResults) { resultLimit = maxResults; } - void setOrderBy(const std::string& attrName, bool decreasing) { - orderBy = attrName; orderDecreasing = decreasing; - } - - const std::string& getPackage() const { return packageName; } - const std::string& getClass() const { return className; } - const ObjectId* getObjectId() const { return oid.get(); } - - bool haveSelect() const { return select != 0; } - bool haveLimit() const { return resultLimit > 0; } - bool haveOrderBy() const { return !orderBy.empty(); } - const QueryOperand* getSelect() const { return select; } - uint32_t getLimit() const { return resultLimit; } - const std::string& getOrderBy() const { return orderBy; } - bool getDecreasing() const { return orderDecreasing; } - - void encode(qpid::framing::Buffer& buffer) const; - bool singleAgent() const { return oid.get() != 0; } - uint32_t agentBank() const { return singleAgent() ? oid->getAgentBank() : 0; } - - std::string packageName; - std::string className; - boost::shared_ptr<ObjectId> oid; - const QueryOperand* select; - uint32_t resultLimit; - std::string orderBy; - bool orderDecreasing; - }; -} -} - -#endif diff --git a/cpp/src/qmf/engine/ResilientConnection.cpp b/cpp/src/qmf/engine/ResilientConnection.cpp deleted file mode 100644 index 851193ccc1..0000000000 --- a/cpp/src/qmf/engine/ResilientConnection.cpp +++ /dev/null @@ -1,512 +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 "qmf/engine/ResilientConnection.h" -#include "qmf/engine/MessageImpl.h" -#include "qmf/engine/ConnectionSettingsImpl.h" -#include <qpid/client/Connection.h> -#include <qpid/client/Session.h> -#include <qpid/client/MessageListener.h> -#include <qpid/client/SubscriptionManager.h> -#include <qpid/client/Message.h> -#include <qpid/sys/Thread.h> -#include <qpid/sys/Runnable.h> -#include <qpid/sys/Mutex.h> -#include <qpid/sys/Condition.h> -#include <qpid/sys/Time.h> -#include <qpid/log/Statement.h> -#include <qpid/RefCounted.h> -#include <boost/bind.hpp> -#include <string> -#include <deque> -#include <vector> -#include <set> -#include <boost/intrusive_ptr.hpp> -#include <boost/noncopyable.hpp> -#include <unistd.h> -#include <fcntl.h> - -using namespace std; -using namespace qmf::engine; -using namespace qpid; -using qpid::sys::Mutex; - -namespace qmf { -namespace engine { - struct ResilientConnectionEventImpl { - ResilientConnectionEvent::EventKind kind; - void* sessionContext; - string errorText; - MessageImpl message; - - ResilientConnectionEventImpl(ResilientConnectionEvent::EventKind k, - const MessageImpl& m = MessageImpl()) : - kind(k), sessionContext(0), message(m) {} - ResilientConnectionEvent copy(); - }; - - struct RCSession : public client::MessageListener, public qpid::sys::Runnable, public qpid::RefCounted { - typedef boost::intrusive_ptr<RCSession> Ptr; - ResilientConnectionImpl& connImpl; - string name; - client::Connection& connection; - client::Session session; - client::SubscriptionManager* subscriptions; - string userId; - void* userContext; - vector<string> dests; - qpid::sys::Thread thread; - - RCSession(ResilientConnectionImpl& ci, const string& n, client::Connection& c, void* uc); - ~RCSession(); - void received(client::Message& msg); - void run(); - void stop(); - }; - - class ResilientConnectionImpl : public qpid::sys::Runnable, public boost::noncopyable { - public: - ResilientConnectionImpl(const ConnectionSettings& settings); - ~ResilientConnectionImpl(); - - bool isConnected() const; - bool getEvent(ResilientConnectionEvent& event); - void popEvent(); - bool createSession(const char* name, void* sessionContext, SessionHandle& handle); - void destroySession(SessionHandle handle); - void sendMessage(SessionHandle handle, qmf::engine::Message& message); - void declareQueue(SessionHandle handle, char* queue); - void deleteQueue(SessionHandle handle, char* queue); - void bind(SessionHandle handle, char* exchange, char* queue, char* key); - void unbind(SessionHandle handle, char* exchange, char* queue, char* key); - void setNotifyFd(int fd); - void notify(); - - void run(); - void failure(); - void sessionClosed(RCSession* sess); - - void EnqueueEvent(ResilientConnectionEvent::EventKind kind, - void* sessionContext = 0, - const MessageImpl& message = MessageImpl(), - const string& errorText = ""); - - private: - int notifyFd; - bool connected; - bool shutdown; - string lastError; - const ConnectionSettings settings; - client::Connection connection; - mutable qpid::sys::Mutex lock; - int delayMin; - int delayMax; - int delayFactor; - qpid::sys::Condition cond; - deque<ResilientConnectionEventImpl> eventQueue; - set<RCSession::Ptr> sessions; - qpid::sys::Thread connThread; - }; -} -} - -ResilientConnectionEvent ResilientConnectionEventImpl::copy() -{ - ResilientConnectionEvent item; - - ::memset(&item, 0, sizeof(ResilientConnectionEvent)); - item.kind = kind; - item.sessionContext = sessionContext; - item.message = message.copy(); - item.errorText = const_cast<char*>(errorText.c_str()); - - return item; -} - -RCSession::RCSession(ResilientConnectionImpl& ci, const string& n, client::Connection& c, void* uc) : - connImpl(ci), name(n), connection(c), session(connection.newSession(name)), - subscriptions(new client::SubscriptionManager(session)), userContext(uc), thread(*this) -{ - const qpid::client::ConnectionSettings& operSettings = connection.getNegotiatedSettings(); - userId = operSettings.username; -} - -RCSession::~RCSession() -{ - subscriptions->stop(); - thread.join(); - session.close(); - delete subscriptions; -} - -void RCSession::run() -{ - try { - subscriptions->run(); - } catch (exception& /*e*/) { - connImpl.sessionClosed(this); - } -} - -void RCSession::stop() -{ - subscriptions->stop(); -} - -void RCSession::received(client::Message& msg) -{ - MessageImpl qmsg; - qmsg.body = msg.getData(); - - qpid::framing::DeliveryProperties dp = msg.getDeliveryProperties(); - if (dp.hasRoutingKey()) { - qmsg.routingKey = dp.getRoutingKey(); - } - - qpid::framing::MessageProperties mp = msg.getMessageProperties(); - if (mp.hasReplyTo()) { - const qpid::framing::ReplyTo& rt = mp.getReplyTo(); - qmsg.replyExchange = rt.getExchange(); - qmsg.replyKey = rt.getRoutingKey(); - } - - if (mp.hasUserId()) { - qmsg.userId = mp.getUserId(); - } - - connImpl.EnqueueEvent(ResilientConnectionEvent::RECV, userContext, qmsg); -} - -ResilientConnectionImpl::ResilientConnectionImpl(const ConnectionSettings& _settings) : - notifyFd(-1), connected(false), shutdown(false), settings(_settings), delayMin(1), connThread(*this) -{ - connection.registerFailureCallback(boost::bind(&ResilientConnectionImpl::failure, this)); - settings.impl->getRetrySettings(&delayMin, &delayMax, &delayFactor); -} - -ResilientConnectionImpl::~ResilientConnectionImpl() -{ - shutdown = true; - connected = false; - cond.notify(); - connThread.join(); - connection.close(); -} - -bool ResilientConnectionImpl::isConnected() const -{ - Mutex::ScopedLock _lock(lock); - return connected; -} - -bool ResilientConnectionImpl::getEvent(ResilientConnectionEvent& event) -{ - Mutex::ScopedLock _lock(lock); - if (eventQueue.empty()) - return false; - event = eventQueue.front().copy(); - return true; -} - -void ResilientConnectionImpl::popEvent() -{ - Mutex::ScopedLock _lock(lock); - if (!eventQueue.empty()) - eventQueue.pop_front(); -} - -bool ResilientConnectionImpl::createSession(const char* name, void* sessionContext, - SessionHandle& handle) -{ - Mutex::ScopedLock _lock(lock); - if (!connected) - return false; - - RCSession::Ptr sess = RCSession::Ptr(new RCSession(*this, name, connection, sessionContext)); - - handle.impl = (void*) sess.get(); - sessions.insert(sess); - - return true; -} - -void ResilientConnectionImpl::destroySession(SessionHandle handle) -{ - Mutex::ScopedLock _lock(lock); - RCSession::Ptr sess = RCSession::Ptr((RCSession*) handle.impl); - set<RCSession::Ptr>::iterator iter = sessions.find(sess); - if (iter != sessions.end()) { - for (vector<string>::iterator dIter = sess->dests.begin(); dIter != sess->dests.end(); dIter++) - sess->subscriptions->cancel(dIter->c_str()); - sess->subscriptions->stop(); - sess->subscriptions->wait(); - - sessions.erase(iter); - return; - } -} - -void ResilientConnectionImpl::sendMessage(SessionHandle handle, qmf::engine::Message& message) -{ - Mutex::ScopedLock _lock(lock); - RCSession::Ptr sess = RCSession::Ptr((RCSession*) handle.impl); - set<RCSession::Ptr>::iterator iter = sessions.find(sess); - qpid::client::Message msg; - string data(message.body, message.length); - msg.getDeliveryProperties().setRoutingKey(message.routingKey); - msg.getMessageProperties().setReplyTo(qpid::framing::ReplyTo(message.replyExchange, message.replyKey)); - if (settings.impl->getSendUserId()) - msg.getMessageProperties().setUserId(sess->userId); - msg.setData(data); - - try { - sess->session.messageTransfer(client::arg::content=msg, client::arg::destination=message.destination); - } catch(exception& e) { - QPID_LOG(error, "Session Exception during message-transfer: " << e.what()); - sessions.erase(iter); - EnqueueEvent(ResilientConnectionEvent::SESSION_CLOSED, (*iter)->userContext); - } -} - -void ResilientConnectionImpl::declareQueue(SessionHandle handle, char* queue) -{ - Mutex::ScopedLock _lock(lock); - RCSession* sess = (RCSession*) handle.impl; - - sess->session.queueDeclare(client::arg::queue=queue, client::arg::autoDelete=true, client::arg::exclusive=true); - sess->subscriptions->setAcceptMode(client::ACCEPT_MODE_NONE); - sess->subscriptions->setAcquireMode(client::ACQUIRE_MODE_PRE_ACQUIRED); - sess->subscriptions->subscribe(*sess, queue, queue); - sess->subscriptions->setFlowControl(queue, client::FlowControl::unlimited()); - sess->dests.push_back(string(queue)); -} - -void ResilientConnectionImpl::deleteQueue(SessionHandle handle, char* queue) -{ - Mutex::ScopedLock _lock(lock); - RCSession* sess = (RCSession*) handle.impl; - - sess->session.queueDelete(client::arg::queue=queue); - for (vector<string>::iterator iter = sess->dests.begin(); - iter != sess->dests.end(); iter++) - if (*iter == queue) { - sess->subscriptions->cancel(queue); - sess->dests.erase(iter); - break; - } -} - -void ResilientConnectionImpl::bind(SessionHandle handle, - char* exchange, char* queue, char* key) -{ - Mutex::ScopedLock _lock(lock); - RCSession* sess = (RCSession*) handle.impl; - - sess->session.exchangeBind(client::arg::exchange=exchange, client::arg::queue=queue, client::arg::bindingKey=key); -} - -void ResilientConnectionImpl::unbind(SessionHandle handle, - char* exchange, char* queue, char* key) -{ - Mutex::ScopedLock _lock(lock); - RCSession* sess = (RCSession*) handle.impl; - - sess->session.exchangeUnbind(client::arg::exchange=exchange, client::arg::queue=queue, client::arg::bindingKey=key); -} - -void ResilientConnectionImpl::notify() -{ - if (notifyFd != -1) - { - if (::write(notifyFd, ".", 1)) {} - } -} - - -void ResilientConnectionImpl::setNotifyFd(int fd) -{ - notifyFd = fd; - if (notifyFd > 0) { - int original = fcntl(notifyFd, F_GETFL); - fcntl(notifyFd, F_SETFL, O_NONBLOCK | original); - } -} - -void ResilientConnectionImpl::run() -{ - int delay(delayMin); - - while (true) { - try { - QPID_LOG(trace, "Trying to open connection..."); - connection.open(settings.impl->getClientSettings()); - { - Mutex::ScopedLock _lock(lock); - connected = true; - EnqueueEvent(ResilientConnectionEvent::CONNECTED); - - while (connected) - cond.wait(lock); - delay = delayMin; - - while (!sessions.empty()) { - set<RCSession::Ptr>::iterator iter = sessions.begin(); - RCSession::Ptr sess = *iter; - sessions.erase(iter); - EnqueueEvent(ResilientConnectionEvent::SESSION_CLOSED, sess->userContext); - Mutex::ScopedUnlock _u(lock); - sess->stop(); - - // Nullify the intrusive pointer within the scoped unlock, otherwise, - // the reference is held until overwritted above (under lock) which causes - // the session destructor to be called with the lock held. - sess = 0; - } - - EnqueueEvent(ResilientConnectionEvent::DISCONNECTED); - - if (shutdown) - return; - } - connection.close(); - } catch (exception &e) { - QPID_LOG(debug, "connection.open exception: " << e.what()); - Mutex::ScopedLock _lock(lock); - lastError = e.what(); - if (delay < delayMax) - delay *= delayFactor; - } - - ::qpid::sys::sleep(delay); - } -} - -void ResilientConnectionImpl::failure() -{ - Mutex::ScopedLock _lock(lock); - - connected = false; - lastError = "Closed by Peer"; - cond.notify(); -} - -void ResilientConnectionImpl::sessionClosed(RCSession*) -{ - Mutex::ScopedLock _lock(lock); - connected = false; - lastError = "Closed due to Session failure"; - cond.notify(); -} - -void ResilientConnectionImpl::EnqueueEvent(ResilientConnectionEvent::EventKind kind, - void* sessionContext, - const MessageImpl& message, - const string& errorText) -{ - { - Mutex::ScopedLock _lock(lock); - ResilientConnectionEventImpl event(kind, message); - - event.sessionContext = sessionContext; - event.errorText = errorText; - - eventQueue.push_back(event); - } - - if (notifyFd != -1) - { - if (::write(notifyFd, ".", 1)) {} - } -} - - -//================================================================== -// Wrappers -//================================================================== - -ResilientConnection::ResilientConnection(const ConnectionSettings& settings) -{ - impl = new ResilientConnectionImpl(settings); -} - -ResilientConnection::~ResilientConnection() -{ - delete impl; -} - -bool ResilientConnection::isConnected() const -{ - return impl->isConnected(); -} - -bool ResilientConnection::getEvent(ResilientConnectionEvent& event) -{ - return impl->getEvent(event); -} - -void ResilientConnection::popEvent() -{ - impl->popEvent(); -} - -bool ResilientConnection::createSession(const char* name, void* sessionContext, SessionHandle& handle) -{ - return impl->createSession(name, sessionContext, handle); -} - -void ResilientConnection::destroySession(SessionHandle handle) -{ - impl->destroySession(handle); -} - -void ResilientConnection::sendMessage(SessionHandle handle, qmf::engine::Message& message) -{ - impl->sendMessage(handle, message); -} - -void ResilientConnection::declareQueue(SessionHandle handle, char* queue) -{ - impl->declareQueue(handle, queue); -} - -void ResilientConnection::deleteQueue(SessionHandle handle, char* queue) -{ - impl->deleteQueue(handle, queue); -} - -void ResilientConnection::bind(SessionHandle handle, char* exchange, char* queue, char* key) -{ - impl->bind(handle, exchange, queue, key); -} - -void ResilientConnection::unbind(SessionHandle handle, char* exchange, char* queue, char* key) -{ - impl->unbind(handle, exchange, queue, key); -} - -void ResilientConnection::setNotifyFd(int fd) -{ - impl->setNotifyFd(fd); -} - -void ResilientConnection::notify() -{ - impl->notify(); -} - diff --git a/cpp/src/qmf/engine/SchemaImpl.cpp b/cpp/src/qmf/engine/SchemaImpl.cpp deleted file mode 100644 index 9d363d3012..0000000000 --- a/cpp/src/qmf/engine/SchemaImpl.cpp +++ /dev/null @@ -1,610 +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 "qmf/engine/SchemaImpl.h" -#include <qpid/framing/Buffer.h> -#include <qpid/framing/FieldTable.h> -#include <qpid/framing/Uuid.h> -#include <string.h> -#include <string> -#include <vector> -#include <sstream> - -using namespace std; -using namespace qmf::engine; -using qpid::framing::Buffer; -using qpid::framing::FieldTable; -using qpid::framing::Uuid; - -SchemaHash::SchemaHash() -{ - for (int idx = 0; idx < 16; idx++) - hash.b[idx] = 0x5A; -} - -void SchemaHash::encode(Buffer& buffer) const -{ - buffer.putBin128(hash.b); -} - -void SchemaHash::decode(Buffer& buffer) -{ - buffer.getBin128(hash.b); -} - -void SchemaHash::update(uint8_t data) -{ - update((char*) &data, 1); -} - -void SchemaHash::update(const char* data, uint32_t len) -{ - uint64_t* first = &hash.q[0]; - uint64_t* second = &hash.q[1]; - for (uint32_t idx = 0; idx < len; idx++) { - *first = *first ^ (uint64_t) data[idx]; - *second = *second << 1; - *second |= ((*first & 0x8000000000000000LL) >> 63); - *first = *first << 1; - *first = *first ^ *second; - } -} - -bool SchemaHash::operator==(const SchemaHash& other) const -{ - return ::memcmp(&hash, &other.hash, 16) == 0; -} - -bool SchemaHash::operator<(const SchemaHash& other) const -{ - return ::memcmp(&hash, &other.hash, 16) < 0; -} - -bool SchemaHash::operator>(const SchemaHash& other) const -{ - return ::memcmp(&hash, &other.hash, 16) > 0; -} - -SchemaArgumentImpl::SchemaArgumentImpl(Buffer& buffer) -{ - FieldTable map; - map.decode(buffer); - - name = map.getAsString("name"); - typecode = (Typecode) map.getAsInt("type"); - unit = map.getAsString("unit"); - description = map.getAsString("desc"); - - dir = DIR_IN; - string dstr(map.getAsString("dir")); - if (dstr == "O") - dir = DIR_OUT; - else if (dstr == "IO") - dir = DIR_IN_OUT; -} - -SchemaArgument* SchemaArgumentImpl::factory(Buffer& buffer) -{ - SchemaArgumentImpl* impl(new SchemaArgumentImpl(buffer)); - return new SchemaArgument(impl); -} - -void SchemaArgumentImpl::encode(Buffer& buffer) const -{ - FieldTable map; - - map.setString("name", name); - map.setInt("type", (int) typecode); - if (dir == DIR_IN) - map.setString("dir", "I"); - else if (dir == DIR_OUT) - map.setString("dir", "O"); - else - map.setString("dir", "IO"); - if (!unit.empty()) - map.setString("unit", unit); - if (!description.empty()) - map.setString("desc", description); - - map.encode(buffer); -} - -void SchemaArgumentImpl::updateHash(SchemaHash& hash) const -{ - hash.update(name); - hash.update(typecode); - hash.update(dir); - hash.update(unit); - hash.update(description); -} - -SchemaMethodImpl::SchemaMethodImpl(Buffer& buffer) -{ - FieldTable map; - int argCount; - - map.decode(buffer); - name = map.getAsString("name"); - argCount = map.getAsInt("argCount"); - description = map.getAsString("desc"); - - for (int idx = 0; idx < argCount; idx++) { - SchemaArgument* arg = SchemaArgumentImpl::factory(buffer); - addArgument(arg); - } -} - -SchemaMethod* SchemaMethodImpl::factory(Buffer& buffer) -{ - SchemaMethodImpl* impl(new SchemaMethodImpl(buffer)); - return new SchemaMethod(impl); -} - -void SchemaMethodImpl::encode(Buffer& buffer) const -{ - FieldTable map; - - map.setString("name", name); - map.setInt("argCount", arguments.size()); - if (!description.empty()) - map.setString("desc", description); - map.encode(buffer); - - for (vector<const SchemaArgument*>::const_iterator iter = arguments.begin(); - iter != arguments.end(); iter++) - (*iter)->impl->encode(buffer); -} - -void SchemaMethodImpl::addArgument(const SchemaArgument* argument) -{ - arguments.push_back(argument); -} - -const SchemaArgument* SchemaMethodImpl::getArgument(int idx) const -{ - int count = 0; - for (vector<const SchemaArgument*>::const_iterator iter = arguments.begin(); - iter != arguments.end(); iter++, count++) - if (idx == count) - return (*iter); - return 0; -} - -void SchemaMethodImpl::updateHash(SchemaHash& hash) const -{ - hash.update(name); - hash.update(description); - for (vector<const SchemaArgument*>::const_iterator iter = arguments.begin(); - iter != arguments.end(); iter++) - (*iter)->impl->updateHash(hash); -} - -SchemaPropertyImpl::SchemaPropertyImpl(Buffer& buffer) -{ - FieldTable map; - map.decode(buffer); - - name = map.getAsString("name"); - typecode = (Typecode) map.getAsInt("type"); - access = (Access) map.getAsInt("access"); - index = map.getAsInt("index") != 0; - optional = map.getAsInt("optional") != 0; - unit = map.getAsString("unit"); - description = map.getAsString("desc"); -} - -SchemaProperty* SchemaPropertyImpl::factory(Buffer& buffer) -{ - SchemaPropertyImpl* impl(new SchemaPropertyImpl(buffer)); - return new SchemaProperty(impl); -} - -void SchemaPropertyImpl::encode(Buffer& buffer) const -{ - FieldTable map; - - map.setString("name", name); - map.setInt("type", (int) typecode); - map.setInt("access", (int) access); - map.setInt("index", index ? 1 : 0); - map.setInt("optional", optional ? 1 : 0); - if (!unit.empty()) - map.setString("unit", unit); - if (!description.empty()) - map.setString("desc", description); - - map.encode(buffer); -} - -void SchemaPropertyImpl::updateHash(SchemaHash& hash) const -{ - hash.update(name); - hash.update(typecode); - hash.update(access); - hash.update(index); - hash.update(optional); - hash.update(unit); - hash.update(description); -} - -SchemaStatisticImpl::SchemaStatisticImpl(Buffer& buffer) -{ - FieldTable map; - map.decode(buffer); - - name = map.getAsString("name"); - typecode = (Typecode) map.getAsInt("type"); - unit = map.getAsString("unit"); - description = map.getAsString("desc"); -} - -SchemaStatistic* SchemaStatisticImpl::factory(Buffer& buffer) -{ - SchemaStatisticImpl* impl(new SchemaStatisticImpl(buffer)); - return new SchemaStatistic(impl); -} - -void SchemaStatisticImpl::encode(Buffer& buffer) const -{ - FieldTable map; - - map.setString("name", name); - map.setInt("type", (int) typecode); - if (!unit.empty()) - map.setString("unit", unit); - if (!description.empty()) - map.setString("desc", description); - - map.encode(buffer); -} - -void SchemaStatisticImpl::updateHash(SchemaHash& hash) const -{ - hash.update(name); - hash.update(typecode); - hash.update(unit); - hash.update(description); -} - -SchemaClassKeyImpl::SchemaClassKeyImpl(const string& p, const string& n, const SchemaHash& h) : package(p), name(n), hash(h) {} - -SchemaClassKeyImpl::SchemaClassKeyImpl(Buffer& buffer) : package(packageContainer), name(nameContainer), hash(hashContainer) -{ - buffer.getShortString(packageContainer); - buffer.getShortString(nameContainer); - hashContainer.decode(buffer); -} - -SchemaClassKey* SchemaClassKeyImpl::factory(const string& package, const string& name, const SchemaHash& hash) -{ - SchemaClassKeyImpl* impl(new SchemaClassKeyImpl(package, name, hash)); - return new SchemaClassKey(impl); -} - -SchemaClassKey* SchemaClassKeyImpl::factory(Buffer& buffer) -{ - SchemaClassKeyImpl* impl(new SchemaClassKeyImpl(buffer)); - return new SchemaClassKey(impl); -} - -void SchemaClassKeyImpl::encode(Buffer& buffer) const -{ - buffer.putShortString(package); - buffer.putShortString(name); - hash.encode(buffer); -} - -bool SchemaClassKeyImpl::operator==(const SchemaClassKeyImpl& other) const -{ - return package == other.package && - name == other.name && - hash == other.hash; -} - -bool SchemaClassKeyImpl::operator<(const SchemaClassKeyImpl& other) const -{ - if (package < other.package) return true; - if (package > other.package) return false; - if (name < other.name) return true; - if (name > other.name) return false; - return hash < other.hash; -} - -const string& SchemaClassKeyImpl::str() const -{ - Uuid printableHash(hash.get()); - stringstream str; - str << package << ":" << name << "(" << printableHash << ")"; - repr = str.str(); - return repr; -} - -SchemaObjectClassImpl::SchemaObjectClassImpl(Buffer& buffer) : hasHash(true), classKey(SchemaClassKeyImpl::factory(package, name, hash)) -{ - buffer.getShortString(package); - buffer.getShortString(name); - hash.decode(buffer); - - uint16_t propCount = buffer.getShort(); - uint16_t statCount = buffer.getShort(); - uint16_t methodCount = buffer.getShort(); - - for (uint16_t idx = 0; idx < propCount; idx++) { - const SchemaProperty* property = SchemaPropertyImpl::factory(buffer); - addProperty(property); - } - - for (uint16_t idx = 0; idx < statCount; idx++) { - const SchemaStatistic* statistic = SchemaStatisticImpl::factory(buffer); - addStatistic(statistic); - } - - for (uint16_t idx = 0; idx < methodCount; idx++) { - SchemaMethod* method = SchemaMethodImpl::factory(buffer); - addMethod(method); - } -} - -SchemaObjectClass* SchemaObjectClassImpl::factory(Buffer& buffer) -{ - SchemaObjectClassImpl* impl(new SchemaObjectClassImpl(buffer)); - return new SchemaObjectClass(impl); -} - -void SchemaObjectClassImpl::encode(Buffer& buffer) const -{ - buffer.putOctet((uint8_t) CLASS_OBJECT); - buffer.putShortString(package); - buffer.putShortString(name); - hash.encode(buffer); - //buffer.putOctet(0); // No parent class - buffer.putShort((uint16_t) properties.size()); - buffer.putShort((uint16_t) statistics.size()); - buffer.putShort((uint16_t) methods.size()); - - for (vector<const SchemaProperty*>::const_iterator iter = properties.begin(); - iter != properties.end(); iter++) - (*iter)->impl->encode(buffer); - for (vector<const SchemaStatistic*>::const_iterator iter = statistics.begin(); - iter != statistics.end(); iter++) - (*iter)->impl->encode(buffer); - for (vector<const SchemaMethod*>::const_iterator iter = methods.begin(); - iter != methods.end(); iter++) - (*iter)->impl->encode(buffer); -} - -const SchemaClassKey* SchemaObjectClassImpl::getClassKey() const -{ - if (!hasHash) { - hasHash = true; - hash.update(package); - hash.update(name); - for (vector<const SchemaProperty*>::const_iterator iter = properties.begin(); - iter != properties.end(); iter++) - (*iter)->impl->updateHash(hash); - for (vector<const SchemaStatistic*>::const_iterator iter = statistics.begin(); - iter != statistics.end(); iter++) - (*iter)->impl->updateHash(hash); - for (vector<const SchemaMethod*>::const_iterator iter = methods.begin(); - iter != methods.end(); iter++) - (*iter)->impl->updateHash(hash); - } - - return classKey.get(); -} - -void SchemaObjectClassImpl::addProperty(const SchemaProperty* property) -{ - properties.push_back(property); -} - -void SchemaObjectClassImpl::addStatistic(const SchemaStatistic* statistic) -{ - statistics.push_back(statistic); -} - -void SchemaObjectClassImpl::addMethod(const SchemaMethod* method) -{ - methods.push_back(method); -} - -const SchemaProperty* SchemaObjectClassImpl::getProperty(int idx) const -{ - int count = 0; - for (vector<const SchemaProperty*>::const_iterator iter = properties.begin(); - iter != properties.end(); iter++, count++) - if (idx == count) - return *iter; - return 0; -} - -const SchemaStatistic* SchemaObjectClassImpl::getStatistic(int idx) const -{ - int count = 0; - for (vector<const SchemaStatistic*>::const_iterator iter = statistics.begin(); - iter != statistics.end(); iter++, count++) - if (idx == count) - return *iter; - return 0; -} - -const SchemaMethod* SchemaObjectClassImpl::getMethod(int idx) const -{ - int count = 0; - for (vector<const SchemaMethod*>::const_iterator iter = methods.begin(); - iter != methods.end(); iter++, count++) - if (idx == count) - return *iter; - return 0; -} - -SchemaEventClassImpl::SchemaEventClassImpl(Buffer& buffer) : hasHash(true), classKey(SchemaClassKeyImpl::factory(package, name, hash)) -{ - buffer.getShortString(package); - buffer.getShortString(name); - hash.decode(buffer); - - uint16_t argCount = buffer.getShort(); - - for (uint16_t idx = 0; idx < argCount; idx++) { - SchemaArgument* argument = SchemaArgumentImpl::factory(buffer); - addArgument(argument); - } -} - -SchemaEventClass* SchemaEventClassImpl::factory(Buffer& buffer) -{ - SchemaEventClassImpl* impl(new SchemaEventClassImpl(buffer)); - return new SchemaEventClass(impl); -} - -void SchemaEventClassImpl::encode(Buffer& buffer) const -{ - buffer.putOctet((uint8_t) CLASS_EVENT); - buffer.putShortString(package); - buffer.putShortString(name); - hash.encode(buffer); - buffer.putShort((uint16_t) arguments.size()); - - for (vector<const SchemaArgument*>::const_iterator iter = arguments.begin(); - iter != arguments.end(); iter++) - (*iter)->impl->encode(buffer); -} - -const SchemaClassKey* SchemaEventClassImpl::getClassKey() const -{ - if (!hasHash) { - hasHash = true; - hash.update(package); - hash.update(name); - for (vector<const SchemaArgument*>::const_iterator iter = arguments.begin(); - iter != arguments.end(); iter++) - (*iter)->impl->updateHash(hash); - } - return classKey.get(); -} - -void SchemaEventClassImpl::addArgument(const SchemaArgument* argument) -{ - arguments.push_back(argument); -} - -const SchemaArgument* SchemaEventClassImpl::getArgument(int idx) const -{ - int count = 0; - for (vector<const SchemaArgument*>::const_iterator iter = arguments.begin(); - iter != arguments.end(); iter++, count++) - if (idx == count) - return (*iter); - return 0; -} - - -//================================================================== -// Wrappers -//================================================================== - -SchemaArgument::SchemaArgument(const char* name, Typecode typecode) { impl = new SchemaArgumentImpl(name, typecode); } -SchemaArgument::SchemaArgument(SchemaArgumentImpl* i) : impl(i) {} -SchemaArgument::SchemaArgument(const SchemaArgument& from) : impl(new SchemaArgumentImpl(*(from.impl))) {} -SchemaArgument::~SchemaArgument() { delete impl; } -void SchemaArgument::setDirection(Direction dir) { impl->setDirection(dir); } -void SchemaArgument::setUnit(const char* val) { impl->setUnit(val); } -void SchemaArgument::setDesc(const char* desc) { impl->setDesc(desc); } -const char* SchemaArgument::getName() const { return impl->getName().c_str(); } -Typecode SchemaArgument::getType() const { return impl->getType(); } -Direction SchemaArgument::getDirection() const { return impl->getDirection(); } -const char* SchemaArgument::getUnit() const { return impl->getUnit().c_str(); } -const char* SchemaArgument::getDesc() const { return impl->getDesc().c_str(); } - -SchemaMethod::SchemaMethod(const char* name) : impl(new SchemaMethodImpl(name)) {} -SchemaMethod::SchemaMethod(SchemaMethodImpl* i) : impl(i) {} -SchemaMethod::SchemaMethod(const SchemaMethod& from) : impl(new SchemaMethodImpl(*(from.impl))) {} -SchemaMethod::~SchemaMethod() { delete impl; } -void SchemaMethod::addArgument(const SchemaArgument* argument) { impl->addArgument(argument); } -void SchemaMethod::setDesc(const char* desc) { impl->setDesc(desc); } -const char* SchemaMethod::getName() const { return impl->getName().c_str(); } -const char* SchemaMethod::getDesc() const { return impl->getDesc().c_str(); } -int SchemaMethod::getArgumentCount() const { return impl->getArgumentCount(); } -const SchemaArgument* SchemaMethod::getArgument(int idx) const { return impl->getArgument(idx); } - -SchemaProperty::SchemaProperty(const char* name, Typecode typecode) : impl(new SchemaPropertyImpl(name, typecode)) {} -SchemaProperty::SchemaProperty(SchemaPropertyImpl* i) : impl(i) {} -SchemaProperty::SchemaProperty(const SchemaProperty& from) : impl(new SchemaPropertyImpl(*(from.impl))) {} -SchemaProperty::~SchemaProperty() { delete impl; } -void SchemaProperty::setAccess(Access access) { impl->setAccess(access); } -void SchemaProperty::setIndex(bool val) { impl->setIndex(val); } -void SchemaProperty::setOptional(bool val) { impl->setOptional(val); } -void SchemaProperty::setUnit(const char* val) { impl->setUnit(val); } -void SchemaProperty::setDesc(const char* desc) { impl->setDesc(desc); } -const char* SchemaProperty::getName() const { return impl->getName().c_str(); } -Typecode SchemaProperty::getType() const { return impl->getType(); } -Access SchemaProperty::getAccess() const { return impl->getAccess(); } -bool SchemaProperty::isIndex() const { return impl->isIndex(); } -bool SchemaProperty::isOptional() const { return impl->isOptional(); } -const char* SchemaProperty::getUnit() const { return impl->getUnit().c_str(); } -const char* SchemaProperty::getDesc() const { return impl->getDesc().c_str(); } - -SchemaStatistic::SchemaStatistic(const char* name, Typecode typecode) : impl(new SchemaStatisticImpl(name, typecode)) {} -SchemaStatistic::SchemaStatistic(SchemaStatisticImpl* i) : impl(i) {} -SchemaStatistic::SchemaStatistic(const SchemaStatistic& from) : impl(new SchemaStatisticImpl(*(from.impl))) {} -SchemaStatistic::~SchemaStatistic() { delete impl; } -void SchemaStatistic::setUnit(const char* val) { impl->setUnit(val); } -void SchemaStatistic::setDesc(const char* desc) { impl->setDesc(desc); } -const char* SchemaStatistic::getName() const { return impl->getName().c_str(); } -Typecode SchemaStatistic::getType() const { return impl->getType(); } -const char* SchemaStatistic::getUnit() const { return impl->getUnit().c_str(); } -const char* SchemaStatistic::getDesc() const { return impl->getDesc().c_str(); } - -SchemaClassKey::SchemaClassKey(SchemaClassKeyImpl* i) : impl(i) {} -SchemaClassKey::SchemaClassKey(const SchemaClassKey& from) : impl(new SchemaClassKeyImpl(*(from.impl))) {} -SchemaClassKey::~SchemaClassKey() { delete impl; } -const char* SchemaClassKey::getPackageName() const { return impl->getPackageName().c_str(); } -const char* SchemaClassKey::getClassName() const { return impl->getClassName().c_str(); } -const uint8_t* SchemaClassKey::getHash() const { return impl->getHash(); } -const char* SchemaClassKey::asString() const { return impl->str().c_str(); } -bool SchemaClassKey::operator==(const SchemaClassKey& other) const { return *impl == *(other.impl); } -bool SchemaClassKey::operator<(const SchemaClassKey& other) const { return *impl < *(other.impl); } - -SchemaObjectClass::SchemaObjectClass(const char* package, const char* name) : impl(new SchemaObjectClassImpl(package, name)) {} -SchemaObjectClass::SchemaObjectClass(SchemaObjectClassImpl* i) : impl(i) {} -SchemaObjectClass::SchemaObjectClass(const SchemaObjectClass& from) : impl(new SchemaObjectClassImpl(*(from.impl))) {} -SchemaObjectClass::~SchemaObjectClass() { delete impl; } -void SchemaObjectClass::addProperty(const SchemaProperty* property) { impl->addProperty(property); } -void SchemaObjectClass::addStatistic(const SchemaStatistic* statistic) { impl->addStatistic(statistic); } -void SchemaObjectClass::addMethod(const SchemaMethod* method) { impl->addMethod(method); } -const SchemaClassKey* SchemaObjectClass::getClassKey() const { return impl->getClassKey(); } -int SchemaObjectClass::getPropertyCount() const { return impl->getPropertyCount(); } -int SchemaObjectClass::getStatisticCount() const { return impl->getStatisticCount(); } -int SchemaObjectClass::getMethodCount() const { return impl->getMethodCount(); } -const SchemaProperty* SchemaObjectClass::getProperty(int idx) const { return impl->getProperty(idx); } -const SchemaStatistic* SchemaObjectClass::getStatistic(int idx) const { return impl->getStatistic(idx); } -const SchemaMethod* SchemaObjectClass::getMethod(int idx) const { return impl->getMethod(idx); } - -SchemaEventClass::SchemaEventClass(const char* package, const char* name, Severity s) : impl(new SchemaEventClassImpl(package, name, s)) {} -SchemaEventClass::SchemaEventClass(SchemaEventClassImpl* i) : impl(i) {} -SchemaEventClass::SchemaEventClass(const SchemaEventClass& from) : impl(new SchemaEventClassImpl(*(from.impl))) {} -SchemaEventClass::~SchemaEventClass() { delete impl; } -void SchemaEventClass::addArgument(const SchemaArgument* argument) { impl->addArgument(argument); } -void SchemaEventClass::setDesc(const char* desc) { impl->setDesc(desc); } -const SchemaClassKey* SchemaEventClass::getClassKey() const { return impl->getClassKey(); } -Severity SchemaEventClass::getSeverity() const { return impl->getSeverity(); } -int SchemaEventClass::getArgumentCount() const { return impl->getArgumentCount(); } -const SchemaArgument* SchemaEventClass::getArgument(int idx) const { return impl->getArgument(idx); } - diff --git a/cpp/src/qmf/engine/SchemaImpl.h b/cpp/src/qmf/engine/SchemaImpl.h deleted file mode 100644 index 683fb6f8f0..0000000000 --- a/cpp/src/qmf/engine/SchemaImpl.h +++ /dev/null @@ -1,230 +0,0 @@ -#ifndef _QmfEngineSchemaImpl_ -#define _QmfEngineSchemaImpl_ - -/* - * 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 "qmf/engine/Schema.h" -#include "qpid/framing/Buffer.h" - -#include <string> -#include <vector> -#include <memory> - -namespace qmf { -namespace engine { - - // TODO: Destructors for schema classes - // TODO: Add "frozen" attribute for schema classes so they can't be modified after - // they've been registered. - - class SchemaHash { - union h { - uint8_t b[16]; - uint64_t q[2]; - } hash; - public: - SchemaHash(); - void encode(qpid::framing::Buffer& buffer) const; - void decode(qpid::framing::Buffer& buffer); - void update(const char* data, uint32_t len); - void update(uint8_t data); - void update(const std::string& data) { update(data.c_str(), data.size()); } - void update(Typecode t) { update((uint8_t) t); } - void update(Direction d) { update((uint8_t) d); } - void update(Access a) { update((uint8_t) a); } - void update(bool b) { update((uint8_t) (b ? 1 : 0)); } - const uint8_t* get() const { return hash.b; } - bool operator==(const SchemaHash& other) const; - bool operator<(const SchemaHash& other) const; - bool operator>(const SchemaHash& other) const; - }; - - struct SchemaArgumentImpl { - std::string name; - Typecode typecode; - Direction dir; - std::string unit; - std::string description; - - SchemaArgumentImpl(const char* n, Typecode t) : name(n), typecode(t), dir(DIR_IN) {} - SchemaArgumentImpl(qpid::framing::Buffer& buffer); - static SchemaArgument* factory(qpid::framing::Buffer& buffer); - void encode(qpid::framing::Buffer& buffer) const; - void setDirection(Direction d) { dir = d; } - void setUnit(const char* val) { unit = val; } - void setDesc(const char* desc) { description = desc; } - const std::string& getName() const { return name; } - Typecode getType() const { return typecode; } - Direction getDirection() const { return dir; } - const std::string& getUnit() const { return unit; } - const std::string& getDesc() const { return description; } - void updateHash(SchemaHash& hash) const; - }; - - struct SchemaMethodImpl { - std::string name; - std::string description; - std::vector<const SchemaArgument*> arguments; - - SchemaMethodImpl(const char* n) : name(n) {} - SchemaMethodImpl(qpid::framing::Buffer& buffer); - static SchemaMethod* factory(qpid::framing::Buffer& buffer); - void encode(qpid::framing::Buffer& buffer) const; - void addArgument(const SchemaArgument* argument); - void setDesc(const char* desc) { description = desc; } - const std::string& getName() const { return name; } - const std::string& getDesc() const { return description; } - int getArgumentCount() const { return arguments.size(); } - const SchemaArgument* getArgument(int idx) const; - void updateHash(SchemaHash& hash) const; - }; - - struct SchemaPropertyImpl { - std::string name; - Typecode typecode; - Access access; - bool index; - bool optional; - std::string unit; - std::string description; - - SchemaPropertyImpl(const char* n, Typecode t) : name(n), typecode(t), access(ACCESS_READ_ONLY), index(false), optional(false) {} - SchemaPropertyImpl(qpid::framing::Buffer& buffer); - static SchemaProperty* factory(qpid::framing::Buffer& buffer); - void encode(qpid::framing::Buffer& buffer) const; - void setAccess(Access a) { access = a; } - void setIndex(bool val) { index = val; } - void setOptional(bool val) { optional = val; } - void setUnit(const char* val) { unit = val; } - void setDesc(const char* desc) { description = desc; } - const std::string& getName() const { return name; } - Typecode getType() const { return typecode; } - Access getAccess() const { return access; } - bool isIndex() const { return index; } - bool isOptional() const { return optional; } - const std::string& getUnit() const { return unit; } - const std::string& getDesc() const { return description; } - void updateHash(SchemaHash& hash) const; - }; - - struct SchemaStatisticImpl { - std::string name; - Typecode typecode; - std::string unit; - std::string description; - - SchemaStatisticImpl(const char* n, Typecode t) : name(n), typecode(t) {} - SchemaStatisticImpl(qpid::framing::Buffer& buffer); - static SchemaStatistic* factory(qpid::framing::Buffer& buffer); - void encode(qpid::framing::Buffer& buffer) const; - void setUnit(const char* val) { unit = val; } - void setDesc(const char* desc) { description = desc; } - const std::string& getName() const { return name; } - Typecode getType() const { return typecode; } - const std::string& getUnit() const { return unit; } - const std::string& getDesc() const { return description; } - void updateHash(SchemaHash& hash) const; - }; - - struct SchemaClassKeyImpl { - const std::string& package; - const std::string& name; - const SchemaHash& hash; - mutable std::string repr; - - // The *Container elements are only used if there isn't an external place to - // store these values. - std::string packageContainer; - std::string nameContainer; - SchemaHash hashContainer; - - SchemaClassKeyImpl(const std::string& package, const std::string& name, const SchemaHash& hash); - SchemaClassKeyImpl(qpid::framing::Buffer& buffer); - static SchemaClassKey* factory(const std::string& package, const std::string& name, const SchemaHash& hash); - static SchemaClassKey* factory(qpid::framing::Buffer& buffer); - - const std::string& getPackageName() const { return package; } - const std::string& getClassName() const { return name; } - const uint8_t* getHash() const { return hash.get(); } - - void encode(qpid::framing::Buffer& buffer) const; - bool operator==(const SchemaClassKeyImpl& other) const; - bool operator<(const SchemaClassKeyImpl& other) const; - const std::string& str() const; - }; - - struct SchemaObjectClassImpl { - std::string package; - std::string name; - mutable SchemaHash hash; - mutable bool hasHash; - std::auto_ptr<SchemaClassKey> classKey; - std::vector<const SchemaProperty*> properties; - std::vector<const SchemaStatistic*> statistics; - std::vector<const SchemaMethod*> methods; - - SchemaObjectClassImpl(const char* p, const char* n) : - package(p), name(n), hasHash(false), classKey(SchemaClassKeyImpl::factory(package, name, hash)) {} - SchemaObjectClassImpl(qpid::framing::Buffer& buffer); - static SchemaObjectClass* factory(qpid::framing::Buffer& buffer); - - void encode(qpid::framing::Buffer& buffer) const; - void addProperty(const SchemaProperty* property); - void addStatistic(const SchemaStatistic* statistic); - void addMethod(const SchemaMethod* method); - - const SchemaClassKey* getClassKey() const; - int getPropertyCount() const { return properties.size(); } - int getStatisticCount() const { return statistics.size(); } - int getMethodCount() const { return methods.size(); } - const SchemaProperty* getProperty(int idx) const; - const SchemaStatistic* getStatistic(int idx) const; - const SchemaMethod* getMethod(int idx) const; - }; - - struct SchemaEventClassImpl { - std::string package; - std::string name; - mutable SchemaHash hash; - mutable bool hasHash; - std::auto_ptr<SchemaClassKey> classKey; - std::string description; - Severity severity; - std::vector<const SchemaArgument*> arguments; - - SchemaEventClassImpl(const char* p, const char* n, Severity sev) : - package(p), name(n), hasHash(false), classKey(SchemaClassKeyImpl::factory(package, name, hash)), severity(sev) {} - SchemaEventClassImpl(qpid::framing::Buffer& buffer); - static SchemaEventClass* factory(qpid::framing::Buffer& buffer); - - void encode(qpid::framing::Buffer& buffer) const; - void addArgument(const SchemaArgument* argument); - void setDesc(const char* desc) { description = desc; } - - const SchemaClassKey* getClassKey() const; - Severity getSeverity() const { return severity; } - int getArgumentCount() const { return arguments.size(); } - const SchemaArgument* getArgument(int idx) const; - }; -} -} - -#endif - diff --git a/cpp/src/qmf/engine/SequenceManager.cpp b/cpp/src/qmf/engine/SequenceManager.cpp deleted file mode 100644 index 4a4644a8b9..0000000000 --- a/cpp/src/qmf/engine/SequenceManager.cpp +++ /dev/null @@ -1,96 +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 "qmf/engine/SequenceManager.h" - -using namespace std; -using namespace qmf::engine; -using namespace qpid::sys; - -SequenceManager::SequenceManager() : nextSequence(1) {} - -void SequenceManager::setUnsolicitedContext(SequenceContext::Ptr ctx) -{ - unsolicitedContext = ctx; -} - -uint32_t SequenceManager::reserve(SequenceContext::Ptr ctx) -{ - Mutex::ScopedLock _lock(lock); - if (ctx.get() == 0) - ctx = unsolicitedContext; - uint32_t seq = nextSequence; - while (contextMap.find(seq) != contextMap.end()) - seq = seq < 0xFFFFFFFF ? seq + 1 : 1; - nextSequence = seq < 0xFFFFFFFF ? seq + 1 : 1; - contextMap[seq] = ctx; - ctx->reserve(); - return seq; -} - -void SequenceManager::release(uint32_t sequence) -{ - Mutex::ScopedLock _lock(lock); - - if (sequence == 0) { - if (unsolicitedContext.get() != 0) - unsolicitedContext->release(); - return; - } - - map<uint32_t, SequenceContext::Ptr>::iterator iter = contextMap.find(sequence); - if (iter != contextMap.end()) { - if (iter->second != 0) - iter->second->release(); - contextMap.erase(iter); - } -} - -void SequenceManager::releaseAll() -{ - Mutex::ScopedLock _lock(lock); - contextMap.clear(); -} - -void SequenceManager::dispatch(uint8_t opcode, uint32_t sequence, const string& routingKey, qpid::framing::Buffer& buffer) -{ - Mutex::ScopedLock _lock(lock); - bool done; - - if (sequence == 0) { - if (unsolicitedContext.get() != 0) { - done = unsolicitedContext->handleMessage(opcode, sequence, routingKey, buffer); - if (done) - unsolicitedContext->release(); - } - return; - } - - map<uint32_t, SequenceContext::Ptr>::iterator iter = contextMap.find(sequence); - if (iter != contextMap.end()) { - if (iter->second != 0) { - done = iter->second->handleMessage(opcode, sequence, routingKey, buffer); - if (done) { - iter->second->release(); - contextMap.erase(iter); - } - } - } -} - diff --git a/cpp/src/qmf/engine/SequenceManager.h b/cpp/src/qmf/engine/SequenceManager.h deleted file mode 100644 index 9e47e38610..0000000000 --- a/cpp/src/qmf/engine/SequenceManager.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _QmfEngineSequenceManager_ -#define _QmfEngineSequenceManager_ - -/* - * 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 "qpid/sys/Mutex.h" -#include <boost/shared_ptr.hpp> -#include <map> - -namespace qpid { - namespace framing { - class Buffer; - } -} - -namespace qmf { -namespace engine { - - class SequenceContext { - public: - typedef boost::shared_ptr<SequenceContext> Ptr; - SequenceContext() {} - virtual ~SequenceContext() {} - - virtual void reserve() = 0; - virtual bool handleMessage(uint8_t opcode, uint32_t sequence, const std::string& routingKey, qpid::framing::Buffer& buffer) = 0; - virtual void release() = 0; - }; - - class SequenceManager { - public: - SequenceManager(); - - void setUnsolicitedContext(SequenceContext::Ptr ctx); - uint32_t reserve(SequenceContext::Ptr ctx = SequenceContext::Ptr()); - void release(uint32_t sequence); - void releaseAll(); - void dispatch(uint8_t opcode, uint32_t sequence, const std::string& routingKey, qpid::framing::Buffer& buffer); - - private: - mutable qpid::sys::Mutex lock; - uint32_t nextSequence; - SequenceContext::Ptr unsolicitedContext; - std::map<uint32_t, SequenceContext::Ptr> contextMap; - }; - -} -} - -#endif - diff --git a/cpp/src/qmf/engine/ValueImpl.cpp b/cpp/src/qmf/engine/ValueImpl.cpp deleted file mode 100644 index f9ebbf5028..0000000000 --- a/cpp/src/qmf/engine/ValueImpl.cpp +++ /dev/null @@ -1,571 +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 "qmf/engine/ValueImpl.h" -#include <qpid/framing/FieldValue.h> -#include <qpid/framing/FieldTable.h> -#include <qpid/framing/List.h> -#include <qpid/log/Statement.h> - -using namespace std; -using namespace qmf::engine; -//using qpid::framing::Buffer; -//using qpid::framing::FieldTable; -//using qpid::framing::FieldValue; -using namespace qpid::framing; - -ValueImpl::ValueImpl(Typecode t, Buffer& buf) : typecode(t) -{ - uint64_t first; - uint64_t second; - FieldTable ft; - List fl; - - switch (typecode) { - case TYPE_UINT8 : value.u32 = (uint32_t) buf.getOctet(); break; - case TYPE_UINT16 : value.u32 = (uint32_t) buf.getShort(); break; - case TYPE_UINT32 : value.u32 = (uint32_t) buf.getLong(); break; - case TYPE_UINT64 : value.u64 = buf.getLongLong(); break; - case TYPE_SSTR : buf.getShortString(stringVal); break; - case TYPE_LSTR : buf.getMediumString(stringVal); break; - case TYPE_ABSTIME : value.s64 = buf.getLongLong(); break; - case TYPE_DELTATIME : value.u64 = buf.getLongLong(); break; - case TYPE_BOOL : value.boolVal = (buf.getOctet() != 0); break; - case TYPE_FLOAT : value.floatVal = buf.getFloat(); break; - case TYPE_DOUBLE : value.doubleVal = buf.getDouble(); break; - case TYPE_INT8 : value.s32 = (int32_t) ((int8_t) buf.getOctet()); break; - case TYPE_INT16 : value.s32 = (int32_t) ((int16_t) buf.getShort()); break; - case TYPE_INT32 : value.s32 = (int32_t) buf.getLong(); break; - case TYPE_INT64 : value.s64 = buf.getLongLong(); break; - case TYPE_UUID : buf.getBin128(value.uuidVal); break; - case TYPE_REF: - first = buf.getLongLong(); - second = buf.getLongLong(); - refVal.impl->setValue(first, second); - break; - - case TYPE_MAP: - ft.decode(buf); - initMap(ft); - break; - - case TYPE_LIST: - fl.decode(buf); - initList(fl); - break; - - case TYPE_ARRAY: - case TYPE_OBJECT: - default: - break; - } -} - -ValueImpl::ValueImpl(Typecode t, Typecode at) : typecode(t), valid(false), arrayTypecode(at) -{ -} - -ValueImpl::ValueImpl(Typecode t) : typecode(t) -{ - ::memset(&value, 0, sizeof(value)); -} - -Value* ValueImpl::factory(Typecode t, Buffer& b) -{ - ValueImpl* impl(new ValueImpl(t, b)); - return new Value(impl); -} - -Value* ValueImpl::factory(Typecode t) -{ - ValueImpl* impl(new ValueImpl(t)); - return new Value(impl); -} - -ValueImpl::~ValueImpl() -{ -} - -void ValueImpl::initMap(const FieldTable& ft) -{ - for (FieldTable::ValueMap::const_iterator iter = ft.begin(); - iter != ft.end(); iter++) { - const string& name(iter->first); - const FieldValue& fvalue(*iter->second); - uint8_t amqType = fvalue.getType(); - - if (amqType == 0x32) { - Value* subval(new Value(TYPE_UINT64)); - subval->setUint64(fvalue.get<int64_t>()); - insert(name.c_str(), subval); - } else if ((amqType & 0xCF) == 0x02) { - Value* subval(new Value(TYPE_UINT32)); - switch (amqType) { - case 0x02 : subval->setUint(fvalue.get<int>()); break; - case 0x12 : subval->setUint(fvalue.get<int>()); break; - case 0x22 : subval->setUint(fvalue.get<int>()); break; - } - insert(name.c_str(), subval); - } else if (amqType == 0x31) { // int64 - Value* subval(new Value(TYPE_INT64)); - subval->setInt64(fvalue.get<int64_t>()); - insert(name.c_str(), subval); - } else if ((amqType & 0xCF) == 0x01) { // 0x01:int8, 0x11:int16, 0x21:int21 - Value* subval(new Value(TYPE_INT32)); - subval->setInt((int32_t)fvalue.get<int>()); - insert(name.c_str(), subval); - } else if (amqType == 0x85 || amqType == 0x95) { - Value* subval(new Value(TYPE_LSTR)); - subval->setString(fvalue.get<string>().c_str()); - insert(name.c_str(), subval); - } else if (amqType == 0x23 || amqType == 0x33) { - Value* subval(new Value(TYPE_DOUBLE)); - subval->setDouble(fvalue.get<double>()); - insert(name.c_str(), subval); - } else if (amqType == 0xa8) { - FieldTable subFt; - bool valid = qpid::framing::getEncodedValue<FieldTable>(iter->second, subFt); - if (valid) { - Value* subval(new Value(TYPE_MAP)); - subval->impl->initMap(subFt); - insert(name.c_str(), subval); - } - } else if (amqType == 0xa9) { - List subList; - bool valid = qpid::framing::getEncodedValue<List>(iter->second, subList); - if (valid) { - Value* subval(new Value(TYPE_LIST)); - subval->impl->initList(subList); - insert(name.c_str(), subval); - } - } else if (amqType == 0x08) { - Value* subval(new Value(TYPE_BOOL)); - subval->setBool(fvalue.get<int>() ? true : false); - insert(name.c_str(), subval); - } else { - QPID_LOG(error, "Unable to decode unsupported AMQP typecode=" << amqType << " map index=" << name); - } - } -} - -void ValueImpl::mapToFieldTable(FieldTable& ft) const -{ - FieldTable subFt; - - for (map<string, Value>::const_iterator iter = mapVal.begin(); - iter != mapVal.end(); iter++) { - const string& name(iter->first); - const Value& subval(iter->second); - - switch (subval.getType()) { - case TYPE_UINT8: - case TYPE_UINT16: - case TYPE_UINT32: - ft.setUInt64(name, (uint64_t) subval.asUint()); - break; - case TYPE_UINT64: - case TYPE_DELTATIME: - ft.setUInt64(name, subval.asUint64()); - break; - case TYPE_SSTR: - case TYPE_LSTR: - ft.setString(name, subval.asString()); - break; - case TYPE_INT64: - case TYPE_ABSTIME: - ft.setInt64(name, subval.asInt64()); - break; - case TYPE_BOOL: - ft.set(name, FieldTable::ValuePtr(new BoolValue(subval.asBool()))); - break; - case TYPE_FLOAT: - ft.setFloat(name, subval.asFloat()); - break; - case TYPE_DOUBLE: - ft.setDouble(name, subval.asDouble()); - break; - case TYPE_INT8: - case TYPE_INT16: - case TYPE_INT32: - ft.setInt(name, subval.asInt()); - break; - case TYPE_MAP: - subFt.clear(); - subval.impl->mapToFieldTable(subFt); - ft.setTable(name, subFt); - break; - case TYPE_LIST: - { - List subList; - subval.impl->listToFramingList(subList); - ft.set(name, - ::qpid::framing::FieldTable::ValuePtr( - new ListValue( - subList))); - } break; - case TYPE_ARRAY: - case TYPE_OBJECT: - case TYPE_UUID: - case TYPE_REF: - default: - break; - } - } - } - - -void ValueImpl::initList(const List& fl) -{ - for (List::const_iterator iter = fl.begin(); - iter != fl.end(); iter++) { - const FieldValue& fvalue(*iter->get()); - uint8_t amqType = fvalue.getType(); - - if (amqType == 0x32) { - Value* subval(new Value(TYPE_UINT64)); - subval->setUint64(fvalue.get<int64_t>()); - appendToList(subval); - } else if ((amqType & 0xCF) == 0x02) { - Value* subval(new Value(TYPE_UINT32)); - switch (amqType) { - case 0x02 : subval->setUint(fvalue.get<int>()); break; // uint8 - case 0x12 : subval->setUint(fvalue.get<int>()); break; // uint16 - case 0x22 : subval->setUint(fvalue.get<int>()); break; // uint32 - } - appendToList(subval); - } else if (amqType == 0x31) { // int64 - Value* subval(new Value(TYPE_INT64)); - subval->setInt64(fvalue.get<int64_t>()); - appendToList(subval); - } else if ((amqType & 0xCF) == 0x01) { // 0x01:int8, 0x11:int16, 0x21:int32 - Value* subval(new Value(TYPE_INT32)); - subval->setInt((int32_t)fvalue.get<int>()); - appendToList(subval); - } else if (amqType == 0x85 || amqType == 0x95) { - Value* subval(new Value(TYPE_LSTR)); - subval->setString(fvalue.get<string>().c_str()); - appendToList(subval); - } else if (amqType == 0x23 || amqType == 0x33) { - Value* subval(new Value(TYPE_DOUBLE)); - subval->setDouble(fvalue.get<double>()); - appendToList(subval); - } else if (amqType == 0xa8) { - FieldTable subFt; - bool valid = qpid::framing::getEncodedValue<FieldTable>(*iter, subFt); - if (valid) { - Value* subval(new Value(TYPE_MAP)); - subval->impl->initMap(subFt); - appendToList(subval); - } - } else if (amqType == 0xa9) { - List subList; - bool valid = qpid::framing::getEncodedValue<List>(*iter, subList); - if (valid) { - Value *subVal(new Value(TYPE_LIST)); - subVal->impl->initList(subList); - appendToList(subVal); - } - } else if (amqType == 0x08) { - Value* subval(new Value(TYPE_BOOL)); - subval->setBool(fvalue.get<int>() ? true : false); - appendToList(subval); - } else { - QPID_LOG(error, "Unable to decode unsupported AMQP typecode =" << amqType); - } - } -} - -void ValueImpl::listToFramingList(List& fl) const -{ - for (vector<Value>::const_iterator iter = vectorVal.begin(); - iter != vectorVal.end(); iter++) { - const Value& subval(*iter); - - switch (subval.getType()) { - case TYPE_UINT8: - case TYPE_UINT16: - case TYPE_UINT32: - fl.push_back(List::ValuePtr(new Unsigned64Value((uint64_t) subval.asUint()))); - break; - case TYPE_UINT64: - case TYPE_DELTATIME: - fl.push_back(List::ValuePtr(new Unsigned64Value(subval.asUint64()))); - break; - case TYPE_SSTR: - case TYPE_LSTR: - fl.push_back(List::ValuePtr(new Str16Value(subval.asString()))); - break; - case TYPE_INT64: - case TYPE_ABSTIME: - fl.push_back(List::ValuePtr(new Integer64Value(subval.asInt64()))); - break; - case TYPE_BOOL: - fl.push_back(List::ValuePtr(new BoolValue(subval.asBool() ? 1 : 0))); - break; - case TYPE_FLOAT: - fl.push_back(List::ValuePtr(new FloatValue(subval.asFloat()))); - break; - case TYPE_DOUBLE: - fl.push_back(List::ValuePtr(new DoubleValue(subval.asDouble()))); - break; - case TYPE_INT8: - case TYPE_INT16: - case TYPE_INT32: - fl.push_back(List::ValuePtr(new IntegerValue(subval.asInt()))); - break; - case TYPE_MAP: - { - FieldTable subFt; - subval.impl->mapToFieldTable(subFt); - fl.push_back(List::ValuePtr(new FieldTableValue(subFt))); - - } break; - case TYPE_LIST: - { - List subList; - subval.impl->listToFramingList(subList); - fl.push_back(List::ValuePtr(new ListValue(subList))); - } break; - - case TYPE_ARRAY: - case TYPE_OBJECT: - case TYPE_UUID: - case TYPE_REF: - default: - break; - } - } - } - - - -void ValueImpl::encode(Buffer& buf) const -{ - FieldTable ft; - List fl; - - switch (typecode) { - case TYPE_UINT8 : buf.putOctet((uint8_t) value.u32); break; - case TYPE_UINT16 : buf.putShort((uint16_t) value.u32); break; - case TYPE_UINT32 : buf.putLong(value.u32); break; - case TYPE_UINT64 : buf.putLongLong(value.u64); break; - case TYPE_SSTR : buf.putShortString(stringVal); break; - case TYPE_LSTR : buf.putMediumString(stringVal); break; - case TYPE_ABSTIME : buf.putLongLong(value.s64); break; - case TYPE_DELTATIME : buf.putLongLong(value.u64); break; - case TYPE_BOOL : buf.putOctet(value.boolVal ? 1 : 0); break; - case TYPE_FLOAT : buf.putFloat(value.floatVal); break; - case TYPE_DOUBLE : buf.putDouble(value.doubleVal); break; - case TYPE_INT8 : buf.putOctet((uint8_t) value.s32); break; - case TYPE_INT16 : buf.putShort((uint16_t) value.s32); break; - case TYPE_INT32 : buf.putLong(value.s32); break; - case TYPE_INT64 : buf.putLongLong(value.s64); break; - case TYPE_UUID : buf.putBin128(value.uuidVal); break; - case TYPE_REF : refVal.impl->encode(buf); break; - case TYPE_MAP: - mapToFieldTable(ft); - ft.encode(buf); - break; - case TYPE_LIST: - listToFramingList(fl); - fl.encode(buf); - break; - - case TYPE_ARRAY: - case TYPE_OBJECT: - default: - break; - } -} - -uint32_t ValueImpl::encodedSize() const -{ - FieldTable ft; - List fl; - - switch (typecode) { - case TYPE_UINT8 : - case TYPE_BOOL : - case TYPE_INT8 : return 1; - - case TYPE_UINT16 : - case TYPE_INT16 : return 2; - - case TYPE_UINT32 : - case TYPE_INT32 : - case TYPE_FLOAT : return 4; - - case TYPE_UINT64 : - case TYPE_INT64 : - case TYPE_DOUBLE : - case TYPE_ABSTIME : - case TYPE_DELTATIME : return 8; - - case TYPE_UUID : - case TYPE_REF : return 16; - - case TYPE_SSTR : return 1 + stringVal.size(); - case TYPE_LSTR : return 2 + stringVal.size(); - case TYPE_MAP: - mapToFieldTable(ft); - return ft.encodedSize(); - - case TYPE_LIST: - listToFramingList(fl); - return fl.encodedSize(); - - case TYPE_ARRAY: - case TYPE_OBJECT: - default: - break; - } - - return 0; -} - -bool ValueImpl::keyInMap(const char* key) const -{ - return typecode == TYPE_MAP && mapVal.count(key) > 0; -} - -Value* ValueImpl::byKey(const char* key) -{ - if (keyInMap(key)) { - map<string, Value>::iterator iter = mapVal.find(key); - if (iter != mapVal.end()) - return &iter->second; - } - return 0; -} - -const Value* ValueImpl::byKey(const char* key) const -{ - if (keyInMap(key)) { - map<string, Value>::const_iterator iter = mapVal.find(key); - if (iter != mapVal.end()) - return &iter->second; - } - return 0; -} - -void ValueImpl::deleteKey(const char* key) -{ - mapVal.erase(key); -} - -void ValueImpl::insert(const char* key, Value* val) -{ - pair<string, Value> entry(key, *val); - mapVal.insert(entry); -} - -const char* ValueImpl::key(uint32_t idx) const -{ - map<string, Value>::const_iterator iter = mapVal.begin(); - for (uint32_t i = 0; i < idx; i++) { - if (iter == mapVal.end()) - break; - iter++; - } - - if (iter == mapVal.end()) - return 0; - else - return iter->first.c_str(); -} - -Value* ValueImpl::arrayItem(uint32_t) -{ - return 0; -} - -void ValueImpl::appendToArray(Value*) -{ -} - -void ValueImpl::deleteArrayItem(uint32_t) -{ -} - - -//================================================================== -// Wrappers -//================================================================== - -Value::Value(const Value& from) : impl(new ValueImpl(*(from.impl))) {} -Value::Value(Typecode t, Typecode at) : impl(new ValueImpl(t, at)) {} -Value::Value(ValueImpl* i) : impl(i) {} -Value::~Value() { delete impl;} - -Typecode Value::getType() const { return impl->getType(); } -bool Value::isNull() const { return impl->isNull(); } -void Value::setNull() { impl->setNull(); } -bool Value::isObjectId() const { return impl->isObjectId(); } -const ObjectId& Value::asObjectId() const { return impl->asObjectId(); } -void Value::setObjectId(const ObjectId& oid) { impl->setObjectId(oid); } -bool Value::isUint() const { return impl->isUint(); } -uint32_t Value::asUint() const { return impl->asUint(); } -void Value::setUint(uint32_t val) { impl->setUint(val); } -bool Value::isInt() const { return impl->isInt(); } -int32_t Value::asInt() const { return impl->asInt(); } -void Value::setInt(int32_t val) { impl->setInt(val); } -bool Value::isUint64() const { return impl->isUint64(); } -uint64_t Value::asUint64() const { return impl->asUint64(); } -void Value::setUint64(uint64_t val) { impl->setUint64(val); } -bool Value::isInt64() const { return impl->isInt64(); } -int64_t Value::asInt64() const { return impl->asInt64(); } -void Value::setInt64(int64_t val) { impl->setInt64(val); } -bool Value::isString() const { return impl->isString(); } -const char* Value::asString() const { return impl->asString(); } -void Value::setString(const char* val) { impl->setString(val); } -bool Value::isBool() const { return impl->isBool(); } -bool Value::asBool() const { return impl->asBool(); } -void Value::setBool(bool val) { impl->setBool(val); } -bool Value::isFloat() const { return impl->isFloat(); } -float Value::asFloat() const { return impl->asFloat(); } -void Value::setFloat(float val) { impl->setFloat(val); } -bool Value::isDouble() const { return impl->isDouble(); } -double Value::asDouble() const { return impl->asDouble(); } -void Value::setDouble(double val) { impl->setDouble(val); } -bool Value::isUuid() const { return impl->isUuid(); } -const uint8_t* Value::asUuid() const { return impl->asUuid(); } -void Value::setUuid(const uint8_t* val) { impl->setUuid(val); } -bool Value::isObject() const { return impl->isObject(); } -const Object* Value::asObject() const { return impl->asObject(); } -void Value::setObject(Object* val) { impl->setObject(val); } -bool Value::isMap() const { return impl->isMap(); } -bool Value::keyInMap(const char* key) const { return impl->keyInMap(key); } -Value* Value::byKey(const char* key) { return impl->byKey(key); } -const Value* Value::byKey(const char* key) const { return impl->byKey(key); } -void Value::deleteKey(const char* key) { impl->deleteKey(key); } -void Value::insert(const char* key, Value* val) { impl->insert(key, val); } -uint32_t Value::keyCount() const { return impl->keyCount(); } -const char* Value::key(uint32_t idx) const { return impl->key(idx); } -bool Value::isList() const { return impl->isList(); } -uint32_t Value::listItemCount() const { return impl->listItemCount(); } -Value* Value::listItem(uint32_t idx) { return impl->listItem(idx); } -void Value::appendToList(Value* val) { impl->appendToList(val); } -void Value::deleteListItem(uint32_t idx) { impl->deleteListItem(idx); } -bool Value::isArray() const { return impl->isArray(); } -Typecode Value::arrayType() const { return impl->arrayType(); } -uint32_t Value::arrayItemCount() const { return impl->arrayItemCount(); } -Value* Value::arrayItem(uint32_t idx) { return impl->arrayItem(idx); } -void Value::appendToArray(Value* val) { impl->appendToArray(val); } -void Value::deleteArrayItem(uint32_t idx) { impl->deleteArrayItem(idx); } - diff --git a/cpp/src/qmf/engine/ValueImpl.h b/cpp/src/qmf/engine/ValueImpl.h deleted file mode 100644 index 8de8c5329f..0000000000 --- a/cpp/src/qmf/engine/ValueImpl.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef _QmfEngineValueImpl_ -#define _QmfEngineValueImpl_ - -/* - * 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 <qmf/engine/Value.h> -#include <qmf/engine/ObjectIdImpl.h> -#include <qmf/engine/Object.h> -#include <qpid/framing/Buffer.h> -#include <string> -#include <string.h> -#include <map> -#include <vector> -#include <boost/shared_ptr.hpp> - -namespace qpid { -namespace framing { - class FieldTable; - class List; -} -} - -namespace qmf { -namespace engine { - - // TODO: set valid flag on all value settors - // TODO: add a modified flag and accessors - - struct ValueImpl { - const Typecode typecode; - bool valid; - - ObjectId refVal; - std::string stringVal; - std::auto_ptr<Object> objectVal; - std::map<std::string, Value> mapVal; - std::vector<Value> vectorVal; - Typecode arrayTypecode; - - union { - uint32_t u32; - uint64_t u64; - int32_t s32; - int64_t s64; - bool boolVal; - float floatVal; - double doubleVal; - uint8_t uuidVal[16]; - } value; - - ValueImpl(const ValueImpl& from) : - typecode(from.typecode), valid(from.valid), refVal(from.refVal), stringVal(from.stringVal), - objectVal(from.objectVal.get() ? new Object(*(from.objectVal)) : 0), - mapVal(from.mapVal), vectorVal(from.vectorVal), arrayTypecode(from.arrayTypecode), - value(from.value) {} - - ValueImpl(Typecode t, Typecode at); - ValueImpl(Typecode t, qpid::framing::Buffer& b); - ValueImpl(Typecode t); - static Value* factory(Typecode t, qpid::framing::Buffer& b); - static Value* factory(Typecode t); - ~ValueImpl(); - - void encode(qpid::framing::Buffer& b) const; - uint32_t encodedSize() const; - - Typecode getType() const { return typecode; } - bool isNull() const { return !valid; } - void setNull() { valid = false; } - - bool isObjectId() const { return typecode == TYPE_REF; } - const ObjectId& asObjectId() const { return refVal; } - void setObjectId(const ObjectId& o) { refVal = o; } // TODO - - bool isUint() const { return typecode >= TYPE_UINT8 && typecode <= TYPE_UINT32; } - uint32_t asUint() const { return value.u32; } - void setUint(uint32_t val) { value.u32 = val; } - - bool isInt() const { return typecode >= TYPE_INT8 && typecode <= TYPE_INT32; } - int32_t asInt() const { return value.s32; } - void setInt(int32_t val) { value.s32 = val; } - - bool isUint64() const { return typecode == TYPE_UINT64 || typecode == TYPE_DELTATIME; } - uint64_t asUint64() const { return value.u64; } - void setUint64(uint64_t val) { value.u64 = val; } - - bool isInt64() const { return typecode == TYPE_INT64 || typecode == TYPE_ABSTIME; } - int64_t asInt64() const { return value.s64; } - void setInt64(int64_t val) { value.s64 = val; } - - bool isString() const { return typecode == TYPE_SSTR || typecode == TYPE_LSTR; } - const char* asString() const { return stringVal.c_str(); } - void setString(const char* val) { stringVal = val; } - - bool isBool() const { return typecode == TYPE_BOOL; } - bool asBool() const { return value.boolVal; } - void setBool(bool val) { value.boolVal = val; } - - bool isFloat() const { return typecode == TYPE_FLOAT; } - float asFloat() const { return value.floatVal; } - void setFloat(float val) { value.floatVal = val; } - - bool isDouble() const { return typecode == TYPE_DOUBLE; } - double asDouble() const { return value.doubleVal; } - void setDouble(double val) { value.doubleVal = val; } - - bool isUuid() const { return typecode == TYPE_UUID; } - const uint8_t* asUuid() const { return value.uuidVal; } - void setUuid(const uint8_t* val) { ::memcpy(value.uuidVal, val, 16); } - - bool isObject() const { return typecode == TYPE_OBJECT; } - Object* asObject() const { return objectVal.get(); } - void setObject(Object* val) { objectVal.reset(val); } - - bool isMap() const { return typecode == TYPE_MAP; } - bool keyInMap(const char* key) const; - Value* byKey(const char* key); - const Value* byKey(const char* key) const; - void deleteKey(const char* key); - void insert(const char* key, Value* val); - uint32_t keyCount() const { return mapVal.size(); } - const char* key(uint32_t idx) const; - - bool isList() const { return typecode == TYPE_LIST; } - uint32_t listItemCount() const { return vectorVal.size(); } - Value* listItem(uint32_t idx) { return idx < listItemCount() ? &vectorVal[idx] : 0; } - const Value* listItem(uint32_t idx) const { return idx < listItemCount() ? &vectorVal[idx] : 0; } - void appendToList(Value* val) { vectorVal.push_back(*val); } - void deleteListItem(uint32_t idx) { if (idx < listItemCount()) vectorVal.erase(vectorVal.begin()+idx); } - - bool isArray() const { return typecode == TYPE_ARRAY; } - Typecode arrayType() const { return arrayTypecode; } - uint32_t arrayItemCount() const { return 0; } - Value* arrayItem(uint32_t idx); - void appendToArray(Value* val); - void deleteArrayItem(uint32_t idx); - - private: - void mapToFieldTable(qpid::framing::FieldTable& ft) const; - void initMap(const qpid::framing::FieldTable& ft); - - void listToFramingList(qpid::framing::List& fl) const; - void initList(const qpid::framing::List& fl); - }; -} -} - -#endif - diff --git a/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/cpp/src/qpid/agent/ManagementAgentImpl.cpp deleted file mode 100644 index a48789973a..0000000000 --- a/cpp/src/qpid/agent/ManagementAgentImpl.cpp +++ /dev/null @@ -1,1434 +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 "qpid/management/Manageable.h" -#include "qpid/management/ManagementObject.h" -#include "qpid/log/Statement.h" -#include "qpid/agent/ManagementAgentImpl.h" -#include "qpid/amqp_0_10/Codecs.h" -#include <list> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <iostream> -#include <fstream> -#include <boost/lexical_cast.hpp> - -namespace qpid { -namespace management { - -using namespace qpid::client; -using namespace qpid::framing; -using namespace qpid::sys; -using namespace std; -using std::stringstream; -using std::ofstream; -using std::ifstream; -using std::string; -using std::endl; -using qpid::types::Variant; -using qpid::amqp_0_10::MapCodec; -using qpid::amqp_0_10::ListCodec; - -namespace { - qpid::sys::Mutex lock; - bool disabled = false; - ManagementAgent* agent = 0; - int refCount = 0; - - const string defaultVendorName("vendor"); - const string defaultProductName("product"); - - // Create a valid binding key substring by - // replacing all '.' chars with '_' - const string keyifyNameStr(const string& name) - { - string n2 = name; - - size_t pos = n2.find('.'); - while (pos != n2.npos) { - n2.replace(pos, 1, "_"); - pos = n2.find('.', pos); - } - return n2; - } -} - -ManagementAgent::Singleton::Singleton(bool disableManagement) -{ - sys::Mutex::ScopedLock _lock(lock); - if (disableManagement && !disabled) { - disabled = true; - assert(refCount == 0); // can't disable after agent has been allocated - } - if (refCount == 0 && !disabled) - agent = new ManagementAgentImpl(); - refCount++; -} - -ManagementAgent::Singleton::~Singleton() -{ - sys::Mutex::ScopedLock _lock(lock); - refCount--; - if (refCount == 0 && !disabled) { - delete agent; - agent = 0; - } -} - -ManagementAgent* ManagementAgent::Singleton::getInstance() -{ - return agent; -} - -const string ManagementAgentImpl::storeMagicNumber("MA02"); - -ManagementAgentImpl::ManagementAgentImpl() : - interval(10), extThread(false), pipeHandle(0), notifyCallback(0), notifyContext(0), - notifyable(0), inCallback(false), - initialized(false), connected(false), useMapMsg(false), lastFailure("never connected"), - topicExchange("qmf.default.topic"), directExchange("qmf.default.direct"), - schemaTimestamp(Duration(EPOCH, now())), - publishAllData(true), requestedBrokerBank(0), requestedAgentBank(0), - assignedBrokerBank(0), assignedAgentBank(0), bootSequence(0), - maxV2ReplyObjs(10), // KAG todo: make this a tuneable parameter - connThreadBody(*this), connThread(connThreadBody), - pubThreadBody(*this), pubThread(pubThreadBody) -{ -} - -ManagementAgentImpl::~ManagementAgentImpl() -{ - // shutdown & cleanup all threads - connThreadBody.close(); - pubThreadBody.close(); - - connThread.join(); - pubThread.join(); - - if (pipeHandle) { - delete pipeHandle; - pipeHandle = 0; - } -} - -void ManagementAgentImpl::setName(const string& vendor, const string& product, const string& instance) -{ - if (vendor.find(':') != vendor.npos) { - throw Exception("vendor string cannot contain a ':' character."); - } - if (product.find(':') != product.npos) { - throw Exception("product string cannot contain a ':' character."); - } - - attrMap["_vendor"] = vendor; - attrMap["_product"] = product; - if (!instance.empty()) { - attrMap["_instance"] = instance; - } -} - - -void ManagementAgentImpl::getName(string& vendor, string& product, string& instance) -{ - vendor = std::string(attrMap["_vendor"]); - product = std::string(attrMap["_product"]); - instance = std::string(attrMap["_instance"]); -} - - -const std::string& ManagementAgentImpl::getAddress() -{ - return name_address; -} - - -void ManagementAgentImpl::init(const string& brokerHost, - uint16_t brokerPort, - uint16_t intervalSeconds, - bool useExternalThread, - const string& _storeFile, - const string& uid, - const string& pwd, - const string& mech, - const string& proto) -{ - management::ConnectionSettings settings; - settings.protocol = proto; - settings.host = brokerHost; - settings.port = brokerPort; - settings.username = uid; - settings.password = pwd; - settings.mechanism = mech; - settings.heartbeat = 10; - init(settings, intervalSeconds, useExternalThread, _storeFile); -} - -void ManagementAgentImpl::init(const qpid::management::ConnectionSettings& settings, - uint16_t intervalSeconds, - bool useExternalThread, - const string& _storeFile) -{ - std::string cfgVendor, cfgProduct, cfgInstance; - - interval = intervalSeconds; - extThread = useExternalThread; - storeFile = _storeFile; - nextObjectId = 1; - - // - // Convert from management::ConnectionSettings to client::ConnectionSettings - // - connectionSettings.protocol = settings.protocol; - connectionSettings.host = settings.host; - connectionSettings.port = settings.port; - connectionSettings.virtualhost = settings.virtualhost; - connectionSettings.username = settings.username; - connectionSettings.password = settings.password; - connectionSettings.mechanism = settings.mechanism; - connectionSettings.locale = settings.locale; - connectionSettings.heartbeat = settings.heartbeat; - connectionSettings.maxChannels = settings.maxChannels; - connectionSettings.maxFrameSize = settings.maxFrameSize; - connectionSettings.bounds = settings.bounds; - connectionSettings.tcpNoDelay = settings.tcpNoDelay; - connectionSettings.service = settings.service; - connectionSettings.minSsf = settings.minSsf; - connectionSettings.maxSsf = settings.maxSsf; - - retrieveData(cfgVendor, cfgProduct, cfgInstance); - - bootSequence++; - if ((bootSequence & 0xF000) != 0) - bootSequence = 1; - - // setup the agent's name. The name may be set via a call to setName(). If setName() - // has not been called, the name can be read from the configuration file. If there is - // no name in the configuration file, a unique default name is provided. - if (attrMap.empty()) { - // setName() never called by application, so use names retrieved from config, otherwise defaults. - setName(cfgVendor.empty() ? defaultVendorName : cfgVendor, - cfgProduct.empty() ? defaultProductName : cfgProduct, - cfgInstance.empty() ? qpid::types::Uuid(true).str() : cfgInstance); - } else if (attrMap.find("_instance") == attrMap.end()) { - // setName() called, but instance was not specified, use config or generate a uuid - setName(attrMap["_vendor"].asString(), attrMap["_product"].asString(), - cfgInstance.empty() ? qpid::types::Uuid(true).str() : cfgInstance); - } - - name_address = attrMap["_vendor"].asString() + ":" + attrMap["_product"].asString() + ":" + attrMap["_instance"].asString(); - vendorNameKey = keyifyNameStr(attrMap["_vendor"].asString()); - productNameKey = keyifyNameStr(attrMap["_product"].asString()); - instanceNameKey = keyifyNameStr(attrMap["_instance"].asString()); - attrMap["_name"] = name_address; - - storeData(true); - - QPID_LOG(info, "QMF Agent Initialized: broker=" << settings.host << ":" << settings.port << - " interval=" << intervalSeconds << " storeFile=" << _storeFile << " name=" << name_address); - - initialized = true; -} - -void ManagementAgentImpl::registerClass(const string& packageName, - const string& className, - uint8_t* md5Sum, - ManagementObject::writeSchemaCall_t schemaCall) -{ - sys::Mutex::ScopedLock lock(agentLock); - PackageMap::iterator pIter = findOrAddPackage(packageName); - addClassLocal(ManagementItem::CLASS_KIND_TABLE, pIter, className, md5Sum, schemaCall); -} - -void ManagementAgentImpl::registerEvent(const string& packageName, - const string& eventName, - uint8_t* md5Sum, - ManagementObject::writeSchemaCall_t schemaCall) -{ - sys::Mutex::ScopedLock lock(agentLock); - PackageMap::iterator pIter = findOrAddPackage(packageName); - addClassLocal(ManagementItem::CLASS_KIND_EVENT, pIter, eventName, md5Sum, schemaCall); -} - -// old-style add object: 64bit id - deprecated -ObjectId ManagementAgentImpl::addObject(ManagementObject* object, - uint64_t persistId) -{ - std::string key; - if (persistId) { - key = boost::lexical_cast<std::string>(persistId); - } - return addObject(object, key, persistId != 0); -} - - -// new style add object - use this approach! -ObjectId ManagementAgentImpl::addObject(ManagementObject* object, - const std::string& key, - bool persistent) -{ - sys::Mutex::ScopedLock lock(addLock); - - uint16_t sequence = persistent ? 0 : bootSequence; - - ObjectId objectId(&attachment, 0, sequence); - if (key.empty()) - objectId.setV2Key(*object); // let object generate the key - else - objectId.setV2Key(key); - objectId.setAgentName(name_address); - - object->setObjectId(objectId); - newManagementObjects[objectId] = boost::shared_ptr<ManagementObject>(object); - return objectId; -} - - -void ManagementAgentImpl::raiseEvent(const ManagementEvent& event, severity_t severity) -{ - static const std::string severityStr[] = { - "emerg", "alert", "crit", "error", "warn", - "note", "info", "debug" - }; - string content; - stringstream key; - Variant::Map headers; - - { - sys::Mutex::ScopedLock lock(agentLock); - Buffer outBuffer(eventBuffer, MA_BUFFER_SIZE); - uint8_t sev = (severity == SEV_DEFAULT) ? event.getSeverity() : (uint8_t) severity; - - // key << "console.event." << assignedBrokerBank << "." << assignedAgentBank << "." << - // event.getPackageName() << "." << event.getEventName(); - key << "agent.ind.event." << keyifyNameStr(event.getPackageName()) - << "." << keyifyNameStr(event.getEventName()) - << "." << severityStr[sev] - << "." << vendorNameKey - << "." << productNameKey - << "." << instanceNameKey; - - Variant::Map map_; - Variant::Map schemaId; - Variant::Map values; - - map_["_schema_id"] = mapEncodeSchemaId(event.getPackageName(), - event.getEventName(), - event.getMd5Sum(), - ManagementItem::CLASS_KIND_EVENT); - event.mapEncode(values); - map_["_values"] = values; - map_["_timestamp"] = uint64_t(Duration(EPOCH, now())); - map_["_severity"] = sev; - - headers["method"] = "indication"; - headers["qmf.opcode"] = "_data_indication"; - headers["qmf.content"] = "_event"; - headers["qmf.agent"] = name_address; - - Variant::List list; - list.push_back(map_); - ListCodec::encode(list, content); - } - - connThreadBody.sendBuffer(content, "", headers, topicExchange, key.str(), "amqp/list"); -} - -uint32_t ManagementAgentImpl::pollCallbacks(uint32_t callLimit) -{ - sys::Mutex::ScopedLock lock(agentLock); - - if (inCallback) { - QPID_LOG(critical, "pollCallbacks invoked from the agent's thread!"); - return 0; - } - - for (uint32_t idx = 0; callLimit == 0 || idx < callLimit; idx++) { - if (methodQueue.empty()) - break; - - QueuedMethod* item = methodQueue.front(); - methodQueue.pop_front(); - { - sys::Mutex::ScopedUnlock unlock(agentLock); - invokeMethodRequest(item->body, item->cid, item->replyToExchange, item->replyToKey, item->userId); - delete item; - } - } - - if (pipeHandle != 0) { - char rbuf[100]; - while (pipeHandle->read(rbuf, 100) > 0) ; // Consume all signaling bytes - } - return methodQueue.size(); -} - -int ManagementAgentImpl::getSignalFd() -{ - if (extThread) { - if (pipeHandle == 0) - pipeHandle = new PipeHandle(true); - return pipeHandle->getReadHandle(); - } - - return -1; -} - -void ManagementAgentImpl::setSignalCallback(cb_t callback, void* context) -{ - sys::Mutex::ScopedLock lock(agentLock); - notifyCallback = callback; - notifyContext = context; -} - -void ManagementAgentImpl::setSignalCallback(Notifyable& _notifyable) -{ - sys::Mutex::ScopedLock lock(agentLock); - notifyable = &_notifyable; -} - -void ManagementAgentImpl::startProtocol() -{ - sendHeartbeat(); - { - sys::Mutex::ScopedLock lock(agentLock); - publishAllData = true; - } -} - -void ManagementAgentImpl::storeData(bool requested) -{ - if (!storeFile.empty()) { - ofstream outFile(storeFile.c_str()); - uint32_t brokerBankToWrite = requested ? requestedBrokerBank : assignedBrokerBank; - uint32_t agentBankToWrite = requested ? requestedAgentBank : assignedAgentBank; - - if (outFile.good()) { - outFile << storeMagicNumber << " " << brokerBankToWrite << " " << - agentBankToWrite << " " << bootSequence << endl; - - if (attrMap.find("_vendor") != attrMap.end()) - outFile << "vendor=" << attrMap["_vendor"] << endl; - if (attrMap.find("_product") != attrMap.end()) - outFile << "product=" << attrMap["_product"] << endl; - if (attrMap.find("_instance") != attrMap.end()) - outFile << "instance=" << attrMap["_instance"] << endl; - - outFile.close(); - } - } -} - -void ManagementAgentImpl::retrieveData(std::string& vendor, std::string& product, std::string& inst) -{ - vendor.clear(); - product.clear(); - inst.clear(); - - if (!storeFile.empty()) { - ifstream inFile(storeFile.c_str()); - string mn; - - if (inFile.good()) { - inFile >> mn; - if (mn == storeMagicNumber) { - std::string inText; - - inFile >> requestedBrokerBank; - inFile >> requestedAgentBank; - inFile >> bootSequence; - - while (inFile.good()) { - std::getline(inFile, inText); - if (!inText.compare(0, 7, "vendor=")) { - vendor = inText.substr(7); - QPID_LOG(debug, "read vendor name [" << vendor << "] from configuration file."); - } else if (!inText.compare(0, 8, "product=")) { - product = inText.substr(8); - QPID_LOG(debug, "read product name [" << product << "] from configuration file."); - } else if (!inText.compare(0, 9, "instance=")) { - inst = inText.substr(9); - QPID_LOG(debug, "read instance name [" << inst << "] from configuration file."); - } - } - } - inFile.close(); - } - } -} - -void ManagementAgentImpl::sendHeartbeat() -{ - static const string addr_key_base("agent.ind.heartbeat."); - - Variant::Map map; - Variant::Map headers; - string content; - std::stringstream addr_key; - - addr_key << addr_key_base << vendorNameKey - << "." << productNameKey - << "." << instanceNameKey; - - headers["method"] = "indication"; - headers["qmf.opcode"] = "_agent_heartbeat_indication"; - headers["qmf.agent"] = name_address; - - getHeartbeatContent(map); - MapCodec::encode(map, content); - - // Set TTL (in msecs) on outgoing heartbeat indications based on the interval - // time to prevent stale heartbeats from getting to the consoles. - - connThreadBody.sendBuffer(content, "", headers, topicExchange, addr_key.str(), - "amqp/map", interval * 2 * 1000); - - QPID_LOG(trace, "SENT AgentHeartbeat name=" << name_address); -} - -void ManagementAgentImpl::sendException(const string& rte, const string& rtk, const string& cid, - const string& text, uint32_t code) -{ - Variant::Map map; - Variant::Map headers; - Variant::Map values; - string content; - - headers["method"] = "indication"; - headers["qmf.opcode"] = "_exception"; - headers["qmf.agent"] = name_address; - - values["error_code"] = code; - values["error_text"] = text; - map["_values"] = values; - - MapCodec::encode(map, content); - connThreadBody.sendBuffer(content, cid, headers, rte, rtk); - - QPID_LOG(trace, "SENT Exception code=" << code <<" text=" << text); -} - -void ManagementAgentImpl::handleSchemaRequest(Buffer& inBuffer, uint32_t sequence, const string& rte, const string& rtk) -{ - string packageName; - SchemaClassKey key; - uint32_t outLen(0); - char localBuffer[MA_BUFFER_SIZE]; - Buffer outBuffer(localBuffer, MA_BUFFER_SIZE); - bool found(false); - - inBuffer.getShortString(packageName); - inBuffer.getShortString(key.name); - inBuffer.getBin128(key.hash); - - QPID_LOG(trace, "RCVD SchemaRequest: package=" << packageName << " class=" << key.name); - - { - sys::Mutex::ScopedLock lock(agentLock); - PackageMap::iterator pIter = packages.find(packageName); - if (pIter != packages.end()) { - ClassMap& cMap = pIter->second; - ClassMap::iterator cIter = cMap.find(key); - if (cIter != cMap.end()) { - SchemaClass& schema = cIter->second; - string body; - - encodeHeader(outBuffer, 's', sequence); - schema.writeSchemaCall(body); - outBuffer.putRawData(body); - outLen = MA_BUFFER_SIZE - outBuffer.available(); - outBuffer.reset(); - found = true; - } - } - } - - if (found) { - connThreadBody.sendBuffer(outBuffer, outLen, rte, rtk); - QPID_LOG(trace, "SENT SchemaInd: package=" << packageName << " class=" << key.name); - } -} - -void ManagementAgentImpl::handleConsoleAddedIndication() -{ - sys::Mutex::ScopedLock lock(agentLock); - publishAllData = true; - - QPID_LOG(trace, "RCVD ConsoleAddedInd"); -} - -void ManagementAgentImpl::invokeMethodRequest(const string& body, const string& cid, const string& rte, const string& rtk, const string& userId) -{ - string methodName; - bool failed = false; - Variant::Map inMap; - Variant::Map outMap; - Variant::Map::const_iterator oid, mid; - string content; - - MapCodec::decode(body, inMap); - - if ((oid = inMap.find("_object_id")) == inMap.end() || - (mid = inMap.find("_method_name")) == inMap.end()) { - sendException(rte, rtk, cid, Manageable::StatusText(Manageable::STATUS_PARAMETER_INVALID), - Manageable::STATUS_PARAMETER_INVALID); - failed = true; - } else { - string methodName; - ObjectId objId; - Variant::Map inArgs; - Variant::Map callMap; - - try { - // conversions will throw if input is invalid. - objId = ObjectId(oid->second.asMap()); - methodName = mid->second.getString(); - - mid = inMap.find("_arguments"); - if (mid != inMap.end()) { - inArgs = (mid->second).asMap(); - } - - QPID_LOG(trace, "Invoking Method: name=" << methodName << " args=" << inArgs); - - boost::shared_ptr<ManagementObject> oPtr; - { - sys::Mutex::ScopedLock lock(agentLock); - ObjectMap::iterator iter = managementObjects.find(objId); - if (iter != managementObjects.end() && !iter->second->isDeleted()) - oPtr = iter->second; - } - - if (oPtr.get() == 0) { - sendException(rte, rtk, cid, Manageable::StatusText(Manageable::STATUS_UNKNOWN_OBJECT), - Manageable::STATUS_UNKNOWN_OBJECT); - failed = true; - } else { - oPtr->doMethod(methodName, inArgs, callMap, userId); - - if (callMap["_status_code"].asUint32() == 0) { - outMap["_arguments"] = Variant::Map(); - for (Variant::Map::const_iterator iter = callMap.begin(); - iter != callMap.end(); iter++) - if (iter->first != "_status_code" && iter->first != "_status_text") - outMap["_arguments"].asMap()[iter->first] = iter->second; - } else { - sendException(rte, rtk, cid, callMap["_status_text"], callMap["_status_code"]); - failed = true; - } - } - - } catch(types::InvalidConversion& e) { - sendException(rte, rtk, cid, e.what(), Manageable::STATUS_EXCEPTION); - failed = true; - } - } - - if (!failed) { - Variant::Map headers; - headers["method"] = "response"; - headers["qmf.agent"] = name_address; - headers["qmf.opcode"] = "_method_response"; - QPID_LOG(trace, "SENT MethodResponse map=" << outMap); - MapCodec::encode(outMap, content); - connThreadBody.sendBuffer(content, cid, headers, rte, rtk); - } -} - -void ManagementAgentImpl::handleGetQuery(const string& body, const string& cid, const string& rte, const string& rtk) -{ - { - sys::Mutex::ScopedLock lock(agentLock); - moveNewObjectsLH(lock); - } - - Variant::Map inMap; - Variant::Map::const_iterator i; - Variant::Map headers; - - MapCodec::decode(body, inMap); - QPID_LOG(trace, "RCVD GetQuery: map=" << inMap << " cid=" << cid); - - headers["method"] = "response"; - headers["qmf.opcode"] = "_query_response"; - headers["qmf.agent"] = name_address; - headers["partial"] = Variant(); - - Variant::List list_; - Variant::Map map_; - Variant::Map values; - Variant::Map oidMap; - string content; - - /* - * Unpack the _what element of the query. Currently we only support OBJECT queries. - */ - i = inMap.find("_what"); - if (i == inMap.end()) { - sendException(rte, rtk, cid, "_what element missing in Query"); - return; - } - - if (i->second.getType() != qpid::types::VAR_STRING) { - sendException(rte, rtk, cid, "_what element is not a string"); - return; - } - - if (i->second.asString() == "OBJECT") { - headers["qmf.content"] = "_data"; - /* - * Unpack the _object_id element of the query if it is present. If it is present, find that one - * object and return it. If it is not present, send a class-based result. - */ - i = inMap.find("_object_id"); - if (i != inMap.end() && i->second.getType() == qpid::types::VAR_MAP) { - ObjectId objId(i->second.asMap()); - boost::shared_ptr<ManagementObject> object; - - { - sys::Mutex::ScopedLock lock(agentLock); - ObjectMap::iterator iter = managementObjects.find(objId); - if (iter != managementObjects.end()) - object = iter->second; - } - - if (object.get() != 0) { - if (object->getConfigChanged() || object->getInstChanged()) - object->setUpdateTime(); - - object->mapEncodeValues(values, true, true); // write both stats and properties - objId.mapEncode(oidMap); - map_["_values"] = values; - map_["_object_id"] = oidMap; - object->writeTimestamps(map_); - map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(), - object->getClassName(), - object->getMd5Sum()); - list_.push_back(map_); - headers.erase("partial"); - - ListCodec::encode(list_, content); - connThreadBody.sendBuffer(content, cid, headers, rte, rtk, "amqp/list"); - QPID_LOG(trace, "SENT QueryResponse (query by object_id) to=" << rte << "/" << rtk); - return; - } - } else { // match using schema_id, if supplied - - string className; - string packageName; - - i = inMap.find("_schema_id"); - if (i != inMap.end() && i->second.getType() == qpid::types::VAR_MAP) { - const Variant::Map& schemaIdMap(i->second.asMap()); - - Variant::Map::const_iterator s_iter = schemaIdMap.find("_class_name"); - if (s_iter != schemaIdMap.end() && s_iter->second.getType() == qpid::types::VAR_STRING) - className = s_iter->second.asString(); - - s_iter = schemaIdMap.find("_package_name"); - if (s_iter != schemaIdMap.end() && s_iter->second.getType() == qpid::types::VAR_STRING) - packageName = s_iter->second.asString(); - - typedef list<boost::shared_ptr<ManagementObject> > StageList; - StageList staging; - - { - sys::Mutex::ScopedLock lock(agentLock); - for (ObjectMap::iterator iter = managementObjects.begin(); - iter != managementObjects.end(); - iter++) { - ManagementObject* object = iter->second.get(); - if (object->getClassName() == className && - (packageName.empty() || object->getPackageName() == packageName)) - staging.push_back(iter->second); - } - } - - unsigned int objCount = 0; - for (StageList::iterator iter = staging.begin(); iter != staging.end(); iter++) { - ManagementObject* object = iter->get(); - if (object->getClassName() == className && - (packageName.empty() || object->getPackageName() == packageName)) { - - values.clear(); - oidMap.clear(); - map_.clear(); - - if (object->getConfigChanged() || object->getInstChanged()) - object->setUpdateTime(); - - object->mapEncodeValues(values, true, true); // write both stats and properties - object->getObjectId().mapEncode(oidMap); - map_["_values"] = values; - map_["_object_id"] = oidMap; - object->writeTimestamps(map_); - map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(), - object->getClassName(), - object->getMd5Sum()); - list_.push_back(map_); - - if (++objCount >= maxV2ReplyObjs) { - objCount = 0; - ListCodec::encode(list_, content); - connThreadBody.sendBuffer(content, cid, headers, rte, rtk, "amqp/list"); - QPID_LOG(trace, "SENT QueryResponse (query by schema_id) to=" << rte << "/" << rtk); - content.clear(); - list_.clear(); - } - } - } - } - } - - // Send last "non-partial" message to indicate CommandComplete - headers.erase("partial"); - ListCodec::encode(list_, content); - connThreadBody.sendBuffer(content, cid, headers, rte, rtk, "amqp/list"); - QPID_LOG(trace, "SENT QueryResponse (last message, no 'partial' indicator) to=" << rte << "/" << rtk); - - } else if (i->second.asString() == "SCHEMA_ID") { - headers["qmf.content"] = "_schema_id"; - /** - * @todo - support for a predicate. For now, send a list of all known schema class keys. - */ - for (PackageMap::iterator pIter = packages.begin(); - pIter != packages.end(); pIter++) { - for (ClassMap::iterator cIter = pIter->second.begin(); - cIter != pIter->second.end(); cIter++) { - - list_.push_back(mapEncodeSchemaId( pIter->first, - cIter->first.name, - cIter->first.hash, - cIter->second.kind )); - } - } - - headers.erase("partial"); - ListCodec::encode(list_, content); - connThreadBody.sendBuffer(content, cid, headers, rte, rtk, "amqp/list"); - QPID_LOG(trace, "SENT QueryResponse (SchemaId) to=" << rte << "/" << rtk); - - } else { - // Unknown query target - sendException(rte, rtk, cid, "Query for _what => '" + i->second.asString() + "' not supported"); - } -} - -void ManagementAgentImpl::handleLocateRequest(const string&, const string& cid, const string& rte, const string& rtk) -{ - QPID_LOG(trace, "RCVD AgentLocateRequest"); - - Variant::Map map; - Variant::Map headers; - string content; - - headers["method"] = "indication"; - headers["qmf.opcode"] = "_agent_locate_response"; - headers["qmf.agent"] = name_address; - - getHeartbeatContent(map); - MapCodec::encode(map, content); - connThreadBody.sendBuffer(content, cid, headers, rte, rtk); - - QPID_LOG(trace, "SENT AgentLocateResponse replyTo=" << rte << "/" << rtk); - - { - sys::Mutex::ScopedLock lock(agentLock); - publishAllData = true; - } -} - -void ManagementAgentImpl::handleMethodRequest(const string& body, const string& cid, const string& rte, const string& rtk, const string& userId) -{ - if (extThread) { - sys::Mutex::ScopedLock lock(agentLock); - - methodQueue.push_back(new QueuedMethod(cid, rte, rtk, body, userId)); - if (pipeHandle != 0) { - pipeHandle->write("X", 1); - } else if (notifyable != 0) { - inCallback = true; - { - sys::Mutex::ScopedUnlock unlock(agentLock); - notifyable->notify(); - } - inCallback = false; - } else if (notifyCallback != 0) { - inCallback = true; - { - sys::Mutex::ScopedUnlock unlock(agentLock); - notifyCallback(notifyContext); - } - inCallback = false; - } - } else { - invokeMethodRequest(body, cid, rte, rtk, userId); - } - - QPID_LOG(trace, "RCVD MethodRequest"); -} - -void ManagementAgentImpl::received(Message& msg) -{ - string replyToExchange; - string replyToKey; - framing::MessageProperties mp = msg.getMessageProperties(); - if (mp.hasReplyTo()) { - const framing::ReplyTo& rt = mp.getReplyTo(); - replyToExchange = rt.getExchange(); - replyToKey = rt.getRoutingKey(); - } - - string userId; - if (mp.hasUserId()) - userId = mp.getUserId(); - - if (mp.hasAppId() && mp.getAppId() == "qmf2") - { - string opcode = mp.getApplicationHeaders().getAsString("qmf.opcode"); - string cid = msg.getMessageProperties().getCorrelationId(); - - if (opcode == "_agent_locate_request") handleLocateRequest(msg.getData(), cid, replyToExchange, replyToKey); - else if (opcode == "_method_request") handleMethodRequest(msg.getData(), cid, replyToExchange, replyToKey, userId); - else if (opcode == "_query_request") handleGetQuery(msg.getData(), cid, replyToExchange, replyToKey); - else { - QPID_LOG(warning, "Support for QMF V2 Opcode [" << opcode << "] TBD!!!"); - } - return; - } - - // old preV2 binary messages - - uint32_t sequence; - string data = msg.getData(); - Buffer inBuffer(const_cast<char*>(data.c_str()), data.size()); - uint8_t opcode; - - - if (checkHeader(inBuffer, &opcode, &sequence)) - { - if (opcode == 'S') handleSchemaRequest(inBuffer, sequence, replyToExchange, replyToKey); - else if (opcode == 'x') handleConsoleAddedIndication(); - else - QPID_LOG(warning, "Ignoring old-format QMF Request! opcode=" << char(opcode)); - } -} - - -void ManagementAgentImpl::encodeHeader(Buffer& buf, uint8_t opcode, uint32_t seq) -{ - buf.putOctet('A'); - buf.putOctet('M'); - buf.putOctet('2'); - buf.putOctet(opcode); - buf.putLong (seq); -} - -Variant::Map ManagementAgentImpl::mapEncodeSchemaId(const string& pname, - const string& cname, - const uint8_t *md5Sum, - uint8_t type) -{ - Variant::Map map_; - - map_["_package_name"] = pname; - map_["_class_name"] = cname; - map_["_hash"] = types::Uuid(md5Sum); - if (type == ManagementItem::CLASS_KIND_EVENT) - map_["_type"] = "_event"; - else - map_["_type"] = "_data"; - - return map_; -} - - -bool ManagementAgentImpl::checkHeader(Buffer& buf, uint8_t *opcode, uint32_t *seq) -{ - if (buf.getSize() < 8) - return false; - - uint8_t h1 = buf.getOctet(); - uint8_t h2 = buf.getOctet(); - uint8_t h3 = buf.getOctet(); - - *opcode = buf.getOctet(); - *seq = buf.getLong(); - - return h1 == 'A' && h2 == 'M' && h3 == '2'; -} - -ManagementAgentImpl::PackageMap::iterator ManagementAgentImpl::findOrAddPackage(const string& name) -{ - PackageMap::iterator pIter = packages.find(name); - if (pIter != packages.end()) - return pIter; - - // No such package found, create a new map entry. - pair<PackageMap::iterator, bool> result = - packages.insert(pair<string, ClassMap>(name, ClassMap())); - - return result.first; -} - -// note well: caller must hold agentLock when calling this! -void ManagementAgentImpl::moveNewObjectsLH(const sys::Mutex::ScopedLock& /*agentLock*/) -{ - sys::Mutex::ScopedLock lock(addLock); - ObjectMap::iterator newObj = newManagementObjects.begin(); - while (newObj != newManagementObjects.end()) { - // before adding a new mgmt object, check for duplicates: - ObjectMap::iterator oldObj = managementObjects.find(newObj->first); - if (oldObj == managementObjects.end()) { - managementObjects[newObj->first] = newObj->second; - newManagementObjects.erase(newObj++); // post inc iterator safe! - } else { - // object exists with same object id. This may be legit, for example, when a - // recently deleted object is re-added before the mgmt poll runs. - if (newObj->second->isDeleted()) { - // @TODO fixme: we missed an add-delete for the new object - QPID_LOG(warning, "Mgmt Object deleted before update sent, oid=" << newObj->first); - newManagementObjects.erase(newObj++); // post inc iterator safe! - } else if (oldObj->second->isDeleted()) { - // skip adding newObj, try again later once oldObj has been cleaned up by poll - ++newObj; - } else { - // real bad - two objects exist with same OID. This is a bug in the application - QPID_LOG(error, "Detected two Mgmt Objects using the same object id! oid=" << newObj->first - << ", this is bad!"); - // what to do here? Can't erase an active obj - owner has a pointer to it. - // for now I punt. Maybe the flood of log messages will get someone's attention :P - ++newObj; - } - } - } -} - -void ManagementAgentImpl::addClassLocal(uint8_t classKind, - PackageMap::iterator pIter, - const string& className, - uint8_t* md5Sum, - ManagementObject::writeSchemaCall_t schemaCall) -{ - SchemaClassKey key; - ClassMap& cMap = pIter->second; - - key.name = className; - memcpy(&key.hash, md5Sum, 16); - - ClassMap::iterator cIter = cMap.find(key); - if (cIter != cMap.end()) - return; - - // No such class found, create a new class with local information. - cMap.insert(pair<SchemaClassKey, SchemaClass>(key, SchemaClass(schemaCall, classKind))); - schemaTimestamp = Duration(EPOCH, now()); - QPID_LOG(trace, "Updated schema timestamp, now=" << uint64_t(schemaTimestamp)); -} - -void ManagementAgentImpl::encodePackageIndication(Buffer& buf, - PackageMap::iterator pIter) -{ - buf.putShortString((*pIter).first); - - QPID_LOG(trace, "SENT PackageInd: package=" << (*pIter).first); -} - -void ManagementAgentImpl::encodeClassIndication(Buffer& buf, - PackageMap::iterator pIter, - ClassMap::iterator cIter) -{ - SchemaClassKey key = (*cIter).first; - - buf.putOctet((*cIter).second.kind); - buf.putShortString((*pIter).first); - buf.putShortString(key.name); - buf.putBin128(key.hash); - - QPID_LOG(trace, "SENT ClassInd: package=" << (*pIter).first << " class=" << key.name); -} - -struct MessageItem { - string content; - Variant::Map headers; - string key; - MessageItem(const Variant::Map& h, const string& k) : headers(h), key(k) {} -}; - -void ManagementAgentImpl::periodicProcessing() -{ - string addr_key_base = "agent.ind.data."; - list<ObjectId> deleteList; - list<boost::shared_ptr<MessageItem> > message_list; - - sendHeartbeat(); - - { - sys::Mutex::ScopedLock lock(agentLock); - - if (!connected) - return; - - moveNewObjectsLH(lock); - - // - // Clear the been-here flag on all objects in the map. - // - for (ObjectMap::iterator iter = managementObjects.begin(); - iter != managementObjects.end(); - iter++) { - ManagementObject* object = iter->second.get(); - object->setFlags(0); - if (publishAllData) { - object->setForcePublish(true); - } - } - - publishAllData = false; - - // - // Process the entire object map. - // - uint32_t v2Objs = 0; - - for (ObjectMap::iterator baseIter = managementObjects.begin(); - baseIter != managementObjects.end(); - baseIter++) { - ManagementObject* baseObject = baseIter->second.get(); - - // - // Skip until we find a base object requiring a sent message. - // - if (baseObject->getFlags() == 1 || - (!baseObject->getConfigChanged() && - !baseObject->getInstChanged() && - !baseObject->getForcePublish() && - !baseObject->isDeleted())) - continue; - - std::string packageName = baseObject->getPackageName(); - std::string className = baseObject->getClassName(); - - Variant::List list_; - std::stringstream addr_key; - Variant::Map headers; - - addr_key << addr_key_base; - addr_key << keyifyNameStr(packageName) - << "." << keyifyNameStr(className) - << "." << vendorNameKey - << "." << productNameKey - << "." << instanceNameKey; - - headers["method"] = "indication"; - headers["qmf.opcode"] = "_data_indication"; - headers["qmf.content"] = "_data"; - headers["qmf.agent"] = name_address; - - for (ObjectMap::iterator iter = baseIter; - iter != managementObjects.end(); - iter++) { - ManagementObject* object = iter->second.get(); - bool send_stats, send_props; - if (baseObject->isSameClass(*object) && object->getFlags() == 0) { - object->setFlags(1); - if (object->getConfigChanged() || object->getInstChanged()) - object->setUpdateTime(); - - send_props = (object->getConfigChanged() || object->getForcePublish() || object->isDeleted()); - send_stats = (object->hasInst() && (object->getInstChanged() || object->getForcePublish())); - - if (send_stats || send_props) { - Variant::Map map_; - Variant::Map values; - Variant::Map oid; - - object->getObjectId().mapEncode(oid); - map_["_object_id"] = oid; - map_["_schema_id"] = mapEncodeSchemaId(object->getPackageName(), - object->getClassName(), - object->getMd5Sum()); - object->writeTimestamps(map_); - object->mapEncodeValues(values, send_props, send_stats); - map_["_values"] = values; - list_.push_back(map_); - - if (++v2Objs >= maxV2ReplyObjs) { - v2Objs = 0; - boost::shared_ptr<MessageItem> item(new MessageItem(headers, addr_key.str())); - ListCodec::encode(list_, item->content); - message_list.push_back(item); - list_.clear(); - } - } - - if (object->isDeleted()) - deleteList.push_back(iter->first); - object->setForcePublish(false); - } - } - - if (!list_.empty()) { - boost::shared_ptr<MessageItem> item(new MessageItem(headers, addr_key.str())); - ListCodec::encode(list_, item->content); - message_list.push_back(item); - } - } - - // Delete flagged objects - for (list<ObjectId>::reverse_iterator iter = deleteList.rbegin(); - iter != deleteList.rend(); - iter++) - managementObjects.erase(*iter); - } - - while (!message_list.empty()) { - boost::shared_ptr<MessageItem> item(message_list.front()); - message_list.pop_front(); - connThreadBody.sendBuffer(item->content, "", item->headers, topicExchange, item->key, "amqp/list"); - QPID_LOG(trace, "SENT DataIndication"); - } -} - - -void ManagementAgentImpl::getHeartbeatContent(qpid::types::Variant::Map& map) -{ - map["_values"] = attrMap; - map["_values"].asMap()["_timestamp"] = uint64_t(Duration(EPOCH, now())); - map["_values"].asMap()["_heartbeat_interval"] = interval; - map["_values"].asMap()["_epoch"] = bootSequence; - map["_values"].asMap()["_schema_updated"] = uint64_t(schemaTimestamp); -} - -void ManagementAgentImpl::ConnectionThread::run() -{ - static const int delayMin(1); - static const int delayMax(128); - static const int delayFactor(2); - int delay(delayMin); - string dest("qmfagent"); - ConnectionThread::shared_ptr tmp; - - sessionId.generate(); - queueName << "qmfagent-" << sessionId; - - while (true) { - try { - if (agent.initialized) { - QPID_LOG(debug, "QMF Agent attempting to connect to the broker..."); - connection.open(agent.connectionSettings); - session = connection.newSession(queueName.str()); - subscriptions.reset(new client::SubscriptionManager(session)); - - session.queueDeclare(arg::queue=queueName.str(), arg::autoDelete=true, - arg::exclusive=true); - session.exchangeBind(arg::exchange="amq.direct", arg::queue=queueName.str(), - arg::bindingKey=queueName.str()); - session.exchangeBind(arg::exchange=agent.directExchange, arg::queue=queueName.str(), - arg::bindingKey=agent.name_address); - session.exchangeBind(arg::exchange=agent.topicExchange, arg::queue=queueName.str(), - arg::bindingKey="console.#"); - - subscriptions->subscribe(agent, queueName.str(), dest); - QPID_LOG(info, "Connection established with broker"); - { - sys::Mutex::ScopedLock _lock(connLock); - if (shutdown) - return; - operational = true; - agent.connected = true; - agent.startProtocol(); - try { - sys::Mutex::ScopedUnlock _unlock(connLock); - subscriptions->run(); - } catch (exception) {} - - QPID_LOG(warning, "Connection to the broker has been lost"); - - operational = false; - agent.connected = false; - tmp = subscriptions; - subscriptions.reset(); - } - tmp.reset(); // frees the subscription outside the lock - delay = delayMin; - connection.close(); - } - } catch (exception &e) { - if (delay < delayMax) - delay *= delayFactor; - QPID_LOG(debug, "Connection failed: exception=" << e.what()); - } - - { - // sleep for "delay" seconds, but peridically check if the - // agent is shutting down so we don't hang for up to delayMax - // seconds during agent shutdown - sys::Mutex::ScopedLock _lock(connLock); - if (shutdown) - return; - sleeping = true; - int totalSleep = 0; - do { - sys::Mutex::ScopedUnlock _unlock(connLock); - qpid::sys::sleep(delayMin); - totalSleep += delayMin; - } while (totalSleep < delay && !shutdown); - sleeping = false; - if (shutdown) - return; - } - } -} - -ManagementAgentImpl::ConnectionThread::~ConnectionThread() -{ -} - -void ManagementAgentImpl::ConnectionThread::sendBuffer(Buffer& buf, - uint32_t length, - const string& exchange, - const string& routingKey) -{ - Message msg; - string data; - - buf.getRawData(data, length); - msg.setData(data); - sendMessage(msg, exchange, routingKey); -} - - - -void ManagementAgentImpl::ConnectionThread::sendBuffer(const string& data, - const string& cid, - const Variant::Map headers, - const string& exchange, - const string& routingKey, - const string& contentType, - uint64_t ttl_msec) -{ - Message msg; - Variant::Map::const_iterator i; - - if (!cid.empty()) - msg.getMessageProperties().setCorrelationId(cid); - - if (!contentType.empty()) - msg.getMessageProperties().setContentType(contentType); - - if (ttl_msec) - msg.getDeliveryProperties().setTtl(ttl_msec); - - for (i = headers.begin(); i != headers.end(); ++i) { - msg.getHeaders().setString(i->first, i->second.asString()); - } - - msg.setData(data); - sendMessage(msg, exchange, routingKey); -} - - - - - -void ManagementAgentImpl::ConnectionThread::sendMessage(Message msg, - const string& exchange, - const string& routingKey) -{ - ConnectionThread::shared_ptr s; - { - sys::Mutex::ScopedLock _lock(connLock); - if (!operational) - return; - s = subscriptions; - } - - msg.getDeliveryProperties().setRoutingKey(routingKey); - msg.getMessageProperties().setReplyTo(ReplyTo("amq.direct", queueName.str())); - msg.getMessageProperties().getApplicationHeaders().setString("qmf.agent", agent.name_address); - msg.getMessageProperties().setAppId("qmf2"); - try { - session.messageTransfer(arg::content=msg, arg::destination=exchange); - } catch(exception& e) { - QPID_LOG(error, "Exception caught in sendMessage: " << e.what()); - // Bounce the connection - if (s) - s->stop(); - } -} - - - -void ManagementAgentImpl::ConnectionThread::bindToBank(uint32_t brokerBank, uint32_t agentBank) -{ - stringstream key; - key << "agent." << brokerBank << "." << agentBank; - session.exchangeBind(arg::exchange="qpid.management", arg::queue=queueName.str(), - arg::bindingKey=key.str()); -} - -void ManagementAgentImpl::ConnectionThread::close() -{ - ConnectionThread::shared_ptr s; - { - sys::Mutex::ScopedLock _lock(connLock); - shutdown = true; - s = subscriptions; - } - if (s) - s->stop(); -} - -bool ManagementAgentImpl::ConnectionThread::isSleeping() const -{ - sys::Mutex::ScopedLock _lock(connLock); - return sleeping; -} - - -void ManagementAgentImpl::PublishThread::run() -{ - uint16_t totalSleep; - uint16_t sleepTime; - - while (!shutdown) { - agent.periodicProcessing(); - totalSleep = 0; - - // - // Calculate a sleep time that is no greater than 5 seconds and - // no less than 1 second. - // - sleepTime = agent.getInterval(); - if (sleepTime > 5) - sleepTime = 5; - else if (sleepTime == 0) - sleepTime = 1; - - while (totalSleep < agent.getInterval() && !shutdown) { - qpid::sys::sleep(sleepTime); - totalSleep += sleepTime; - } - } -} - -}} - diff --git a/cpp/src/qpid/agent/ManagementAgentImpl.h b/cpp/src/qpid/agent/ManagementAgentImpl.h deleted file mode 100644 index 4c97bc89da..0000000000 --- a/cpp/src/qpid/agent/ManagementAgentImpl.h +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef _qpid_agent_ManagementAgentImpl_ -#define _qpid_agent_ManagementAgentImpl_ - -// -// 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 "qpid/agent/ManagementAgent.h" -#include "qpid/client/Connection.h" -#include "qpid/client/ConnectionSettings.h" -#include "qpid/client/SubscriptionManager.h" -#include "qpid/client/Session.h" -#include "qpid/client/AsyncSession.h" -#include "qpid/client/Message.h" -#include "qpid/client/MessageListener.h" -#include "qpid/sys/Thread.h" -#include "qpid/sys/Runnable.h" -#include "qpid/sys/Mutex.h" -#include "qpid/sys/PipeHandle.h" -#include "qpid/sys/Time.h" -#include "qpid/framing/Uuid.h" -#include <iostream> -#include <sstream> -#include <deque> - -namespace qpid { -namespace management { - -class ManagementAgentImpl : public ManagementAgent, public client::MessageListener -{ - public: - - ManagementAgentImpl(); - virtual ~ManagementAgentImpl(); - - // - // Methods from ManagementAgent - // - int getMaxThreads() { return 1; } - void setName(const std::string& vendor, - const std::string& product, - const std::string& instance=""); - void getName(std::string& vendor, std::string& product, std::string& instance); - const std::string& getAddress(); - void init(const std::string& brokerHost = "localhost", - uint16_t brokerPort = 5672, - uint16_t intervalSeconds = 10, - bool useExternalThread = false, - const std::string& storeFile = "", - const std::string& uid = "", - const std::string& pwd = "", - const std::string& mech = "PLAIN", - const std::string& proto = "tcp"); - void init(const management::ConnectionSettings& settings, - uint16_t intervalSeconds = 10, - bool useExternalThread = false, - const std::string& storeFile = ""); - bool isConnected() { return connected; } - std::string& getLastFailure() { return lastFailure; } - void registerClass(const std::string& packageName, - const std::string& className, - uint8_t* md5Sum, - management::ManagementObject::writeSchemaCall_t schemaCall); - void registerEvent(const std::string& packageName, - const std::string& eventName, - uint8_t* md5Sum, - management::ManagementObject::writeSchemaCall_t schemaCall); - ObjectId addObject(management::ManagementObject* objectPtr, uint64_t persistId = 0); - ObjectId addObject(management::ManagementObject* objectPtr, const std::string& key, - bool persistent); - void raiseEvent(const management::ManagementEvent& event, severity_t severity = SEV_DEFAULT); - uint32_t pollCallbacks(uint32_t callLimit = 0); - int getSignalFd(); - void setSignalCallback(cb_t callback, void* context); - void setSignalCallback(Notifyable& n); - - uint16_t getInterval() { return interval; } - void periodicProcessing(); - - uint16_t getBootSequence(void) { return bootSequence; } - void setBootSequence(uint16_t b) { bootSequence = b; } - - private: - - struct SchemaClassKey { - std::string name; - uint8_t hash[16]; - }; - - struct SchemaClassKeyComp { - bool operator() (const SchemaClassKey& lhs, const SchemaClassKey& rhs) const - { - if (lhs.name != rhs.name) - return lhs.name < rhs.name; - else - for (int i = 0; i < 16; i++) - if (lhs.hash[i] != rhs.hash[i]) - return lhs.hash[i] < rhs.hash[i]; - return false; - } - }; - - struct SchemaClass { - management::ManagementObject::writeSchemaCall_t writeSchemaCall; - uint8_t kind; - - SchemaClass(const management::ManagementObject::writeSchemaCall_t call, - const uint8_t _kind) : writeSchemaCall(call), kind(_kind) {} - }; - - struct QueuedMethod { - QueuedMethod(const std::string& _cid, const std::string& _rte, const std::string& _rtk, const std::string& _body, const std::string& _uid) : - cid(_cid), replyToExchange(_rte), replyToKey(_rtk), body(_body), userId(_uid) {} - - std::string cid; - std::string replyToExchange; - std::string replyToKey; - std::string body; - std::string userId; - }; - - typedef std::deque<QueuedMethod*> MethodQueue; - typedef std::map<SchemaClassKey, SchemaClass, SchemaClassKeyComp> ClassMap; - typedef std::map<std::string, ClassMap> PackageMap; - - PackageMap packages; - AgentAttachment attachment; - - typedef std::map<ObjectId, boost::shared_ptr<ManagementObject> > ObjectMap; - - ObjectMap managementObjects; - ObjectMap newManagementObjects; - MethodQueue methodQueue; - - void received (client::Message& msg); - - qpid::types::Variant::Map attrMap; - std::string name_address; - std::string vendorNameKey; // vendor name with "." --> "_" - std::string productNameKey; // product name with "." --> "_" - std::string instanceNameKey; // agent instance with "." --> "_" - uint16_t interval; - bool extThread; - sys::PipeHandle* pipeHandle; - uint64_t nextObjectId; - cb_t notifyCallback; - void* notifyContext; - Notifyable* notifyable; - bool inCallback; - std::string storeFile; - sys::Mutex agentLock; - sys::Mutex addLock; - framing::Uuid systemId; - client::ConnectionSettings connectionSettings; - bool initialized; - bool connected; - bool useMapMsg; - std::string lastFailure; - std::string topicExchange; - std::string directExchange; - qpid::sys::Duration schemaTimestamp; - - bool publishAllData; - uint32_t requestedBrokerBank; - uint32_t requestedAgentBank; - uint32_t assignedBrokerBank; - uint32_t assignedAgentBank; - uint16_t bootSequence; - - // Maximum # of objects allowed in a single V2 response - // message. - uint32_t maxV2ReplyObjs; - - static const uint8_t DEBUG_OFF = 0; - static const uint8_t DEBUG_CONN = 1; - static const uint8_t DEBUG_PROTO = 2; - static const uint8_t DEBUG_PUBLISH = 3; - -# define MA_BUFFER_SIZE 65536 - char outputBuffer[MA_BUFFER_SIZE]; - char eventBuffer[MA_BUFFER_SIZE]; - - friend class ConnectionThread; - class ConnectionThread : public sys::Runnable - { - typedef boost::shared_ptr<client::SubscriptionManager> shared_ptr; - - bool operational; - ManagementAgentImpl& agent; - framing::Uuid sessionId; - client::Connection connection; - client::Session session; - ConnectionThread::shared_ptr subscriptions; - std::stringstream queueName; - mutable sys::Mutex connLock; - bool shutdown; - bool sleeping; - void run(); - public: - ConnectionThread(ManagementAgentImpl& _agent) : - operational(false), agent(_agent), - shutdown(false), sleeping(false) {} - ~ConnectionThread(); - void sendBuffer(qpid::framing::Buffer& buf, - uint32_t length, - const std::string& exchange, - const std::string& routingKey); - void sendBuffer(const std::string& data, - const std::string& cid, - const qpid::types::Variant::Map headers, - const std::string& exchange, - const std::string& routingKey, - const std::string& contentType="amqp/map", - uint64_t ttl_msec=0); - void sendMessage(qpid::client::Message msg, - const std::string& exchange, - const std::string& routingKey); - void bindToBank(uint32_t brokerBank, uint32_t agentBank); - void close(); - bool isSleeping() const; - }; - - class PublishThread : public sys::Runnable - { - ManagementAgentImpl& agent; - void run(); - bool shutdown; - public: - PublishThread(ManagementAgentImpl& _agent) : - agent(_agent), shutdown(false) {} - void close() { shutdown = true; } - }; - - ConnectionThread connThreadBody; - sys::Thread connThread; - PublishThread pubThreadBody; - sys::Thread pubThread; - - static const std::string storeMagicNumber; - - void startProtocol(); - void storeData(bool requested=false); - void retrieveData(std::string& vendor, std::string& product, std::string& inst); - PackageMap::iterator findOrAddPackage(const std::string& name); - void moveNewObjectsLH(const sys::Mutex::ScopedLock& agentLock); - void addClassLocal (uint8_t classKind, - PackageMap::iterator pIter, - const std::string& className, - uint8_t* md5Sum, - management::ManagementObject::writeSchemaCall_t schemaCall); - void encodePackageIndication (framing::Buffer& buf, - PackageMap::iterator pIter); - void encodeClassIndication (framing::Buffer& buf, - PackageMap::iterator pIter, - ClassMap::iterator cIter); - void encodeHeader (framing::Buffer& buf, uint8_t opcode, uint32_t seq = 0); - qpid::types::Variant::Map mapEncodeSchemaId(const std::string& pname, - const std::string& cname, - const uint8_t *md5Sum, - uint8_t type=ManagementItem::CLASS_KIND_TABLE); - bool checkHeader (framing::Buffer& buf, uint8_t *opcode, uint32_t *seq); - void sendHeartbeat(); - void sendException(const std::string& replyToExchange, const std::string& replyToKey, const std::string& cid, - const std::string& text, uint32_t code=1); - void handlePackageRequest (qpid::framing::Buffer& inBuffer); - void handleClassQuery (qpid::framing::Buffer& inBuffer); - void handleSchemaRequest (qpid::framing::Buffer& inBuffer, uint32_t sequence, const std::string& rte, const std::string& rtk); - void invokeMethodRequest (const std::string& body, const std::string& cid, const std::string& rte, const std::string& rtk, const std::string& userId); - - void handleGetQuery (const std::string& body, const std::string& cid, const std::string& rte, const std::string& rtk); - void handleLocateRequest (const std::string& body, const std::string& sequence, const std::string& rte, const std::string& rtk); - void handleMethodRequest (const std::string& body, const std::string& sequence, const std::string& rte, const std::string& rtk, const std::string& userId); - void handleConsoleAddedIndication(); - void getHeartbeatContent (qpid::types::Variant::Map& map); -}; - -}} - -#endif /*!_qpid_agent_ManagementAgentImpl_*/ diff --git a/cpp/src/tests/testagent.cpp b/cpp/src/tests/testagent.cpp deleted file mode 100644 index e6010a8e00..0000000000 --- a/cpp/src/tests/testagent.cpp +++ /dev/null @@ -1,208 +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 <qpid/management/Manageable.h> -#include <qpid/management/ManagementObject.h> -#include <qpid/agent/ManagementAgent.h> -#include <qpid/sys/Mutex.h> -#include <qpid/sys/Time.h> -#include "qmf/org/apache/qpid/agent/example/Parent.h" -#include "qmf/org/apache/qpid/agent/example/Child.h" -#include "qmf/org/apache/qpid/agent/example/ArgsParentCreate_child.h" -#include "qmf/org/apache/qpid/agent/example/EventChildCreated.h" -#include "qmf/org/apache/qpid/agent/example/Package.h" - -#include <signal.h> -#include <cstdlib> -#include <iostream> - -#include <sstream> - -namespace qpid { -namespace tests { - -static bool running = true; - -using std::string; -using qpid::management::ManagementAgent; -using qpid::management::ManagementObject; -using qpid::management::Manageable; -using qpid::management::Args; -using qpid::sys::Mutex; -namespace _qmf = qmf::org::apache::qpid::agent::example; - -class ChildClass; - -//============================================================== -// CoreClass is the operational class that corresponds to the -// "Parent" class in the management schema. -//============================================================== -class CoreClass : public Manageable -{ - string name; - ManagementAgent* agent; - _qmf::Parent* mgmtObject; - std::vector<ChildClass*> children; - Mutex vectorLock; - -public: - - CoreClass(ManagementAgent* agent, string _name); - ~CoreClass() { mgmtObject->resourceDestroy(); } - - ManagementObject* GetManagementObject(void) const - { return mgmtObject; } - - void doLoop(); - status_t ManagementMethod (uint32_t methodId, Args& args, string& text); -}; - -class ChildClass : public Manageable -{ - string name; - _qmf::Child* mgmtObject; - -public: - - ChildClass(ManagementAgent* agent, CoreClass* parent, string name); - ~ChildClass() { mgmtObject->resourceDestroy(); } - - ManagementObject* GetManagementObject(void) const - { return mgmtObject; } - - void doWork() - { - mgmtObject->inc_count(2); - } -}; - -CoreClass::CoreClass(ManagementAgent* _agent, string _name) : name(_name), agent(_agent) -{ - static uint64_t persistId = 0x111222333444555LL; - mgmtObject = new _qmf::Parent(agent, this, name); - - agent->addObject(mgmtObject, persistId++); - mgmtObject->set_state("IDLE"); -} - -void CoreClass::doLoop() -{ - // Periodically bump a counter to provide a changing statistical value - while (running) { - qpid::sys::sleep(1); - mgmtObject->inc_count(); - mgmtObject->set_state("IN_LOOP"); - - { - Mutex::ScopedLock _lock(vectorLock); - - for (std::vector<ChildClass*>::iterator iter = children.begin(); - iter != children.end(); - iter++) { - (*iter)->doWork(); - } - } - } -} - -Manageable::status_t CoreClass::ManagementMethod(uint32_t methodId, Args& args, string& /*text*/) -{ - Mutex::ScopedLock _lock(vectorLock); - - switch (methodId) { - case _qmf::Parent::METHOD_CREATE_CHILD: - _qmf::ArgsParentCreate_child& ioArgs = (_qmf::ArgsParentCreate_child&) args; - - ChildClass *child = new ChildClass(agent, this, ioArgs.i_name); - ioArgs.o_childRef = child->GetManagementObject()->getObjectId(); - - children.push_back(child); - - agent->raiseEvent(_qmf::EventChildCreated(ioArgs.i_name)); - - return STATUS_OK; - } - - return STATUS_NOT_IMPLEMENTED; -} - -ChildClass::ChildClass(ManagementAgent* agent, CoreClass* parent, string name) -{ - mgmtObject = new _qmf::Child(agent, this, parent, name); - - agent->addObject(mgmtObject); -} - - -//============================================================== -// Main program -//============================================================== - -ManagementAgent::Singleton* singleton; - -void shutdown(int) -{ - running = false; -} - -int main_int(int argc, char** argv) -{ - singleton = new ManagementAgent::Singleton(); - const char* host = argc>1 ? argv[1] : "127.0.0.1"; - int port = argc>2 ? atoi(argv[2]) : 5672; - - signal(SIGINT, shutdown); - - // Create the qmf management agent - ManagementAgent* agent = singleton->getInstance(); - - // Register the Qmf_example schema with the agent - _qmf::Package packageInit(agent); - - // Start the agent. It will attempt to make a connection to the - // management broker - agent->init(host, port, 5, false, ".magentdata"); - - // Allocate some core objects - CoreClass core1(agent, "Example Core Object #1"); - CoreClass core2(agent, "Example Core Object #2"); - CoreClass core3(agent, "Example Core Object #3"); - - core1.doLoop(); - - // done, cleanup and exit - delete singleton; - - return 0; -} - -}} // namespace qpid::tests - -int main(int argc, char** argv) -{ - try { - return qpid::tests::main_int(argc, argv); - } catch(std::exception& e) { - std::cerr << "Top Level Exception: " << e.what() << std::endl; - return 1; - } -} - diff --git a/cpp/src/tests/testagent.xml b/cpp/src/tests/testagent.xml deleted file mode 100644 index 0b1436f999..0000000000 --- a/cpp/src/tests/testagent.xml +++ /dev/null @@ -1,64 +0,0 @@ -<schema package="org.apache.qpid.agent.example"> - -<!-- - 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. ---> - - <!-- - =============================================================== - Parent - =============================================================== - --> - <class name="Parent"> - - This class represents a parent object - - <property name="name" type="lstr" access="RC" index="y"/> - - <statistic name="state" type="sstr" desc="Operational state of the link"/> - <statistic name="count" type="count64" unit="tick" desc="Counter that increases monotonically"/> - - <method name="create_child" desc="Create child object"> - <arg name="name" dir="I" type="lstr"/> - <arg name="childRef" dir="O" type="objId"/> - </method> - </class> - - - <!-- - =============================================================== - Child - =============================================================== - --> - <class name="Child"> - <property name="ParentRef" type="objId" references="Parent" access="RC" index="y" parentRef="y"/> - <property name="name" type="lstr" access="RC" index="y"/> - - <statistic name="count" type="count64" unit="tick" desc="Counter that increases monotonically"/> - - <method name="delete"/> - </class> - - <eventArguments> - <arg name="childName" type="lstr"/> - </eventArguments> - - <event name="ChildCreated" args="childName"/> - <event name="ChildDestroyed" args="childName"/> -</schema> - |