summaryrefslogtreecommitdiff
path: root/extras
diff options
context:
space:
mode:
authorTed Ross <tross@apache.org>2013-10-24 18:01:00 +0000
committerTed Ross <tross@apache.org>2013-10-24 18:01:00 +0000
commita1d53aa6923cba3d92ae3d7d2ff2ab33eafc3279 (patch)
tree0dd1f54d9869db5d005f11b5288ebc745dfb5895 /extras
parentae2fa917369c8b0896c891425df0db31fe8eeaeb (diff)
downloadqpid-python-a1d53aa6923cba3d92ae3d7d2ff2ab33eafc3279.tar.gz
QPID-5257 - Removed dispatch code from its old location
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1535460 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'extras')
-rw-r--r--extras/dispatch/CMakeLists.txt189
-rw-r--r--extras/dispatch/ChangeLog26
-rw-r--r--extras/dispatch/LICENSE201
-rw-r--r--extras/dispatch/README.md30
-rw-r--r--extras/dispatch/TODO54
-rw-r--r--extras/dispatch/config.sh27
-rw-r--r--extras/dispatch/etc/qpid-dispatch.conf151
-rw-r--r--extras/dispatch/include/qpid/dispatch.h44
-rw-r--r--extras/dispatch/include/qpid/dispatch/agent.h98
-rw-r--r--extras/dispatch/include/qpid/dispatch/alloc.h72
-rw-r--r--extras/dispatch/include/qpid/dispatch/amqp.h98
-rw-r--r--extras/dispatch/include/qpid/dispatch/bitmask.h37
-rw-r--r--extras/dispatch/include/qpid/dispatch/buffer.h79
-rw-r--r--extras/dispatch/include/qpid/dispatch/compose.h184
-rw-r--r--extras/dispatch/include/qpid/dispatch/config.h31
-rw-r--r--extras/dispatch/include/qpid/dispatch/container.h209
-rw-r--r--extras/dispatch/include/qpid/dispatch/ctools.h147
-rw-r--r--extras/dispatch/include/qpid/dispatch/dispatch.h52
-rw-r--r--extras/dispatch/include/qpid/dispatch/error.h29
-rw-r--r--extras/dispatch/include/qpid/dispatch/hash.h45
-rw-r--r--extras/dispatch/include/qpid/dispatch/iovec.h32
-rw-r--r--extras/dispatch/include/qpid/dispatch/iterator.h197
-rw-r--r--extras/dispatch/include/qpid/dispatch/log.h36
-rw-r--r--extras/dispatch/include/qpid/dispatch/message.h188
-rw-r--r--extras/dispatch/include/qpid/dispatch/parse.h195
-rw-r--r--extras/dispatch/include/qpid/dispatch/python_embedded.h81
-rw-r--r--extras/dispatch/include/qpid/dispatch/router.h52
-rw-r--r--extras/dispatch/include/qpid/dispatch/server.h459
-rw-r--r--extras/dispatch/include/qpid/dispatch/threading.h45
-rw-r--r--extras/dispatch/include/qpid/dispatch/timer.h89
-rw-r--r--extras/dispatch/include/qpid/dispatch/user_fd.h123
-rw-r--r--extras/dispatch/python/qpid/__init__.py0
-rw-r--r--extras/dispatch/python/qpid/dispatch/__init__.py0
-rw-r--r--extras/dispatch/python/qpid/dispatch/config/__init__.py20
-rw-r--r--extras/dispatch/python/qpid/dispatch/config/parser.py333
-rw-r--r--extras/dispatch/python/qpid/dispatch/config/schema.py85
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/__init__.py20
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/configuration.py47
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/data.py275
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/link.py144
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/mobile.py189
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/neighbor.py83
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/node.py174
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/path.py235
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/router_engine.py301
-rw-r--r--extras/dispatch/python/qpid/dispatch/router/routing.py62
-rw-r--r--extras/dispatch/python/qpid/dispatch/stubs/__init__.py22
-rw-r--r--extras/dispatch/python/qpid/dispatch/stubs/ioadapter.py27
-rw-r--r--extras/dispatch/python/qpid/dispatch/stubs/logadapter.py33
-rwxr-xr-xextras/dispatch/release.sh90
-rw-r--r--extras/dispatch/router/CMakeLists.txt38
-rw-r--r--extras/dispatch/router/src/config.h.in21
-rw-r--r--extras/dispatch/router/src/main.c145
-rw-r--r--extras/dispatch/src/agent.c525
-rw-r--r--extras/dispatch/src/alloc.c253
-rw-r--r--extras/dispatch/src/alloc_private.h28
-rw-r--r--extras/dispatch/src/amqp.c30
-rw-r--r--extras/dispatch/src/bitmask.c124
-rw-r--r--extras/dispatch/src/buffer.c83
-rw-r--r--extras/dispatch/src/compose.c454
-rw-r--r--extras/dispatch/src/compose_private.h47
-rw-r--r--extras/dispatch/src/config.c260
-rw-r--r--extras/dispatch/src/config_private.h30
-rw-r--r--extras/dispatch/src/container.c868
-rw-r--r--extras/dispatch/src/dispatch.c227
-rw-r--r--extras/dispatch/src/dispatch_private.h61
-rw-r--r--extras/dispatch/src/hash.c285
-rw-r--r--extras/dispatch/src/iovec.c81
-rw-r--r--extras/dispatch/src/iterator.c519
-rw-r--r--extras/dispatch/src/log.c116
-rw-r--r--extras/dispatch/src/log_private.h27
-rw-r--r--extras/dispatch/src/message.c879
-rw-r--r--extras/dispatch/src/message_private.h98
-rw-r--r--extras/dispatch/src/parse.c385
-rw-r--r--extras/dispatch/src/posix/threading.c125
-rw-r--r--extras/dispatch/src/python_embedded.c678
-rw-r--r--extras/dispatch/src/router_agent.c208
-rw-r--r--extras/dispatch/src/router_node.c1323
-rw-r--r--extras/dispatch/src/router_private.h177
-rw-r--r--extras/dispatch/src/router_pynode.c682
-rw-r--r--extras/dispatch/src/server.c1039
-rw-r--r--extras/dispatch/src/server_private.h100
-rw-r--r--extras/dispatch/src/timer.c239
-rw-r--r--extras/dispatch/src/timer_private.h53
-rw-r--r--extras/dispatch/src/work_queue.c132
-rw-r--r--extras/dispatch/src/work_queue.h33
-rw-r--r--extras/dispatch/tests/CMakeLists.txt59
-rw-r--r--extras/dispatch/tests/alloc_test.c86
-rw-r--r--extras/dispatch/tests/compose_test.c292
-rw-r--r--extras/dispatch/tests/config-1/A.conf54
-rw-r--r--extras/dispatch/tests/config-2/A.conf59
-rw-r--r--extras/dispatch/tests/config-2/B.conf67
-rw-r--r--extras/dispatch/tests/config-3-linear/A.conf69
-rw-r--r--extras/dispatch/tests/config-3-linear/B.conf68
-rw-r--r--extras/dispatch/tests/config-3-linear/C.conf60
-rw-r--r--extras/dispatch/tests/config-3-linear/topology.txt12
-rw-r--r--extras/dispatch/tests/field_test.c178
-rw-r--r--extras/dispatch/tests/message_test.c193
-rw-r--r--extras/dispatch/tests/parse_test.c166
-rw-r--r--extras/dispatch/tests/router_engine_test.py651
-rw-r--r--extras/dispatch/tests/run_unit_tests.c46
-rw-r--r--extras/dispatch/tests/run_unit_tests_size.c44
-rw-r--r--extras/dispatch/tests/server_test.c209
-rw-r--r--extras/dispatch/tests/system_tests_one_router.py452
-rw-r--r--extras/dispatch/tests/test_case.h36
-rw-r--r--extras/dispatch/tests/threads4.conf26
-rw-r--r--extras/dispatch/tests/timer_test.c413
-rw-r--r--extras/dispatch/tests/tool_test.c233
-rwxr-xr-xextras/dispatch/tools/src/py/qdstat328
-rw-r--r--extras/dispatch/tools/src/py/qdtoollibs/__init__.py21
-rw-r--r--extras/dispatch/tools/src/py/qdtoollibs/disp.py270
111 files changed, 0 insertions, 19905 deletions
diff --git a/extras/dispatch/CMakeLists.txt b/extras/dispatch/CMakeLists.txt
deleted file mode 100644
index a55de067f9..0000000000
--- a/extras/dispatch/CMakeLists.txt
+++ /dev/null
@@ -1,189 +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.
-##
-
-project(qpid-dispatch C)
-
-cmake_minimum_required(VERSION 2.6)
-include(CheckLibraryExists)
-include(CheckSymbolExists)
-include(CheckFunctionExists)
-include(CheckIncludeFiles)
-include(FindPythonInterp)
-include(FindPythonLibs)
-
-enable_testing()
-include (CTest)
-
-if (NOT PYTHONLIBS_FOUND)
- message(FATAL_ERROR "Python Development Libraries are needed.")
-endif (NOT PYTHONLIBS_FOUND)
-
-set (SO_VERSION_MAJOR 0)
-set (SO_VERSION_MINOR 1)
-set (SO_VERSION "${SO_VERSION_MAJOR}.${SO_VERSION_MINOR}")
-
-if (NOT DEFINED LIB_SUFFIX)
- get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
- if ("${LIB64}" STREQUAL "TRUE" AND ${CMAKE_SIZEOF_VOID_P} STREQUAL "8")
- set(LIB_SUFFIX 64)
- else()
- set(LIB_SUFFIX "")
- endif()
-endif()
-
-set(INCLUDE_INSTALL_DIR include CACHE PATH "Include file directory")
-set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "Library object file directory")
-set(SYSCONF_INSTALL_DIR etc CACHE PATH "System read only configuration directory")
-set(SHARE_INSTALL_DIR share CACHE PATH "Shared read only data directory")
-set(DOC_INSTALL_DIR ${SHARE_INSTALL_DIR}/doc CACHE PATH "Shared read-only data directory")
-set(MAN_INSTALL_DIR share/man CACHE PATH "Manpage directory")
-
-# determine the location for installing the python packages
-if (PYTHONLIBS_FOUND)
- execute_process(COMMAND ${PYTHON_EXECUTABLE}
- -c "from distutils.sysconfig import get_python_lib; print get_python_lib(False)"
- OUTPUT_VARIABLE PYTHON_SITELIB_PACKAGES
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-endif (PYTHONLIBS_FOUND)
-
-##
-## Find dependencies
-##
-find_library(proton_lib qpid-proton)
-find_library(pthread_lib pthread)
-find_library(rt_lib rt)
-find_path(proton_include proton/driver.h)
-
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/include
- ${CMAKE_CURRENT_SOURCE_DIR}/src
- ${proton_include}
- ${PYTHON_INCLUDE_PATH}
- )
-
-set(CMAKE_C_FLAGS "-pthread -Wall -Werror -std=gnu99")
-set(CATCH_UNDEFINED "-Wl,--no-undefined")
-
-##
-## Build the Multi-Threaded Server Library
-##
-set(server_SOURCES
- src/agent.c
- src/alloc.c
- src/amqp.c
- src/bitmask.c
- src/buffer.c
- src/compose.c
- src/config.c
- src/container.c
- src/dispatch.c
- src/hash.c
- src/iovec.c
- src/iterator.c
- src/log.c
- src/message.c
- src/parse.c
- src/posix/threading.c
- src/python_embedded.c
- src/router_agent.c
- src/router_node.c
- src/router_pynode.c
- src/server.c
- src/timer.c
- src/work_queue.c
- )
-
-set_property(SOURCE src/python_embedded.c src/router_pynode.c
- PROPERTY COMPILE_FLAGS -Wno-strict-aliasing
- )
-
-add_library(qpid-dispatch SHARED ${server_SOURCES})
-target_link_libraries(qpid-dispatch ${proton_lib} ${pthread_lib} ${rt_lib} ${PYTHON_LIBRARIES})
-set_target_properties(qpid-dispatch PROPERTIES
- VERSION "${SO_VERSION}"
- SOVERSION "${SO_VERSION_MAJOR}"
- LINK_FLAGS "${CATCH_UNDEFINED}"
- )
-install(TARGETS qpid-dispatch
- LIBRARY DESTINATION ${LIB_INSTALL_DIR})
-file(GLOB headers "include/qpid/dispatch/*.h")
-install(FILES ${headers} DESTINATION ${INCLUDE_INSTALL_DIR}/qpid/dispatch)
-install(FILES include/qpid/dispatch.h DESTINATION ${INCLUDE_INSTALL_DIR}/qpid)
-install(FILES etc/qpid-dispatch.conf DESTINATION ${SYSCONF_INSTALL_DIR}/qpid)
-
-##
-## Python modules installation
-##
-set(PYTHON_STUBS_SOURCES
- python/qpid/dispatch/stubs/__init__.py
- python/qpid/dispatch/stubs/ioadapter.py
- python/qpid/dispatch/stubs/logadapter.py
-)
-
-set(PYTHON_ROUTER_SOURCES
- python/qpid/dispatch/router/link.py
- python/qpid/dispatch/router/router_engine.py
- python/qpid/dispatch/router/__init__.py
- python/qpid/dispatch/router/adapter.py
- python/qpid/dispatch/router/mobile.py
- python/qpid/dispatch/router/node.py
- python/qpid/dispatch/router/routing.py
- python/qpid/dispatch/router/data.py
- python/qpid/dispatch/router/configuration.py
- python/qpid/dispatch/router/neighbor.py
- python/qpid/dispatch/router/path.py
- python/qpid/dispatch/router/binding.py
-)
-
-set(PYTHON_CONFIG_SOURCES
- python/qpid/dispatch/config/parser.py
- python/qpid/dispatch/config/__init__.py
- python/qpid/dispatch/config/schema.py
- python/qpid/dispatch/__init__.py
-)
-
-set(DOC_FILES
- ChangeLog
- LICENSE
- README.md
- TODO
-)
-
-install(FILES ${PYTHON_STUBS_SOURCES}
- DESTINATION ${PYTHON_SITELIB_PACKAGES}/qpid/dispatch/stubs)
-
-install(FILES ${PYTHON_ROUTER_SOURCES}
- DESTINATION ${PYTHON_SITELIB_PACKAGES}/qpid/dispatch/router)
-
-install(FILES ${PYTHON_CONFIG_SOURCES}
- DESTINATION ${PYTHON_SITELIB_PACKAGES}/qpid/dispatch/config)
-
-install(FILES python/qpid/__init__.py
- DESTINATION ${PYTHON_SITELIB_PACKAGES}/qpid)
-
-install(FILES python/qpid/dispatch/__init__.py
- DESTINATION ${PYTHON_SITELIB_PACKAGES}/qpid/dispatch)
-
-install(FILES ${DOC_FILES}
- DESTINATION ${DOC_INSTALL_DIR}/qpid-dispatch)
-##
-## Build Tests
-##
-add_subdirectory(router)
-add_subdirectory(tests)
diff --git a/extras/dispatch/ChangeLog b/extras/dispatch/ChangeLog
deleted file mode 100644
index 2a5b4bc4b7..0000000000
--- a/extras/dispatch/ChangeLog
+++ /dev/null
@@ -1,26 +0,0 @@
-Version 0.1:
- * Initial development work.
- * QPID-5186: Install documentation files.
- * QPID-5185: Install qpid-dispatch.conf to /etc/qpid
- * QPID-4612: Dispatch - Change server and container pattern to be consistent with other objects
- * QPID-4613: Dispatch Message API Improvement
- * QPID-4614: CTEST for Dispatch
- * QPID-4913: Dispatch - Add a configuration file reader to configure the service
- * QPID-4968: Dispatch - Generalized framework for embedded Python modules
- * QPID-4974: Dispatch - Improve the API for parsing and composing AMQP-typed fields
- * QPID-5066: Dispatch - move Python code into the qpid.dispatch package
- * QPID-5068: Dispatch - Internal feature to easily add and update Delivery Annotations
- * QPID-5096: Dispatch - Install the configuration file
- * QPID-5097: Dispatch - create a source tarball
- * QPID-5181: Dispatch - Assign temporary source addresses for dynamic listener links
- * QPID-5185: Move the qpid-dispatch.conf file to /etc/qpid
- * QPID-5186: Installing Dispatch should also install the LICENSE, TODO and related files
- * QPID-5189: Add a config.sh file for Qpid Dispatch to set an environment for running the router
-
- * QPID-4788: Dispatch - Re-schedule of an "immediate" timer causes crash
- * QPID-4816: dispatch-router crashes when incomplete (but valid) url specified by client.
- * QPID-4997: Dispatch - Thread safety issues in the usage of Proton
- * QPID-5064: Dispatch - make-install doesn't install the Python artifacts
- * QPID-5173: [dispatch] cmake ignores overrides to CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH
- * QPID-5201: Dispatch - Fix build errors in Release mode
- * QPID-5218: [dispatch] Crash when outgoing window > 0 and multiple subscribed Messenger clients
diff --git a/extras/dispatch/LICENSE b/extras/dispatch/LICENSE
deleted file mode 100644
index 261eeb9e9f..0000000000
--- a/extras/dispatch/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed 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.
diff --git a/extras/dispatch/README.md b/extras/dispatch/README.md
deleted file mode 100644
index 1a4438fdf9..0000000000
--- a/extras/dispatch/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-Qpid Dispatch
-=============
-
-A lightweight AMQP router for building scalable, available, and performant messaging
-interconnect.
-
-Building
-========
-
-From the dispatch directory:
-
-$ mkdir build
-$ cd build
-$ cmake ..
-$ make
-$ make test # see below
-
-Note: Your PYTHONPATH _must_ include <dispatch>/python in its list of paths in order
-to test and run Dispatch.
-
-Running The Tests
-=================
-
-Prior to running the unit tests, you should source the file config.sh which is
-found in the root directory.
-
-$ . config.sh
-
-The file sets up the environment so that the tests can find the Python
-libraries, etc.
diff --git a/extras/dispatch/TODO b/extras/dispatch/TODO
deleted file mode 100644
index 5bb334a6ca..0000000000
--- a/extras/dispatch/TODO
+++ /dev/null
@@ -1,54 +0,0 @@
-Qpid Dispatch TODO List
-==============================================================================
-Beyond this simple laundry list, you can find the list of bugs and
-enhancements to be fixed by going to the Apache Qpid JIRA instance:
-
- http://issues.apache.org/jira/browse/QPID
-==============================================================================
-
-- Router Mode:
- o Stand-Alone-Router - Does not participate in routing protocol, does not permit inter-router
- links, acts as a normal interior-router otherwise.
- o Interior-Router - Participates in the routing protocol
- o Edge-Concentrator - Does not participate in routing protocol, requires uplink connection(s)
- This mode should be used when Dispatch is integrated into an endpoint
- application or when it is acting as a connection concentrator.
- Proxy and access-protocol functions will be available in this mode.
-
-- Connection Annotation:
- o Type: Inter-router, uplink, endpoint, etc. This formal annotation can be accessed internally
- by the connection handlers to guide Dispatch's handling of new connections.
- o Weight-{in,out}: Weight/Cost metrics for inter-router links
-
-- Statistics for Instrumentation:
- o Link
- . delivery count {unsettled, pre-settled}
- . deliveries {accepted, rejected, released, modified}
- . octets of delivery {accepted, rejected, released, modified}
- . flow frame count
- . disposition frame count {forward, backward}
- o Address
- . deliveries {ingress, egress, transit}
- . octets of delivery {ingress, egress, transit}
-
-- Infrastructure
- o Router_Link - Buffer and Iterator for a copy of the link's target address (for use
- as an address for messages with no 'to' field).
- o Router Event Queue - Event queue to feed alerts to the Python router code.
- Neighbor-link-loss is a valuable event because it accelerates the
- detection of topology change.
- o All PyRouter stimulus through a work queue.
- o Router Code Updates
- . Report address mappings to routers
- . Generate RA immediately after updating routing tables
- . Generate unsolicited updates for mobile addresses?
- o Expose idle-timeout/keepalive on connectors and listeners
-
-- Major Roadmap Features
- o Security Policy Enforcement
- o Proxy (Translation Node) Capability
- o Address Provisioning with variable semantics
- o Link Routing
- o Management, Instrumentation, and Accounting
- o Link Cost
- o Area Routing
diff --git a/extras/dispatch/config.sh b/extras/dispatch/config.sh
deleted file mode 100644
index 3c96464ea9..0000000000
--- a/extras/dispatch/config.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/bash
-#
-# 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.
-#
-
-cd $(dirname ${BASH_SOURCE[0]}) > /dev/null
-export QPID_DISPATCH_HOME=$(pwd)
-cd - > /dev/null
-
-export PYTHONPATH=$QPID_DISPATCH_HOME/python:$QPID_DISPATCH_HOME/tools/src/py:$PYTHONPATH
-export PATH=$QPID_DISPATCH_HOME/tools/src/py:$PATH
-
diff --git a/extras/dispatch/etc/qpid-dispatch.conf b/extras/dispatch/etc/qpid-dispatch.conf
deleted file mode 100644
index bf25993130..0000000000
--- a/extras/dispatch/etc/qpid-dispatch.conf
+++ /dev/null
@@ -1,151 +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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- ##
- ## worker-threads - The number of threads that will be created to
- ## process message traffic and other application work (timers, non-amqp
- ## file descriptors, etc.)
- ##
- ## The number of threads should be related to the number of available
- ## processor cores. To fully utilize a quad-core system, set the
- ## number of threads to 4.
- ##
- worker-threads: 4
-
- ##
- ## container-name - The name of the AMQP container. If not specified,
- ## the container name will be set to a value of the container's
- ## choosing. The automatically assigned container name is not
- ## guaranteed to be persistent across restarts of the container.
- ##
- container-name: Qpid.Dispatch.Router.A
-}
-
-
-##
-## SSL Profile section - Zero or more SSL profiles may be defined here and
-## then referenced later in listeners (for incoming connections) or
-## connectors (for outgoing connectors).
-##
-ssl-profile {
- ##
- ## name - The name of the profile to be referenced later.
- ##
- name: ssl-profile-name
-
- ##
- ## cert-db - The path to the database that contains the public
- ## certificates of trusted certificate authorities (CAs).
- ##
- ## cert-db: /path/to/trusted-ca.db
-
- ##
- ## cert-file - The path to the file containing the PEM-formatted public
- ## certificate to be used on the local end of any connections using
- ## this profile.
- ##
- ## cert-file: /path/to/cert-file.pem
-
- ##
- ## key-file - The path to the file containing the PEM-formatted private
- ## key for the above certificate.
- ##
- ## key-file: /path/to/private-key-file.pem
-
- ##
- ## password-file - If the above private key is password protected, this
- ## is the path to a file containing the password that unlocks the
- ## certificate key.
- ##
- ## password-file: /path/to/password-file
-
- ##
- ## password - An alternative to storing the password in a file
- ## referenced by password-file is to supply the password right here in
- ## the configuration file. This option can be used by supplying the
- ## password in the 'password' option. Don't use both password and
- ## password-file in the same profile.
- ##
- ## password: <password>
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- addr: 0.0.0.0
- port: amqp
- sasl-mechanisms: ANONYMOUS
-}
-
-listener {
- label: Router Interconnect Access
- role: inter-router
- addr: 0.0.0.0
- port: 5671
- sasl-mechanisms: EXTERNAL
- ssl-profile: ssl-profile-name
- require-peer-auth: yes
- allow-unsecured: yes
-}
-
-connector {
- label: Router Uplink
- role: inter-router
- addr: backbone.enterprise.com
- port: amqps
- sasl-mechanisms: EXTERNAL
- ssl-profile: ssl-profile-name
- allow-redirect: no
-}
-
-
-##
-## Router section - Configure the AMQP router function.
-##
-router {
- ##
- ## Router Mode:
- ##
- ## standalone - Standalone router. In standalone mode, the router operates as
- ## a single component. It does not participate in the routing protocol
- ## and therefore will not coorperate with other routers.
- ## interior - Interior router. The router operates in cooreration with other
- ## interior routers in an interconnected network.
- ## edge - Edge router. The router operates with an uplink into an interior
- ## router network. Edge routers are typically used as connection concentrators
- ## or as security firewalls for access into the interior network.
- ##
- mode: standalone
-
- ##
- ## For Interior router mode only.
- ##
- ## router-id - Each router is assigned a router-id that is unique.
- ##
- router-id: Router.A
-}
-
-
diff --git a/extras/dispatch/include/qpid/dispatch.h b/extras/dispatch/include/qpid/dispatch.h
deleted file mode 100644
index 6b3d6a963f..0000000000
--- a/extras/dispatch/include/qpid/dispatch.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __dispatch_h__
-#define __dispatch_h__ 1
-/*
- * 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/dispatch/alloc.h>
-#include <qpid/dispatch/bitmask.h>
-#include <qpid/dispatch/buffer.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/hash.h>
-#include <qpid/dispatch/iovec.h>
-#include <qpid/dispatch/iterator.h>
-#include <qpid/dispatch/log.h>
-#include <qpid/dispatch/router.h>
-#include <qpid/dispatch/amqp.h>
-#include <qpid/dispatch/parse.h>
-#include <qpid/dispatch/compose.h>
-#include <qpid/dispatch/config.h>
-#include <qpid/dispatch/threading.h>
-#include <qpid/dispatch/timer.h>
-#include <qpid/dispatch/user_fd.h>
-#include <qpid/dispatch/server.h>
-#include <qpid/dispatch/message.h>
-#include <qpid/dispatch/container.h>
-#include <qpid/dispatch/agent.h>
-#include <qpid/dispatch/dispatch.h>
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/agent.h b/extras/dispatch/include/qpid/dispatch/agent.h
deleted file mode 100644
index fb2279049f..0000000000
--- a/extras/dispatch/include/qpid/dispatch/agent.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef __dispatch_agent_h__
-#define __dispatch_agent_h__ 1
-/*
- * 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/dispatch/dispatch.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-/**
- * \defgroup Container Management Agent
- * @{
- */
-
-typedef struct dx_agent_class_t dx_agent_class_t;
-
-
-/**
- * \brief Get Schema Data Handler
- *
- * @param context The handler context supplied in dx_agent_register.
- */
-typedef void (*dx_agent_schema_cb_t)(void* context, void *correlator);
-
-
-/**
- * \brief Query Handler
- *
- * @param context The handler context supplied in dx_agent_register.
- * @param id The identifier of the instance being queried or NULL for all instances.
- * @param correlator The correlation handle to be used in calls to dx_agent_value_*
- */
-typedef void (*dx_agent_query_cb_t)(void* context, const char *id, void *correlator);
-
-
-/**
- * \brief Register a class/object-type with the agent.
- */
-dx_agent_class_t *dx_agent_register_class(dx_dispatch_t *dx,
- const char *fqname,
- void *context,
- dx_agent_schema_cb_t schema_handler,
- dx_agent_query_cb_t query_handler);
-
-/**
- * \brief Register an event-type with the agent.
- */
-dx_agent_class_t *dx_agent_register_event(dx_dispatch_t *dx,
- const char *fqname,
- void *context,
- dx_agent_schema_cb_t schema_handler);
-
-/**
- *
- */
-void dx_agent_value_string(void *correlator, const char *key, const char *value);
-void dx_agent_value_uint(void *correlator, const char *key, uint64_t value);
-void dx_agent_value_null(void *correlator, const char *key);
-void dx_agent_value_boolean(void *correlator, const char *key, bool value);
-void dx_agent_value_binary(void *correlator, const char *key, const uint8_t *value, size_t len);
-void dx_agent_value_uuid(void *correlator, const char *key, const uint8_t *value);
-void dx_agent_value_timestamp(void *correlator, const char *key, uint64_t value);
-
-
-/**
- *
- */
-void dx_agent_value_complete(void *correlator, bool more);
-
-
-/**
- *
- */
-void *dx_agent_raise_event(dx_dispatch_t *dx, dx_agent_class_t *event);
-
-
-/**
- * @}
- */
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/alloc.h b/extras/dispatch/include/qpid/dispatch/alloc.h
deleted file mode 100644
index ae4190ad89..0000000000
--- a/extras/dispatch/include/qpid/dispatch/alloc.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef __dispatch_alloc_h__
-#define __dispatch_alloc_h__ 1
-/*
- * 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 <stdlib.h>
-#include <stdint.h>
-#include <qpid/dispatch/threading.h>
-
-typedef struct dx_alloc_pool_t dx_alloc_pool_t;
-
-typedef struct {
- int transfer_batch_size;
- int local_free_list_max;
- int global_free_list_max;
-} dx_alloc_config_t;
-
-typedef struct {
- uint64_t total_alloc_from_heap;
- uint64_t total_free_to_heap;
- uint64_t held_by_threads;
- uint64_t batches_rebalanced_to_threads;
- uint64_t batches_rebalanced_to_global;
-} dx_alloc_stats_t;
-
-typedef struct {
- char *type_name;
- size_t type_size;
- size_t *additional_size;
- size_t total_size;
- dx_alloc_config_t *config;
- dx_alloc_stats_t *stats;
- dx_alloc_pool_t *global_pool;
- sys_mutex_t *lock;
-} dx_alloc_type_desc_t;
-
-
-void *dx_alloc(dx_alloc_type_desc_t *desc, dx_alloc_pool_t **tpool);
-void dx_dealloc(dx_alloc_type_desc_t *desc, dx_alloc_pool_t **tpool, void *p);
-
-
-#define ALLOC_DECLARE(T) \
- T *new_##T(); \
- void free_##T(T *p)
-
-#define ALLOC_DEFINE_CONFIG(T,S,A,C) \
- dx_alloc_type_desc_t __desc_##T = {#T, S, A, 0, C, 0, 0, 0}; \
- __thread dx_alloc_pool_t *__local_pool_##T = 0; \
- T *new_##T() { return (T*) dx_alloc(&__desc_##T, &__local_pool_##T); } \
- void free_##T(T *p) { dx_dealloc(&__desc_##T, &__local_pool_##T, (void*) p); } \
- dx_alloc_stats_t *alloc_stats_##T() { return __desc_##T.stats; }
-
-#define ALLOC_DEFINE(T) ALLOC_DEFINE_CONFIG(T, sizeof(T), 0, 0)
-
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/amqp.h b/extras/dispatch/include/qpid/dispatch/amqp.h
deleted file mode 100644
index c27eec6589..0000000000
--- a/extras/dispatch/include/qpid/dispatch/amqp.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef __dispatch_amqp_h__
-#define __dispatch_amqp_h__ 1
-/*
- * 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.
- */
-
-/**
- * AMQP Performative Tags
- */
-#define DX_PERFORMATIVE_HEADER 0x70
-#define DX_PERFORMATIVE_DELIVERY_ANNOTATIONS 0x71
-#define DX_PERFORMATIVE_MESSAGE_ANNOTATIONS 0x72
-#define DX_PERFORMATIVE_PROPERTIES 0x73
-#define DX_PERFORMATIVE_APPLICATION_PROPERTIES 0x74
-#define DX_PERFORMATIVE_BODY_DATA 0x75
-#define DX_PERFORMATIVE_BODY_AMQP_SEQUENCE 0x76
-#define DX_PERFORMATIVE_BODY_AMQP_VALUE 0x77
-#define DX_PERFORMATIVE_FOOTER 0x78
-
-
-/**
- * AMQP Type Tags
- */
-#define DX_AMQP_NULL 0x40
-#define DX_AMQP_BOOLEAN 0x56
-#define DX_AMQP_TRUE 0x41
-#define DX_AMQP_FALSE 0x42
-#define DX_AMQP_UBYTE 0x50
-#define DX_AMQP_USHORT 0x60
-#define DX_AMQP_UINT 0x70
-#define DX_AMQP_SMALLUINT 0x52
-#define DX_AMQP_UINT0 0x43
-#define DX_AMQP_ULONG 0x80
-#define DX_AMQP_SMALLULONG 0x53
-#define DX_AMQP_ULONG0 0x44
-#define DX_AMQP_BYTE 0x51
-#define DX_AMQP_SHORT 0x61
-#define DX_AMQP_INT 0x71
-#define DX_AMQP_SMALLINT 0x54
-#define DX_AMQP_LONG 0x81
-#define DX_AMQP_SMALLLONG 0x55
-#define DX_AMQP_FLOAT 0x72
-#define DX_AMQP_DOUBLE 0x82
-#define DX_AMQP_DECIMAL32 0x74
-#define DX_AMQP_DECIMAL64 0x84
-#define DX_AMQP_DECIMAL128 0x94
-#define DX_AMQP_UTF32 0x73
-#define DX_AMQP_TIMESTAMP 0x83
-#define DX_AMQP_UUID 0x98
-#define DX_AMQP_VBIN8 0xa0
-#define DX_AMQP_VBIN32 0xb0
-#define DX_AMQP_STR8_UTF8 0xa1
-#define DX_AMQP_STR32_UTF8 0xb1
-#define DX_AMQP_SYM8 0xa3
-#define DX_AMQP_SYM32 0xb3
-#define DX_AMQP_LIST0 0x45
-#define DX_AMQP_LIST8 0xc0
-#define DX_AMQP_LIST32 0xd0
-#define DX_AMQP_MAP8 0xc1
-#define DX_AMQP_MAP32 0xd1
-#define DX_AMQP_ARRAY8 0xe0
-#define DX_AMQP_ARRAY32 0xf0
-
-/**
- * Delivery Annotation Headers
- */
-const char * const DX_DA_INGRESS; // Ingress Router
-const char * const DX_DA_TRACE; // Trace
-const char * const DX_DA_TO; // To-Override
-
-/**
- * Link Terminus Capabilities
- */
-const char * const DX_CAPABILITY_ROUTER;
-
-/**
- * Miscellaneous Strings
- */
-const char * const DX_INTERNODE_LINK_NAME_1;
-const char * const DX_INTERNODE_LINK_NAME_2;
-
-#endif
-
diff --git a/extras/dispatch/include/qpid/dispatch/bitmask.h b/extras/dispatch/include/qpid/dispatch/bitmask.h
deleted file mode 100644
index fe436bc19b..0000000000
--- a/extras/dispatch/include/qpid/dispatch/bitmask.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __dispatch_bitmask_h__
-#define __dispatch_bitmask_h__ 1
-/*
- * 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.
- */
-
-typedef struct dx_bitmask_t dx_bitmask_t;
-
-int dx_bitmask_width();
-dx_bitmask_t *dx_bitmask(int initial);
-void dx_bitmask_free(dx_bitmask_t *b);
-void dx_bitmask_set_all(dx_bitmask_t *b);
-void dx_bitmask_clear_all(dx_bitmask_t *b);
-void dx_bitmask_set_bit(dx_bitmask_t *b, int bitnum);
-void dx_bitmask_clear_bit(dx_bitmask_t *b, int bitnum);
-int dx_bitmask_value(dx_bitmask_t *b, int bitnum);
-int dx_bitmask_first_set(dx_bitmask_t *b, int *bitnum);
-
-
-
-#endif
-
diff --git a/extras/dispatch/include/qpid/dispatch/buffer.h b/extras/dispatch/include/qpid/dispatch/buffer.h
deleted file mode 100644
index fadded4d74..0000000000
--- a/extras/dispatch/include/qpid/dispatch/buffer.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef __dispatch_buffer_h__
-#define __dispatch_buffer_h__ 1
-/*
- * 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/dispatch/ctools.h>
-
-typedef struct dx_buffer_t dx_buffer_t;
-
-DEQ_DECLARE(dx_buffer_t, dx_buffer_list_t);
-
-struct dx_buffer_t {
- DEQ_LINKS(dx_buffer_t);
- unsigned int size;
-};
-
-/**
- */
-void dx_buffer_set_size(size_t size);
-
-/**
- */
-dx_buffer_t *dx_buffer(void);
-
-/**
- * @param buf A pointer to an allocated buffer
- */
-void dx_buffer_free(dx_buffer_t *buf);
-
-/**
- * @param buf A pointer to an allocated buffer
- * @return A pointer to the first octet in the buffer
- */
-unsigned char *dx_buffer_base(dx_buffer_t *buf);
-
-/**
- * @param buf A pointer to an allocated buffer
- * @return A pointer to the first free octet in the buffer, the insert point for new data.
- */
-unsigned char *dx_buffer_cursor(dx_buffer_t *buf);
-
-/**
- * @param buf A pointer to an allocated buffer
- * @return The number of octets in the buffer's free space, how many octets may be inserted.
- */
-size_t dx_buffer_capacity(dx_buffer_t *buf);
-
-/**
- * @param buf A pointer to an allocated buffer
- * @return The number of octets of data in the buffer
- */
-size_t dx_buffer_size(dx_buffer_t *buf);
-
-/**
- * Notify the buffer that octets have been inserted at the buffer's cursor. This will advance the
- * cursor by len octets.
- *
- * @param buf A pointer to an allocated buffer
- * @param len The number of octets that have been appended to the buffer
- */
-void dx_buffer_insert(dx_buffer_t *buf, size_t len);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/compose.h b/extras/dispatch/include/qpid/dispatch/compose.h
deleted file mode 100644
index d68f6be746..0000000000
--- a/extras/dispatch/include/qpid/dispatch/compose.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef __dispatch_compose_h__
-#define __dispatch_compose_h__ 1
-/*
- * 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/dispatch/buffer.h>
-#include <qpid/dispatch/iterator.h>
-
-typedef struct dx_composed_field_t dx_composed_field_t;
-
-/**
- * Begin composing a new field for a message. The new field can be standalone or
- * appended onto an existing field.
- *
- * @param performative The performative for the message section being composed.
- * @param extend An existing field onto which to append the new field or NULL to
- * create a standalone field.
- * @return A pointer to the newly created field.
- */
-dx_composed_field_t *dx_compose(uint64_t performative, dx_composed_field_t *extend);
-
-/**
- * Free the resources associated with a composed field.
- *
- * @param A field pointer returned by dx_compose.
- */
-void dx_compose_free(dx_composed_field_t *field);
-
-/**
- * Begin to compose the elements of a list in the field. This is called before inserting
- * the first list element.
- *
- * @param field A field created by dx_compose.
- */
-void dx_compose_start_list(dx_composed_field_t *field);
-
-/**
- * Complete the composition of a list in the field. This is called after the last
- * list element has been inserted.
- *
- * @param field A field created by dx_compose.
- */
-void dx_compose_end_list(dx_composed_field_t *field);
-
-/**
- * Begin to compose the elements os a map in the field. This is called before
- * inserting the first element-pair into the map.
- *
- * @param field A field created by dx_compose.
- */
-void dx_compose_start_map(dx_composed_field_t *field);
-
-/**
- * Complete the composition of a map in the field. This is called after the last
- * element-pair has been inserted.
- *
- * @param field A field created by dx_compose.
- */
-void dx_compose_end_map(dx_composed_field_t *field);
-
-/**
- * Insert a null element into the field.
- *
- * @param field A field created by dx_compose.
- */
-void dx_compose_insert_null(dx_composed_field_t *field);
-
-/**
- * Insert a boolean value into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The boolean (zero or non-zero) value to insert.
- */
-void dx_compose_insert_bool(dx_composed_field_t *field, int value);
-
-/**
- * Insert an unsigned integer (up to 32 bits) into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The unsigned integer value to be inserted.
- */
-void dx_compose_insert_uint(dx_composed_field_t *field, uint32_t value);
-
-/**
- * Insert a long (64-bit) unsigned value into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The unsigned integer value to be inserted.
- */
-void dx_compose_insert_ulong(dx_composed_field_t *field, uint64_t value);
-
-/**
- * Insert a signed integer (up to 32 bits) into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The integer value to be inserted.
- */
-void dx_compose_insert_int(dx_composed_field_t *field, int32_t value);
-
-/**
- * Insert a long signed integer (64 bits) into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The integer value to be inserted.
- */
-void dx_compose_insert_long(dx_composed_field_t *field, int64_t value);
-
-/**
- * Insert a timestamp into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The timestamp value to be inserted.
- */
-void dx_compose_insert_timestamp(dx_composed_field_t *field, uint64_t value);
-
-/**
- * Insert a UUID into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The pointer to the first octet in the UUID to be inserted.
- */
-void dx_compose_insert_uuid(dx_composed_field_t *field, const uint8_t *value);
-
-/**
- * Insert a binary blob into the field.
- *
- * @param field A field created by dx_compose.
- * @param value The pointer to the first octet to be inserted.
- * @param len The length, in octets, of the binary blob.
- */
-void dx_compose_insert_binary(dx_composed_field_t *field, const uint8_t *value, uint32_t len);
-
-/**
- * Insert a binary blob from a list of buffers.
- *
- * @param field A field created by dx_compose.
- * @param buffers A pointer to a list of buffers to be inserted as binary data. Note that
- * the buffer list will be left empty by this function.
- */
-void dx_compose_insert_binary_buffers(dx_composed_field_t *field, dx_buffer_list_t *buffers);
-
-/**
- * Insert a null-terminated utf8-encoded string into the field.
- *
- * @param field A field created by dx_compose.
- * @param value A pointer to a null-terminated string.
- */
-void dx_compose_insert_string(dx_composed_field_t *field, const char *value);
-
-/**
- * Insert a utf8-encoded string into the field from an iterator
- *
- * @param field A field created by dx_compose.
- * @param iter An iterator for a string value. The caller is responsible for freeing
- * this iterator after the call is complete.
- */
-void dx_compose_insert_string_iterator(dx_composed_field_t *field, dx_field_iterator_t *iter);
-
-/**
- * Insert a symbol into the field.
- *
- * @param field A field created by dx_compose.
- * @param value A pointer to a null-terminated ASCII string.
- */
-void dx_compose_insert_symbol(dx_composed_field_t *field, const char *value);
-
-#endif
-
diff --git a/extras/dispatch/include/qpid/dispatch/config.h b/extras/dispatch/include/qpid/dispatch/config.h
deleted file mode 100644
index 78186ee5cd..0000000000
--- a/extras/dispatch/include/qpid/dispatch/config.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef __dispatch_config_h__
-#define __dispatch_config_h__ 1
-/*
- * 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 <stdint.h>
-
-typedef struct dx_config_t dx_config_t;
-
-int dx_config_item_count(const dx_config_t *config, const char *section);
-const char *dx_config_item_value_string(const dx_config_t *config, const char *section, int index, const char* key);
-uint32_t dx_config_item_value_int(const dx_config_t *config, const char *section, int index, const char* key);
-int dx_config_item_value_bool(const dx_config_t *config, const char *section, int index, const char* key);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/container.h b/extras/dispatch/include/qpid/dispatch/container.h
deleted file mode 100644
index 03fdd0c4cc..0000000000
--- a/extras/dispatch/include/qpid/dispatch/container.h
+++ /dev/null
@@ -1,209 +0,0 @@
-#ifndef __dispatch_container_h__
-#define __dispatch_container_h__ 1
-/*
- * 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 <proton/engine.h>
-#include <qpid/dispatch/dispatch.h>
-#include <qpid/dispatch/server.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/ctools.h>
-
-typedef uint8_t dx_dist_mode_t;
-#define DX_DIST_COPY 0x01
-#define DX_DIST_MOVE 0x02
-#define DX_DIST_BOTH 0x03
-
-/**
- * Node Lifetime Policy (see AMQP 3.5.9)
- */
-typedef enum {
- DX_LIFE_PERMANENT,
- DX_LIFE_DELETE_CLOSE,
- DX_LIFE_DELETE_NO_LINKS,
- DX_LIFE_DELETE_NO_MESSAGES,
- DX_LIFE_DELETE_NO_LINKS_MESSAGES
-} dx_lifetime_policy_t;
-
-
-/**
- * Link Direction
- */
-typedef enum {
- DX_INCOMING,
- DX_OUTGOING
-} dx_direction_t;
-
-
-typedef struct dx_node_t dx_node_t;
-typedef struct dx_link_t dx_link_t;
-typedef struct dx_delivery_t dx_delivery_t;
-
-typedef void (*dx_container_delivery_handler_t) (void *node_context, dx_link_t *link, dx_delivery_t *delivery);
-typedef int (*dx_container_link_handler_t) (void *node_context, dx_link_t *link);
-typedef int (*dx_container_link_detach_handler_t) (void *node_context, dx_link_t *link, int closed);
-typedef void (*dx_container_node_handler_t) (void *type_context, dx_node_t *node);
-typedef void (*dx_container_conn_handler_t) (void *type_context, dx_connection_t *conn);
-
-typedef struct {
- char *type_name;
- void *type_context;
- int allow_dynamic_creation;
-
- //=======================
- // Node-Instance Handlers
- //=======================
-
- //
- // rx_handler - Invoked when a new received delivery is avaliable for processing.
- //
- dx_container_delivery_handler_t rx_handler;
-
- //
- // disp_handler - Invoked when an existing delivery changes disposition
- // or settlement state.
- //
- dx_container_delivery_handler_t disp_handler;
-
- //
- // incoming_handler - Invoked when an attach for a new incoming link is received.
- //
- dx_container_link_handler_t incoming_handler;
-
- //
- // outgoing_handler - Invoked when an attach for a new outgoing link is received.
- //
- dx_container_link_handler_t outgoing_handler;
-
- //
- // writable_handler - Invoked when an outgoing link is available for sending either
- // deliveries or disposition changes. The handler must check the
- // link's credit to determine whether (and how many) message
- // deliveries may be sent.
- //
- dx_container_link_handler_t writable_handler;
-
- //
- // link_detach_handler - Invoked when a link is detached.
- //
- dx_container_link_detach_handler_t link_detach_handler;
-
- //===================
- // Node-Type Handlers
- //===================
-
- //
- // node_created_handler - Invoked when a new instance of the node-type is created.
- //
- dx_container_node_handler_t node_created_handler;
-
- //
- // node_destroyed_handler - Invoked when an instance of the node type is destroyed.
- //
- dx_container_node_handler_t node_destroyed_handler;
-
- //
- // inbound_conn_open_handler - Invoked when an incoming connection (via listener)
- // is established.
- //
- dx_container_conn_handler_t inbound_conn_open_handler;
-
- //
- // outbound_conn_open_handler - Invoked when an outgoing connection (via connector)
- // is established.
- //
- dx_container_conn_handler_t outbound_conn_open_handler;
-} dx_node_type_t;
-
-
-int dx_container_register_node_type(dx_dispatch_t *dispatch, const dx_node_type_t *nt);
-
-dx_node_t *dx_container_set_default_node_type(dx_dispatch_t *dispatch,
- const dx_node_type_t *nt,
- void *node_context,
- dx_dist_mode_t supported_dist);
-
-dx_node_t *dx_container_create_node(dx_dispatch_t *dispatch,
- const dx_node_type_t *nt,
- const char *name,
- void *node_context,
- dx_dist_mode_t supported_dist,
- dx_lifetime_policy_t life_policy);
-void dx_container_destroy_node(dx_node_t *node);
-
-void dx_container_node_set_context(dx_node_t *node, void *node_context);
-dx_dist_mode_t dx_container_node_get_dist_modes(const dx_node_t *node);
-dx_lifetime_policy_t dx_container_node_get_life_policy(const dx_node_t *node);
-
-dx_link_t *dx_link(dx_node_t *node, dx_connection_t *conn, dx_direction_t dir, const char *name);
-
-/**
- * Context associated with the link for storing link-specific state.
- */
-void dx_link_set_context(dx_link_t *link, void *link_context);
-void *dx_link_get_context(dx_link_t *link);
-
-/**
- * Link context associated with the link's connection for storing state shared across
- * all links in a connection.
- */
-void dx_link_set_conn_context(dx_link_t *link, void *link_context);
-void *dx_link_get_conn_context(dx_link_t *link);
-
-dx_connection_t *dx_link_connection(dx_link_t *link);
-pn_link_t *dx_link_pn(dx_link_t *link);
-pn_terminus_t *dx_link_source(dx_link_t *link);
-pn_terminus_t *dx_link_target(dx_link_t *link);
-pn_terminus_t *dx_link_remote_source(dx_link_t *link);
-pn_terminus_t *dx_link_remote_target(dx_link_t *link);
-void dx_link_activate(dx_link_t *link);
-void dx_link_close(dx_link_t *link);
-
-/**
- * Important: dx_delivery must never be called twice in a row without an intervening pn_link_advance.
- * The Disatch architecture provides a hook for discovering when an outgoing link is writable
- * and has credit. When a link is writable, a delivery is allocated, written, and advanced
- * in one operation. If a backlog of pending deliveries is created, an assertion will be
- * thrown.
- */
-dx_delivery_t *dx_delivery(dx_link_t *link, pn_delivery_tag_t tag);
-void dx_delivery_free(dx_delivery_t *delivery, uint64_t final_disposition);
-void dx_delivery_set_peer(dx_delivery_t *delivery, dx_delivery_t *peer);
-dx_delivery_t *dx_delivery_peer(dx_delivery_t *delivery);
-void dx_delivery_set_context(dx_delivery_t *delivery, void *context);
-void *dx_delivery_context(dx_delivery_t *delivery);
-pn_delivery_t *dx_delivery_pn(dx_delivery_t *delivery);
-void dx_delivery_settle(dx_delivery_t *delivery);
-bool dx_delivery_settled(dx_delivery_t *delivery);
-bool dx_delivery_disp_changed(dx_delivery_t *delivery);
-uint64_t dx_delivery_disp(dx_delivery_t *delivery);
-dx_link_t *dx_delivery_link(dx_delivery_t *delivery);
-
-
-typedef struct dx_link_item_t dx_link_item_t;
-
-struct dx_link_item_t {
- DEQ_LINKS(dx_link_item_t);
- dx_link_t *link;
-};
-
-ALLOC_DECLARE(dx_link_item_t);
-DEQ_DECLARE(dx_link_item_t, dx_link_list_t);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/ctools.h b/extras/dispatch/include/qpid/dispatch/ctools.h
deleted file mode 100644
index 655c49f261..0000000000
--- a/extras/dispatch/include/qpid/dispatch/ctools.h
+++ /dev/null
@@ -1,147 +0,0 @@
-#ifndef __dispatch_ctools_h__
-#define __dispatch_ctools_h__ 1
-/*
- * 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 <stdlib.h>
-#include <assert.h>
-
-#define CT_ASSERT(exp) { assert(exp); }
-
-#define NEW(t) (t*) malloc(sizeof(t))
-#define NEW_ARRAY(t,n) (t*) malloc(sizeof(t)*(n))
-#define NEW_PTR_ARRAY(t,n) (t**) malloc(sizeof(t*)*(n))
-
-#define DEQ_DECLARE(i,d) typedef struct { \
- i *head; \
- i *tail; \
- i *scratch; \
- size_t size; \
- } d
-
-#define DEQ_LINKS(t) t *prev; t *next
-
-#define DEQ_INIT(d) do { (d).head = 0; (d).tail = 0; (d).scratch = 0; (d).size = 0; } while (0)
-#define DEQ_ITEM_INIT(i) do { (i)->next = 0; (i)->prev = 0; } while(0)
-#define DEQ_HEAD(d) ((d).head)
-#define DEQ_TAIL(d) ((d).tail)
-#define DEQ_SIZE(d) ((d).size)
-#define DEQ_NEXT(i) (i)->next
-#define DEQ_PREV(i) (i)->prev
-
-#define DEQ_INSERT_HEAD(d,i) \
-do { \
- CT_ASSERT((i)->next == 0); \
- CT_ASSERT((i)->prev == 0); \
- if ((d).head) { \
- (i)->next = (d).head; \
- (d).head->prev = i; \
- } else { \
- (d).tail = i; \
- (i)->next = 0; \
- CT_ASSERT((d).size == 0); \
- } \
- (i)->prev = 0; \
- (d).head = i; \
- (d).size++; \
-} while (0)
-
-#define DEQ_INSERT_TAIL(d,i) \
-do { \
- CT_ASSERT((i)->next == 0); \
- CT_ASSERT((i)->prev == 0); \
- if ((d).tail) { \
- (i)->prev = (d).tail; \
- (d).tail->next = i; \
- } else { \
- (d).head = i; \
- (i)->prev = 0; \
- CT_ASSERT((d).size == 0); \
- } \
- (i)->next = 0; \
- (d).tail = i; \
- (d).size++; \
-} while (0)
-
-#define DEQ_REMOVE_HEAD(d) \
-do { \
- CT_ASSERT((d).head); \
- if ((d).head) { \
- (d).scratch = (d).head; \
- (d).head = (d).head->next; \
- if ((d).head == 0) { \
- (d).tail = 0; \
- CT_ASSERT((d).size == 1); \
- } else \
- (d).head->prev = 0; \
- (d).size--; \
- (d).scratch->next = 0; \
- (d).scratch->prev = 0; \
- } \
-} while (0)
-
-#define DEQ_REMOVE_TAIL(d) \
-do { \
- CT_ASSERT((d).tail); \
- if ((d).tail) { \
- (d).scratch = (d).tail; \
- (d).tail = (d).tail->prev; \
- if ((d).tail == 0) { \
- (d).head = 0; \
- CT_ASSERT((d).size == 1); \
- } else \
- (d).tail->next = 0; \
- (d).size--; \
- (d).scratch->next = 0; \
- (d).scratch->prev = 0; \
- } \
-} while (0)
-
-#define DEQ_INSERT_AFTER(d,i,a) \
-do { \
- CT_ASSERT((i)->next == 0); \
- CT_ASSERT((i)->prev == 0); \
- CT_ASSERT(a); \
- if ((a)->next) \
- (a)->next->prev = (i); \
- else \
- (d).tail = (i); \
- (i)->next = (a)->next; \
- (i)->prev = (a); \
- (a)->next = (i); \
- (d).size++; \
-} while (0)
-
-#define DEQ_REMOVE(d,i) \
-do { \
- if ((i)->next) \
- (i)->next->prev = (i)->prev; \
- else \
- (d).tail = (i)->prev; \
- if ((i)->prev) \
- (i)->prev->next = (i)->next; \
- else \
- (d).head = (i)->next; \
- (d).size--; \
- (i)->next = 0; \
- (i)->prev = 0; \
- CT_ASSERT((d).size || (!(d).head && !(d).tail)); \
-} while (0)
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/dispatch.h b/extras/dispatch/include/qpid/dispatch/dispatch.h
deleted file mode 100644
index 87f3fc32d1..0000000000
--- a/extras/dispatch/include/qpid/dispatch/dispatch.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __dispatch_dispatch_h__
-#define __dispatch_dispatch_h__ 1
-/*
- * 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.
- */
-
-/**
- * \defgroup General Dispatch Definitions
- * @{
- */
-
-typedef struct dx_dispatch_t dx_dispatch_t;
-
-/**
- * \brief Initialize the Dispatch library and prepare it for operation.
- *
- * #param config_path The path to the configuration file.
- * @return A handle to be used in API calls for this instance.
- */
-dx_dispatch_t *dx_dispatch(const char *config_path);
-
-
-/**
- * \brief Finalize the Dispatch library after it has stopped running.
- *
- * @param dispatch The dispatch handle returned by dx_dispatch
- */
-void dx_dispatch_free(dx_dispatch_t *dispatch);
-
-void dx_dispatch_configure(dx_dispatch_t *dispatch);
-
-
-/**
- * @}
- */
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/error.h b/extras/dispatch/include/qpid/dispatch/error.h
deleted file mode 100644
index a62f80fde4..0000000000
--- a/extras/dispatch/include/qpid/dispatch/error.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef __dispatch_error_h__
-#define __dispatch_error_h__ 1
-/*
- * 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.
- */
-
-typedef enum {
- DX_ERROR_NONE = 0,
- DX_ERROR_NOT_FOUND,
- DX_ERROR_ALREADY_EXISTS,
- DX_ERROR_ALLOC
-} dx_error_t;
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/hash.h b/extras/dispatch/include/qpid/dispatch/hash.h
deleted file mode 100644
index 4f079f6993..0000000000
--- a/extras/dispatch/include/qpid/dispatch/hash.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __dispatch_hash_h__
-#define __dispatch_hash_h__ 1
-/*
- * 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 <stdlib.h>
-#include <qpid/dispatch/iterator.h>
-#include <qpid/dispatch/error.h>
-
-typedef struct dx_hash_t dx_hash_t;
-typedef struct dx_hash_handle_t dx_hash_handle_t;
-
-dx_hash_t *dx_hash(int bucket_exponent, int batch_size, int value_is_const);
-void dx_hash_free(dx_hash_t *h);
-
-size_t dx_hash_size(dx_hash_t *h);
-dx_error_t dx_hash_insert(dx_hash_t *h, dx_field_iterator_t *key, void *val, dx_hash_handle_t **handle);
-dx_error_t dx_hash_insert_const(dx_hash_t *h, dx_field_iterator_t *key, const void *val, dx_hash_handle_t **handle);
-dx_error_t dx_hash_retrieve(dx_hash_t *h, dx_field_iterator_t *key, void **val);
-dx_error_t dx_hash_retrieve_const(dx_hash_t *h, dx_field_iterator_t *key, const void **val);
-dx_error_t dx_hash_remove(dx_hash_t *h, dx_field_iterator_t *key);
-
-void dx_hash_handle_free(dx_hash_handle_t *handle);
-const unsigned char *dx_hash_key_by_handle(const dx_hash_handle_t *handle);
-dx_error_t dx_hash_remove_by_handle(dx_hash_t *h, dx_hash_handle_t *handle);
-dx_error_t dx_hash_remove_by_handle2(dx_hash_t *h, dx_hash_handle_t *handle, unsigned char **key);
-
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/iovec.h b/extras/dispatch/include/qpid/dispatch/iovec.h
deleted file mode 100644
index 5b56c638ff..0000000000
--- a/extras/dispatch/include/qpid/dispatch/iovec.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef __dispatch_iovec_h__
-#define __dispatch_iovec_h__ 1
-/*
- * 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 <sys/uio.h>
-
-typedef struct dx_iovec_t dx_iovec_t;
-
-dx_iovec_t *dx_iovec(int vector_count);
-void dx_iovec_free(dx_iovec_t *iov);
-struct iovec *dx_iovec_array(dx_iovec_t *iov);
-int dx_iovec_count(dx_iovec_t *iov);
-
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/iterator.h b/extras/dispatch/include/qpid/dispatch/iterator.h
deleted file mode 100644
index e31e67e6fd..0000000000
--- a/extras/dispatch/include/qpid/dispatch/iterator.h
+++ /dev/null
@@ -1,197 +0,0 @@
-#ifndef __dispatch_iterator_h__
-#define __dispatch_iterator_h__ 1
-/*
- * 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 <stdint.h>
-#include <qpid/dispatch/buffer.h>
-#include <qpid/dispatch/iovec.h>
-
-/**
- * The field iterator is used to access fields within a buffer chain.
- * It shields the user from the fact that the field may be split across
- * one or more physical buffers.
- */
-typedef struct dx_field_iterator_t dx_field_iterator_t;
-
-/**
- * Iterator views allow the code traversing the field to see a transformed
- * view of the raw field.
- *
- * ITER_VIEW_ALL - No transformation of the raw field data
- *
- * ITER_VIEW_NO_HOST - Remove the scheme and host fields from the view
- *
- * amqp://host.domain.com:port/node-id/node/specific
- * ^^^^^^^^^^^^^^^^^^^^^
- * node-id/node/specific
- * ^^^^^^^^^^^^^^^^^^^^^
- *
- * ITER_VIEW_NODE_ID - Isolate the node identifier from an address
- *
- * amqp://host.domain.com:port/node-id/node/specific
- * ^^^^^^^
- * node-id/node/specific
- * ^^^^^^^
- *
- * ITER_VIEW_NODE_SPECIFIC - Isolate node-specific text from an address
- *
- * amqp://host.domain.com:port/node-id/node/specific
- * ^^^^^^^^^^^^^
- * node-id/node/specific
- * ^^^^^^^^^^^^^
- *
- * ITER_VIEW_ADDRESS_HASH - Isolate the hashable part of the address depending on address syntax
- *
- * amqp:/_local/<local>
- * L^^^^^^^
- * amqp:/_topo/<area>/<router>/<local>
- * A^^^^^^
- * amqp:/_topo/<my-area>/<router>/<local>
- * R^^^^^^^^
- * amqp:/_topo/<my_area>/<my-router>/<local>
- * L^^^^^^^
- * amqp:/_topo/<area>/all/<local>
- * A^^^^^^
- * amqp:/_topo/<my-area>/all/<local>
- * L^^^^^^^
- * amqp:/_topo/all/all/<local>
- * L^^^^^^^
- * amqp:/<mobile>
- * M^^^^^^^^
- *
- * ITER_VIEW_NODE_HASH - Isolate the hashable part of a router-id, used for headers
- *
- * <area>/<router>
- * A^^^^^^
- *
- * <my_area>/<router>
- * R^^^^^^^^
- *
- */
-typedef enum {
- ITER_VIEW_ALL,
- ITER_VIEW_NO_HOST,
- ITER_VIEW_NODE_ID,
- ITER_VIEW_NODE_SPECIFIC,
- ITER_VIEW_ADDRESS_HASH,
- ITER_VIEW_NODE_HASH
-} dx_iterator_view_t;
-
-
-/**
- * Set the area and router names for the local router. These are used to match
- * my-area and my-router in address fields.
- */
-void dx_field_iterator_set_address(const char *area, const char *router);
-
-/**
- * Create an iterator from a null-terminated string.
- *
- * The "text" string must stay intact for the whole life of the iterator. The iterator
- * does not copy the string, it references it.
- */
-dx_field_iterator_t* dx_field_iterator_string(const char *text,
- dx_iterator_view_t view);
-
-dx_field_iterator_t* dx_field_iterator_binary(const char *text,
- int length,
- dx_iterator_view_t view);
-
-
-/**
- * Create an iterator from a field in a buffer chain
- */
-dx_field_iterator_t *dx_field_iterator_buffer(dx_buffer_t *buffer,
- int offset,
- int length,
- dx_iterator_view_t view);
-
-/**
- * Free an iterator
- */
-void dx_field_iterator_free(dx_field_iterator_t *iter);
-
-/**
- * Reset the iterator to the first octet and set a new view
- */
-void dx_field_iterator_reset(dx_field_iterator_t *iter);
-
-void dx_field_iterator_reset_view(dx_field_iterator_t *iter,
- dx_iterator_view_t view);
-
-/**
- * Return the current octet in the iterator's view and step to the next.
- */
-unsigned char dx_field_iterator_octet(dx_field_iterator_t *iter);
-
-/**
- * Return true iff the iterator has no more octets in the view.
- */
-int dx_field_iterator_end(dx_field_iterator_t *iter);
-
-/**
- * Return a sub-iterator that equals the supplied iterator except that it
- * starts at the supplied iterator's current position.
- */
-dx_field_iterator_t *dx_field_iterator_sub(dx_field_iterator_t *iter, uint32_t length);
-
-void dx_field_iterator_advance(dx_field_iterator_t *iter, uint32_t length);
-
-/**
- * Return the remaining length (in octets) for the iterator.
- *
- * IMPORTANT: This function returns the limit of the remaining length.
- * The actual length *may* be less than indicated, but will
- * never be more. This function is safe for allocating memory.
- *
- * @param iter A field iterator
- * @return The number of octets remaining in the view (or more)
- */
-uint32_t dx_field_iterator_remaining(dx_field_iterator_t *iter);
-
-/**
- * Compare an input string to the iterator's view. Return true iff they are equal.
- */
-int dx_field_iterator_equal(dx_field_iterator_t *iter, const unsigned char *string);
-
-/**
- * Return true iff the string matches the characters at the current location in the view.
- * This function ignores octets beyond the length of the prefix.
- * This function does not alter the position of the iterator if the prefix does not match,
- * if it matches, the prefix is consumed.
- */
-int dx_field_iterator_prefix(dx_field_iterator_t *iter, const char *prefix);
-
-/**
- * Return a copy of the iterator's view.
- */
-unsigned char *dx_field_iterator_copy(dx_field_iterator_t *iter);
-
-/**
- * Return the contents of this iter into an iovec structure. This is used in a
- * scatter/gather IO mechanism. If the iterator spans multiple physical buffers,
- * the iovec structure will contain one pointer per buffer.
- *
- * @param iter A field iterator
- * @return An iovec structure that references the data in the iterator's buffers.
- */
-dx_iovec_t *dx_field_iterator_iovec(const dx_field_iterator_t *iter);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/log.h b/extras/dispatch/include/qpid/dispatch/log.h
deleted file mode 100644
index 4b69733280..0000000000
--- a/extras/dispatch/include/qpid/dispatch/log.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef __dispatch_log_h__
-#define __dispatch_log_h__ 1
-/*
- * 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.
- */
-
-#define LOG_NONE 0x00000000
-#define LOG_TRACE 0x00000001
-#define LOG_DEBUG 0x00000002
-#define LOG_INFO 0x00000004
-#define LOG_NOTICE 0x00000008
-#define LOG_WARNING 0x00000010
-#define LOG_ERROR 0x00000020
-#define LOG_CRITICAL 0x00000040
-
-void dx_log_impl(const char *module, int cls, const char *file, int line, const char *fmt, ...);
-#define dx_log(m, c, f, ...) dx_log_impl(m, c, __FILE__, __LINE__, f , ##__VA_ARGS__)
-
-void dx_log_set_mask(int mask);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/message.h b/extras/dispatch/include/qpid/dispatch/message.h
deleted file mode 100644
index 8702e509b3..0000000000
--- a/extras/dispatch/include/qpid/dispatch/message.h
+++ /dev/null
@@ -1,188 +0,0 @@
-#ifndef __dispatch_message_h__
-#define __dispatch_message_h__ 1
-/*
- * 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/dispatch/ctools.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/iterator.h>
-#include <qpid/dispatch/buffer.h>
-#include <qpid/dispatch/compose.h>
-#include <qpid/dispatch/parse.h>
-#include <qpid/dispatch/container.h>
-
-// Callback for status change (confirmed persistent, loaded-in-memory, etc.)
-
-typedef struct dx_message_t dx_message_t;
-
-DEQ_DECLARE(dx_message_t, dx_message_list_t);
-
-struct dx_message_t {
- DEQ_LINKS(dx_message_t);
- // Private members not listed here.
-};
-
-typedef enum {
- DX_DEPTH_NONE,
- DX_DEPTH_HEADER,
- DX_DEPTH_DELIVERY_ANNOTATIONS,
- DX_DEPTH_MESSAGE_ANNOTATIONS,
- DX_DEPTH_PROPERTIES,
- DX_DEPTH_APPLICATION_PROPERTIES,
- DX_DEPTH_BODY,
- DX_DEPTH_ALL
-} dx_message_depth_t;
-
-
-typedef enum {
- //
- // Message Sections
- //
- DX_FIELD_HEADER,
- DX_FIELD_DELIVERY_ANNOTATION,
- DX_FIELD_MESSAGE_ANNOTATION,
- DX_FIELD_PROPERTIES,
- DX_FIELD_APPLICATION_PROPERTIES,
- DX_FIELD_BODY,
- DX_FIELD_FOOTER,
-
- //
- // Fields of the Header Section
- //
- DX_FIELD_DURABLE,
- DX_FIELD_PRIORITY,
- DX_FIELD_TTL,
- DX_FIELD_FIRST_ACQUIRER,
- DX_FIELD_DELIVERY_COUNT,
-
- //
- // Fields of the Properties Section
- //
- DX_FIELD_MESSAGE_ID,
- DX_FIELD_USER_ID,
- DX_FIELD_TO,
- DX_FIELD_SUBJECT,
- DX_FIELD_REPLY_TO,
- DX_FIELD_CORRELATION_ID,
- DX_FIELD_CONTENT_TYPE,
- DX_FIELD_CONTENT_ENCODING,
- DX_FIELD_ABSOLUTE_EXPIRY_TIME,
- DX_FIELD_CREATION_TIME,
- DX_FIELD_GROUP_ID,
- DX_FIELD_GROUP_SEQUENCE,
- DX_FIELD_REPLY_TO_GROUP_ID
-} dx_message_field_t;
-
-
-/**
- * Allocate a new message.
- *
- * @return A pointer to a dx_message_t that is the sole reference to a newly allocated
- * message.
- */
-dx_message_t *dx_message(void);
-
-/**
- * Free a message reference. If this is the last reference to the message, free the
- * message as well.
- *
- * @param msg A pointer to a dx_message_t that is no longer needed.
- */
-void dx_message_free(dx_message_t *msg);
-
-/**
- * Make a new reference to an existing message.
- *
- * @param msg A pointer to a dx_message_t referencing a message.
- * @return A new pointer to the same referenced message.
- */
-dx_message_t *dx_message_copy(dx_message_t *msg);
-
-/**
- * Retrieve the delivery annotations from a message.
- *
- * IMPORTANT: The pointer returned by this function remains owned by the message.
- * The caller MUST NOT free the parsed field.
- *
- * @param msg Pointer to a received message.
- * @return Pointer to the parsed field for the delivery annotations. If the message doesn't
- * have delivery annotations, the return value shall be NULL.
- */
-dx_parsed_field_t *dx_message_delivery_annotations(dx_message_t *msg);
-
-/**
- * Set the delivery annotations for the message. If the message already has delivery annotations,
- * they will be overwritten/replaced by the new field.
- *
- * @param msg Pointer to a receiver message.
- * @param da Pointer to a composed field representing the new delivery annotations of the message.
- * If null, the message will not have a delivery annotations field.
- * IMPORTANT: The message will not take ownership of the composed field. The
- * caller is responsible for freeing it after this call. Since the contents
- * are copied into the message, it is safe to free the composed field
- * any time after the call to this function.
- */
-void dx_message_set_delivery_annotations(dx_message_t *msg, dx_composed_field_t *da);
-
-/**
- * Receive message data via a delivery. This function may be called more than once on the same
- * delivery if the message spans multiple frames. Once a complete message has been received, this
- * function shall return the message.
- *
- * @param delivery An incoming delivery from a link
- * @return A pointer to the complete message or 0 if the message is not yet complete.
- */
-dx_message_t *dx_message_receive(dx_delivery_t *delivery);
-
-/**
- * Send the message outbound on an outgoing link.
- *
- * @param msg A pointer to a message to be sent.
- * @param link The outgoing link on which to send the message.
- */
-void dx_message_send(dx_message_t *msg, dx_link_t *link);
-
-/**
- * Check that the message is well-formed up to a certain depth. Any part of the message that is
- * beyond the specified depth is not checked for validity.
- */
-int dx_message_check(dx_message_t *msg, dx_message_depth_t depth);
-
-/**
- * Return an iterator for the requested message field. If the field is not in the message,
- * return NULL.
- *
- * @param msg A pointer to a message.
- * @param field The field to be returned via iterator.
- * @return A field iterator that spans the requested field.
- */
-dx_field_iterator_t *dx_message_field_iterator(dx_message_t *msg, dx_message_field_t field);
-
-ssize_t dx_message_field_length(dx_message_t *msg, dx_message_field_t field);
-ssize_t dx_message_field_copy(dx_message_t *msg, dx_message_field_t field, void *buffer);
-
-//
-// Functions for composed messages
-//
-
-// Convenience Functions
-void dx_message_compose_1(dx_message_t *msg, const char *to, dx_buffer_list_t *buffers);
-void dx_message_compose_2(dx_message_t *msg, dx_composed_field_t *content);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/parse.h b/extras/dispatch/include/qpid/dispatch/parse.h
deleted file mode 100644
index 087a440c4e..0000000000
--- a/extras/dispatch/include/qpid/dispatch/parse.h
+++ /dev/null
@@ -1,195 +0,0 @@
-#ifndef __dispatch_parse_h__
-#define __dispatch_parse_h__ 1
-/*
- * 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/dispatch/buffer.h>
-#include <qpid/dispatch/iterator.h>
-
-typedef struct dx_parsed_field_t dx_parsed_field_t;
-
-/**
- * Parse a field delimited by a field iterator.
- *
- * @param iter Field iterator for the field being parsed
- * @return A pointer to the newly created field.
- */
-dx_parsed_field_t *dx_parse(dx_field_iterator_t *iter);
-
-/**
- * Free the resources associated with a parsed field.
- *
- * @param A field pointer returned by dx_parse.
- */
-void dx_parse_free(dx_parsed_field_t *field);
-
-/**
- * Check to see if the field parse was successful (i.e. the field was
- * well-formed).
- *
- * @param field The field pointer returned by dx_parse.
- * @return true iff the field was well-formed and successfully parsed.
- */
-int dx_parse_ok(dx_parsed_field_t *field);
-
-/**
- * Return the text of the error describing the parse error if the field
- * is not well-formed.
- *
- * @param field The field pointer returned by dx_parse.
- * @return a null-terminated string describing the parse failure.
- */
-const char *dx_parse_error(dx_parsed_field_t *field);
-
-/**
- * Return the AMQP tag for the parsed (and well-formed) field.
- *
- * @param field The field pointer returned by dx_parse.
- * @return The tag (see amqp.h) that indicates the type of the field.
- */
-uint8_t dx_parse_tag(dx_parsed_field_t *field);
-
-/**
- * Return an iterator for the raw content of the field. This is useful
- * only for scalar fields. It is not appropriate for compound fields.
- * For compound fields, use the sub-field functions instead.
- *
- * The returned iterator describes the raw content of the field, and can be
- * used for comparison, indexing, or copying.
- *
- * IMPORTANT: The returned iterator is owned by the field and *must not* be
- * freed by the caller of this function.
- *
- * @param field The field pointer returned by dx_parse.
- * @return A field iterator that describes the field's raw content.
- */
-dx_field_iterator_t *dx_parse_raw(dx_parsed_field_t *field);
-
-/**
- * Return the raw content as an unsigned integer up to 32-bits. This is
- * valid only for scalar fields of a fixed size of 4-octets or fewer.
- *
- * @param field The field pointer returned by dx_parse.
- * @return The raw content of the field cast as a uint32_t.
- */
-uint32_t dx_parse_as_uint(dx_parsed_field_t *field);
-
-/**
- * Return the raw content as an unsigned integer up to 64-bits. This is
- * valid only for scalar fields of a fixed size of 8-octets or fewer.
- *
- * @param field The field pointer returned by dx_parse.
- * @return The raw content of the field cast as a uint64_t.
- */
-uint64_t dx_parse_as_ulong(dx_parsed_field_t *field);
-
-/**
- * Return the raw content as a signed integer up to 32-bits. This is
- * valid only for scalar fields of a fixed size of 4-octets or fewer.
- *
- * @param field The field pointer returned by dx_parse.
- * @return The raw content of the field cast as an int32_t.
- */
-int32_t dx_parse_as_int(dx_parsed_field_t *field);
-
-/**
- * Return the raw content as a signed integer up to 64-bits. This is
- * valid only for scalar fields of a fixed size of 8-octets or fewer.
- *
- * @param field The field pointer returned by dx_parse.
- * @return The raw content of the field cast as an int64_t.
- */
-int64_t dx_parse_as_long(dx_parsed_field_t *field);
-
-/**
- * Return the number of sub-field in a compound field. If the field is
- * a list or array, this is the number of items in the list/array. If
- * the field is a map, this is the number of key/value pairs in the map
- * (i.e. half the number of actual sub-field in the map).
- *
- * For scalar fields, this function will return zero.
- *
- * @param field The field pointer returned by dx_parse.
- * @return The number of sub-fields in the field.
- */
-uint32_t dx_parse_sub_count(dx_parsed_field_t *field);
-
-/**
- * Return a dx_parsed_field_t for the idx'th key in a map field.
- * If 'field' is not a map, or idx is equal-to or greater-than the number
- * of sub-fields in field, this function will return NULL.
- *
- * IMPORTANT: The pointer returned by this function remains owned by the
- * parent field. It *must not* be freed by the caller.
- *
- * @param field The field pointer returned by dx_parse.
- * @param idx The index of the desired sub-field (in range 0..sub_count)
- * @return A pointer to the parsed sub-field
- */
-dx_parsed_field_t *dx_parse_sub_key(dx_parsed_field_t *field, uint32_t idx);
-
-/**
- * Return a dx_parsed_field_t for the idx'th value in a compound field.
- * If idx is equal-to or greater-than the number of sub-fields in field,
- * this function will return NULL.
- *
- * IMPORTANT: The pointer returned by this function remains owned by the
- * parent field. It *must not* be freed by the caller.
- *
- * @param field The field pointer returned by dx_parse.
- * @param idx The index of the desired sub-field (in range 0..sub_count)
- * @return A pointer to the parsed sub-field
- */
-dx_parsed_field_t *dx_parse_sub_value(dx_parsed_field_t *field, uint32_t idx);
-
-/**
- * Convenience Function - Return true iff the field is a map.
- *
- * @param field The field pointer returned by dx_parse[_sub_{value,key}]
- * @return non-zero if the condition is mat.
- */
-int dx_parse_is_map(dx_parsed_field_t *field);
-
-/**
- * Convenience Function - Return true iff the field is a list.
- *
- * @param field The field pointer returned by dx_parse[_sub_{value,key}]
- * @return non-zero if the condition is mat.
- */
-int dx_parse_is_list(dx_parsed_field_t *field);
-
-/**
- * Convenience Function - Return true iff the field is a scalar type.
- *
- * @param field The field pointer returned by dx_parse[_sub_{value,key}]
- * @return non-zero if the condition is mat.
- */
-int dx_parse_is_scalar(dx_parsed_field_t *field);
-
-/**
- * Convenience Function - Return the value for a key in a map.
- *
- * @param field The field pointer returned by dx_parse[_sub_{value,key}]
- * @param key The key to search for in the map.
- * @return The value field corresponding to the key or NULL.
- */
-dx_parsed_field_t *dx_parse_value_by_key(dx_parsed_field_t *field, const char *key);
-
-#endif
-
diff --git a/extras/dispatch/include/qpid/dispatch/python_embedded.h b/extras/dispatch/include/qpid/dispatch/python_embedded.h
deleted file mode 100644
index aad0453c24..0000000000
--- a/extras/dispatch/include/qpid/dispatch/python_embedded.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef __python_embedded_h__
-#define __python_embedded_h__ 1
-/*
- * 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 <Python.h>
-#include <qpid/dispatch/dispatch.h>
-#include <qpid/dispatch/compose.h>
-#include <qpid/dispatch/parse.h>
-#include <qpid/dispatch/iterator.h>
-
-/**
- * Initialize the embedded-python subsystem. This must be called before
- * any other call into this module is invoked.
- */
-void dx_python_initialize(dx_dispatch_t *dx);
-
-/**
- * Finalize the embedded-python subsystem. After this is called, there
- * must be no further invocation of dx_python methods.
- */
-void dx_python_finalize();
-
-/**
- * Start using embedded python. This is called once by each module that plans
- * to use embedded python capabilities. It must call dx_python_start before
- * using any python components.
- */
-void dx_python_start();
-
-/**
- * Stop using embedded python. This is called once by each module after it is
- * finished using embedded python capabilities.
- */
-void dx_python_stop();
-
-/**
- * Get the Python top level "dispatch" module.
- */
-PyObject *dx_python_module();
-
-/**
- * Convert a Python object to AMQP format and append to a composed_field.
- *
- * @param value A Python Object
- * @param field A composed field
- */
-void dx_py_to_composed(PyObject *value, dx_composed_field_t *field);
-
-/**
- * Convert a parsed field to a Python object
- *
- * @param field A parsed field
- * @return A generated Python object
- */
-PyObject *dx_field_to_py(dx_parsed_field_t *field);
-
-/**
- * These are temporary and will eventually be replaced by having an internal python
- * work queue that feeds a dedicated embedded-python thread.
- */
-void dx_python_lock();
-void dx_python_unlock();
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/router.h b/extras/dispatch/include/qpid/dispatch/router.h
deleted file mode 100644
index 82978dd440..0000000000
--- a/extras/dispatch/include/qpid/dispatch/router.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef __dispatch_router_h__
-#define __dispatch_router_h__ 1
-/*
- * 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/dispatch/dispatch.h>
-#include <qpid/dispatch/message.h>
-#include <qpid/dispatch/iterator.h>
-#include <stdbool.h>
-
-typedef struct dx_address_t dx_address_t;
-
-
-typedef void (*dx_router_message_cb)(void *context, dx_message_t *msg, int link_id);
-
-const char *dx_router_id(const dx_dispatch_t *dx);
-
-dx_address_t *dx_router_register_address(dx_dispatch_t *dx,
- const char *address,
- dx_router_message_cb handler,
- void *context);
-
-void dx_router_unregister_address(dx_address_t *address);
-
-
-void dx_router_send(dx_dispatch_t *dx,
- dx_field_iterator_t *address,
- dx_message_t *msg);
-
-void dx_router_send2(dx_dispatch_t *dx,
- const char *address,
- dx_message_t *msg);
-
-void dx_router_build_node_list(dx_dispatch_t *dx, dx_composed_field_t *field);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/server.h b/extras/dispatch/include/qpid/dispatch/server.h
deleted file mode 100644
index e50f9ac75b..0000000000
--- a/extras/dispatch/include/qpid/dispatch/server.h
+++ /dev/null
@@ -1,459 +0,0 @@
-#ifndef __dispatch_server_h__
-#define __dispatch_server_h__ 1
-/*
- * 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/dispatch/dispatch.h>
-#include <proton/engine.h>
-
-/**
- * \defgroup Control Server Control Functions
- * @{
- */
-
-/**
- * \brief Thread Start Handler
- *
- * Callback invoked when a new server thread is started. The callback is
- * invoked on the newly created thread.
- *
- * This handler can be used to set processor affinity or other thread-specific
- * tuning values.
- *
- * @param context The handler context supplied in dx_server_initialize.
- * @param thread_id The integer thread identifier that uniquely identifies this thread.
- */
-typedef void (*dx_thread_start_cb_t)(void* context, int thread_id);
-
-
-/**
- * \brief Set the optional thread-start handler.
- *
- * This handler is called once on each worker thread at the time the thread is
- * started. This may be used to set tuning settings like processor affinity,
- * etc.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- * @param start_handler The thread-start handler invoked per thread on thread startup.
- * @param context Opaque context to be passed back in the callback function.
- */
-void dx_server_set_start_handler(dx_dispatch_t *dx, dx_thread_start_cb_t start_handler, void *context);
-
-
-/**
- * \brief Run the server threads until completion - The blocking version.
- *
- * Start the operation of the server, including launching all of the worker
- * threads. This function does not return until after the server has been
- * stopped. The thread that calls dx_server_run is used as one of the worker
- * threads.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- */
-void dx_server_run(dx_dispatch_t *dx);
-
-
-/**
- * \brief Start the server threads and return immediately - The non-blocking version.
- *
- * Start the operation of the server, including launching all of the worker
- * threads.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- */
-void dx_server_start(dx_dispatch_t *dx);
-
-
-/**
- * \brief Stop the server
- *
- * Stop the server and join all of its worker threads. This function may be
- * called from any thread. When this function returns, all of the other
- * server threads have been closed and joined. The calling thread will be the
- * only running thread in the process.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- */
-void dx_server_stop(dx_dispatch_t *dx);
-
-
-/**
- * \brief Pause (quiesce) the server.
- *
- * This call blocks until all of the worker threads (except the one calling
- * this function) are finished processing and have been blocked. When this
- * call returns, the calling thread is the only thread running in the process.
- *
- * If the calling process is *not* one of the server's worker threads, then
- * this function will block all of the worker threads before returning.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- */
-void dx_server_pause(dx_dispatch_t *dx);
-
-
-/**
- * \brief Resume normal operation of a paused server.
- *
- * This call unblocks all of the worker threads so they can resume normal
- * connection processing.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- */
-void dx_server_resume(dx_dispatch_t *dx);
-
-
-/**
- * @}
- * \defgroup Signal Server Signal Handling Functions
- * @{
- */
-
-
-/**
- * \brief Signal Handler
- *
- * Callback for signal handling. This handler will be invoked on one of the
- * worker threads in an orderly fashion. This callback is triggered by a call
- * to dx_server_signal.
- *
- * @param context The handler context supplied in dx_server_initialize.
- * @param signum The signal number that was passed into dx_server_signal.
- */
-typedef void (*dx_signal_handler_cb_t)(void* context, int signum);
-
-
-/**
- * Set the signal handler for the server. The signal handler is invoked
- * cleanly on a worker thread after a call is made to dx_server_signal. The
- * signal handler is optional and need not be set.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- * @param signal_handler The signal handler called when a registered signal is caught.
- * @param context Opaque context to be passed back in the callback function.
- */
-void dx_server_set_signal_handler(dx_dispatch_t *dx, dx_signal_handler_cb_t signal_handler, void *context);
-
-
-/**
- * \brief Schedule the invocation of the Server's signal handler.
- *
- * This function is safe to call from any context, including an OS signal
- * handler or an Interrupt Service Routine. It schedules the orderly
- * invocation of the Server's signal handler on one of the worker threads.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- * @param signum The signal number... TODO
- */
-void dx_server_signal(dx_dispatch_t *dx, int signum);
-
-
-/**
- * @}
- * \defgroup Connection Server AMQP Connection Handling Functions
- * @{
- */
-
-/**
- * \brief Listener objects represent the desire to accept incoming transport connections.
- */
-typedef struct dx_listener_t dx_listener_t;
-
-/**
- * \brief Connector objects represent the desire to create and maintain an outgoing transport connection.
- */
-typedef struct dx_connector_t dx_connector_t;
-
-/**
- * \brief Connection objects wrap Proton connection objects.
- */
-typedef struct dx_connection_t dx_connection_t;
-
-/**
- * \brief Event type for the connection callback.
- */
-typedef enum {
- /// The connection just opened via a listener (inbound).
- DX_CONN_EVENT_LISTENER_OPEN,
-
- /// The connection just opened via a connector (outbound).
- DX_CONN_EVENT_CONNECTOR_OPEN,
-
- /// The connection was closed at the transport level (not cleanly).
- DX_CONN_EVENT_CLOSE,
-
- /// The connection requires processing.
- DX_CONN_EVENT_PROCESS
-} dx_conn_event_t;
-
-
-/**
- * \brief Configuration block for a connector or a listener.
- */
-typedef struct dx_server_config_t {
- /**
- * Host name or network address to bind to a listener or use in the connector.
- */
- const char *host;
-
- /**
- * Port name or number to bind to a listener or use in the connector.
- */
- const char *port;
-
- /**
- * Space-separated list of SASL mechanisms to be accepted for the connection.
- */
- const char *sasl_mechanisms;
-
- /**
- * If appropriate for the mechanism, the username for authentication
- * (connector only)
- */
- const char *sasl_username;
-
- /**
- * If appropriate for the mechanism, the password for authentication
- * (connector only)
- */
- const char *sasl_password;
-
- /**
- * If appropriate for the mechanism, the minimum acceptable security strength factor
- */
- int sasl_minssf;
-
- /**
- * If appropriate for the mechanism, the maximum acceptable security strength factor
- */
- int sasl_maxssf;
-
- /**
- * SSL is enabled for this connection iff non-zero.
- */
- int ssl_enabled;
-
- /**
- * Connection will take on the role of SSL server iff non-zero.
- */
- int ssl_server;
-
- /**
- * Iff non-zero AND ssl_enabled is non-zero, this listener will detect the client's use
- * of SSL or non-SSL and conform to the client's protocol.
- * (listener only)
- */
- int ssl_allow_unsecured_client;
-
- /**
- * Path to the file containing the PEM-formatted public certificate for the local end
- * of the connection.
- */
- const char *ssl_certificate_file;
-
- /**
- * Path to the file containing the PEM-formatted private key for the local end of the
- * connection.
- */
- const char *ssl_private_key_file;
-
- /**
- * The password used to sign the private key, or NULL if the key is not protected.
- */
- const char *ssl_password;
-
- /**
- * Path to the file containing the PEM-formatted set of certificates of trusted CAs.
- */
- const char *ssl_trusted_certificate_db;
-
- /**
- * Iff non-zero, require that the peer's certificate be supplied and that it be authentic
- * according to the set of trusted CAs.
- */
- int ssl_require_peer_authentication;
-
- /**
- * Allow the connection to be redirected by the peer (via CLOSE->Redirect). This is
- * meaningful for outgoing (connector) connections only.
- */
- int allow_redirect;
-
- /**
- * The specified role of the connection. This can be used to control the behavior and
- * capabilities of the connections.
- */
- const char *role;
-} dx_server_config_t;
-
-
-/**
- * \brief Connection Event Handler
- *
- * Callback invoked when processing is needed on a proton connection. This
- * callback shall be invoked on one of the server's worker threads. The
- * server guarantees that no two threads shall be allowed to process a single
- * connection concurrently. The implementation of this handler may assume
- * that it has exclusive access to the connection and its subservient
- * components (sessions, links, deliveries, etc.).
- *
- * @param handler_context The handler context supplied in dx_server_set_conn_handler.
- * @param conn_context The handler context supplied in dx_server_{connect,listen}.
- * @param event The event/reason for the invocation of the handler.
- * @param conn The connection that requires processing by the handler.
- * @return A value greater than zero if the handler did any proton processing for
- * the connection. If no work was done, zero is returned.
- */
-typedef int (*dx_conn_handler_cb_t)(void *handler_context, void* conn_context, dx_conn_event_t event, dx_connection_t *conn);
-
-
-/**
- * \brief Set the connection event handler callback.
- *
- * Set the connection handler callback for the server. This callback is
- * mandatory and must be set prior to the invocation of dx_server_run.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- * @param conn_hander The handler for processing connection-related events.
- */
-void dx_server_set_conn_handler(dx_dispatch_t *dx, dx_conn_handler_cb_t conn_handler, void *handler_context);
-
-
-/**
- * \brief Set the user context for a connection.
- *
- * @param conn Connection object supplied in DX_CONN_EVENT_{LISTENER,CONNETOR}_OPEN
- * @param context User context to be stored with the connection.
- */
-void dx_connection_set_context(dx_connection_t *conn, void *context);
-
-
-/**
- * \brief Get the user context from a connection.
- *
- * @param conn Connection object supplied in DX_CONN_EVENT_{LISTENER,CONNETOR}_OPEN
- * @return The user context stored with the connection.
- */
-void *dx_connection_get_context(dx_connection_t *conn);
-
-
-/**
- * \brief Set the link context for a connection.
- *
- * @param conn Connection object supplied in DX_CONN_EVENT_{LISTENER,CONNETOR}_OPEN
- * @param context Link context to be stored with the connection.
- */
-void dx_connection_set_link_context(dx_connection_t *conn, void *context);
-
-
-/**
- * \brief Get the link context from a connection.
- *
- * @param conn Connection object supplied in DX_CONN_EVENT_{LISTENER,CONNETOR}_OPEN
- * @return The link context stored with the connection.
- */
-void *dx_connection_get_link_context(dx_connection_t *conn);
-
-
-/**
- * \brief Activate a connection for output.
- *
- * This function is used to request that the server activate the indicated
- * connection. It is assumed that the connection is one that the caller does
- * not have permission to access (i.e. it may be owned by another thread
- * currently). An activated connection will, when writable, appear in the
- * internal work list and be invoked for processing by a worker thread.
- *
- * @param conn The connection over which the application wishes to send data
- */
-void dx_server_activate(dx_connection_t *conn);
-
-
-/**
- * \brief Get the wrapped proton-engine connection object.
- *
- * @param conn Connection object supplied in DX_CONN_EVENT_{LISTENER,CONNETOR}_OPEN
- * @return The proton connection object.
- */
-pn_connection_t *dx_connection_pn(dx_connection_t *conn);
-
-
-/**
- * \brief Get the configuration that was used in the setup of this connection.
- *
- * @param conn Connection object supplied in DX_CONN_EVENT_{LISTENER,CONNETOR}_OPEN
- * @return A pointer to the server configuration used in the establishment of this connection.
- */
-const dx_server_config_t *dx_connection_config(const dx_connection_t *conn);
-
-
-/**
- * \brief Create a listener for incoming connections.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- * @param config Pointer to a configuration block for this listener. This block will be
- * referenced by the server, not copied. The referenced record must remain
- * in-scope for the life of the listener.
- * @param context User context passed back in the connection handler.
- * @return A pointer to the new listener, or NULL in case of failure.
- */
-dx_listener_t *dx_server_listen(dx_dispatch_t *dx, const dx_server_config_t *config, void *context);
-
-
-/**
- * \brief Free the resources associated with a listener.
- *
- * @param li A listener pointer returned by dx_listen.
- */
-void dx_listener_free(dx_listener_t* li);
-
-
-/**
- * \brief Close a listener so it will accept no more connections.
- *
- * @param li A listener pointer returned by dx_listen.
- */
-void dx_listener_close(dx_listener_t* li);
-
-
-/**
- * \brief Create a connector for an outgoing connection.
- *
- * @param dx The dispatch handle returned by dx_dispatch.
- * @param config Pointer to a configuration block for this connector. This block will be
- * referenced by the server, not copied. The referenced record must remain
- * in-scope for the life of the connector..
- * @param context User context passed back in the connection handler.
- * @return A pointer to the new connector, or NULL in case of failure.
- */
-dx_connector_t *dx_server_connect(dx_dispatch_t *dx, const dx_server_config_t *config, void *context);
-
-
-/**
- * \brief Free the resources associated with a connector.
- *
- * @param ct A connector pointer returned by dx_connect.
- */
-void dx_connector_free(dx_connector_t* ct);
-
-/**
- * @}
- */
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/threading.h b/extras/dispatch/include/qpid/dispatch/threading.h
deleted file mode 100644
index f275fc0086..0000000000
--- a/extras/dispatch/include/qpid/dispatch/threading.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __sys_threading_h__
-#define __sys_threading_h__ 1
-/*
- * 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.
- */
-
-typedef struct sys_mutex_t sys_mutex_t;
-
-sys_mutex_t *sys_mutex(void);
-void sys_mutex_free(sys_mutex_t *mutex);
-void sys_mutex_lock(sys_mutex_t *mutex);
-void sys_mutex_unlock(sys_mutex_t *mutex);
-
-
-typedef struct sys_cond_t sys_cond_t;
-
-sys_cond_t *sys_cond(void);
-void sys_cond_free(sys_cond_t *cond);
-void sys_cond_wait(sys_cond_t *cond, sys_mutex_t *held_mutex);
-void sys_cond_signal(sys_cond_t *cond);
-void sys_cond_signal_all(sys_cond_t *cond);
-
-
-typedef struct sys_thread_t sys_thread_t;
-
-sys_thread_t *sys_thread(void *(*run_function) (void *), void *arg);
-void sys_thread_free(sys_thread_t *thread);
-void sys_thread_join(sys_thread_t *thread);
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/timer.h b/extras/dispatch/include/qpid/dispatch/timer.h
deleted file mode 100644
index 1e04351822..0000000000
--- a/extras/dispatch/include/qpid/dispatch/timer.h
+++ /dev/null
@@ -1,89 +0,0 @@
-#ifndef __dispatch_timer_h__
-#define __dispatch_timer_h__ 1
-/*
- * 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/dispatch/dispatch.h>
-#include <qpid/dispatch/server.h>
-
-/**
- * \defgroup Timer Server Timer Functions
- * @{
- */
-
-typedef struct dx_timer_t dx_timer_t;
-
-/**
- * Timer Callback
- *
- * Callback invoked after a timer's interval expires and the timer fires.
- *
- * @param context The context supplied in dx_timer
- */
-typedef void (*dx_timer_cb_t)(void* context);
-
-
-/**
- * Create a new timer object.
- *
- * @param cb The callback function to be invoked when the timer expires.
- * @param context An opaque, user-supplied context to be passed into the callback.
- * @return A pointer to the new timer object or NULL if memory is exhausted.
- */
-dx_timer_t *dx_timer(dx_dispatch_t *dx, dx_timer_cb_t cb, void* context);
-
-
-/**
- * Free the resources for a timer object. If the timer was scheduled, it will be canceled
- * prior to freeing. After this function returns, the callback will not be invoked for this
- * timer.
- *
- * @param timer Pointer to the timer object returned by dx_timer.
- */
-void dx_timer_free(dx_timer_t *timer);
-
-
-/**
- * Schedule a timer to fire in the future.
- *
- * Note that the timer callback will never be invoked synchronously during the execution
- * of dx_timer_schedule. Even if the interval is immediate (0), the callback invocation will
- * be asynchronous and after the return of this function.
- *
- * @param timer Pointer to the timer object returned by dx_timer.
- * @param msec The minimum number of milliseconds of delay until the timer fires.
- * If 0 is supplied, the timer will be scheduled to fire immediately.
- */
-void dx_timer_schedule(dx_timer_t *timer, long msec);
-
-
-/**
- * Attempt to cancel a scheduled timer. Since the timer callback can be invoked on any
- * server thread, it is always possible that a last-second cancel attempt may arrive too late
- * to stop the timer from firing (i.e. the cancel is concurrent with the fire callback).
- *
- * @param timer Pointer to the timer object returned by dx_timer.
- */
-void dx_timer_cancel(dx_timer_t *timer);
-
-/**
- * @}
- */
-
-#endif
diff --git a/extras/dispatch/include/qpid/dispatch/user_fd.h b/extras/dispatch/include/qpid/dispatch/user_fd.h
deleted file mode 100644
index 2cd9627bd3..0000000000
--- a/extras/dispatch/include/qpid/dispatch/user_fd.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef __dispatch_user_fd_h__
-#define __dispatch_user_fd_h__ 1
-/*
- * 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/dispatch/dispatch.h>
-#include <qpid/dispatch/server.h>
-
-/**
- * \defgroup UserFd Server User-File-Descriptor Functions
- * @{
- */
-
-typedef struct dx_user_fd_t dx_user_fd_t;
-
-
-/**
- * User_fd Handler
- *
- * Callback invoked when a user-managed file descriptor is available for reading or writing or there
- * was an error on the file descriptor.
- *
- * @param context The handler context supplied in the dx_user_fd call.
- * @param ufd The user_fd handle for the processable fd.
- */
-typedef void (*dx_user_fd_handler_cb_t)(void* context, dx_user_fd_t *ufd);
-
-
-/**
- * Set the user-fd handler callback for the server. This handler is optional, but must be supplied
- * if the dx_server is used to manage the activation of user file descriptors.
- */
-void dx_server_set_user_fd_handler(dx_dispatch_t *dx, dx_user_fd_handler_cb_t ufd_handler);
-
-
-/**
- * Create a tracker for a user-managed file descriptor.
- *
- * A user-fd is appropriate for use when the application opens and manages file descriptors
- * for purposes other than AMQP communication. Registering a user fd with the dispatch server
- * controls processing of the FD alongside the FDs used for messaging.
- *
- * @param fd The open file descriptor being managed by the application.
- * @param context User context passed back in the connection handler.
- * @return A pointer to the new user_fd.
- */
-dx_user_fd_t *dx_user_fd(dx_dispatch_t *dx, int fd, void *context);
-
-
-/**
- * Free the resources for a user-managed FD tracker.
- *
- * @param ufd Structure pointer returned by dx_user_fd.
- */
-void dx_user_fd_free(dx_user_fd_t *ufd);
-
-
-/**
- * Activate a user-fd for read.
- *
- * Use this activation when the application has capacity to receive data from the user-fd. This will
- * cause the callback set in dx_server_set_user_fd_handler to later be invoked when the
- * file descriptor has data to read.
- *
- * @param ufd Structure pointer returned by dx_user_fd.
- */
-void dx_user_fd_activate_read(dx_user_fd_t *ufd);
-
-
-/**
- * Activate a user-fd for write.
- *
- * Use this activation when the application has data to write via the user-fd. This will
- * cause the callback set in dx_server_set_user_fd_handler to later be invoked when the
- * file descriptor is writable.
- *
- * @param ufd Structure pointer returned by dx_user_fd.
- */
-void dx_user_fd_activate_write(dx_user_fd_t *ufd);
-
-
-/**
- * Check readable status of a user-fd
- *
- * Note: It is possible that readable status is spurious (i.e. this function returns true
- * but the file-descriptor is not readable and will block if not set to O_NONBLOCK).
- * Code accordingly.
- *
- * @param ufd Structure pointer returned by dx_user_fd.
- * @return true iff the user file descriptor is readable.
- */
-bool dx_user_fd_is_readable(dx_user_fd_t *ufd);
-
-
-/**
- * Check writable status of a user-fd
- *
- * @param ufd Structure pointer returned by dx_user_fd.
- * @return true iff the user file descriptor is writable.
- */
-bool dx_user_fd_is_writeable(dx_user_fd_t *ufd);
-
-/**
- * @}
- */
-
-#endif
diff --git a/extras/dispatch/python/qpid/__init__.py b/extras/dispatch/python/qpid/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/extras/dispatch/python/qpid/__init__.py
+++ /dev/null
diff --git a/extras/dispatch/python/qpid/dispatch/__init__.py b/extras/dispatch/python/qpid/dispatch/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/extras/dispatch/python/qpid/dispatch/__init__.py
+++ /dev/null
diff --git a/extras/dispatch/python/qpid/dispatch/config/__init__.py b/extras/dispatch/python/qpid/dispatch/config/__init__.py
deleted file mode 100644
index 36121bb015..0000000000
--- a/extras/dispatch/python/qpid/dispatch/config/__init__.py
+++ /dev/null
@@ -1,20 +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.
-#
-
-from parser import DXConfig
diff --git a/extras/dispatch/python/qpid/dispatch/config/parser.py b/extras/dispatch/python/qpid/dispatch/config/parser.py
deleted file mode 100644
index a809c78692..0000000000
--- a/extras/dispatch/python/qpid/dispatch/config/parser.py
+++ /dev/null
@@ -1,333 +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 json
-from schema import config_schema
-from dispatch import LogAdapter, LOG_TRACE, LOG_ERROR, LOG_INFO
-
-class Section:
- """
- """
-
- def __init__(self, name, kv_pairs, schema_section):
- self.name = name
- self.schema_section = schema_section
- self.values = schema_section.check_and_default(kv_pairs)
- self.index = schema_section.index_of(kv_pairs)
-
- def __repr__(self):
- return "%r" % self.values
-
-
-class ConfigMain:
- """
- """
-
- def __init__(self, schema):
- self.sections_by_name = {}
- self.sections_by_index = {}
- self.schema = schema
-
-
- def update(self, raw_config):
- for sec_map in raw_config:
- name = sec_map.keys()[0]
- kv = sec_map[name]
- schema_section = self.schema.sections[name]
- sec = Section(name, kv, schema_section)
- if name not in self.sections_by_name:
- self.sections_by_name[name] = []
- self.sections_by_name[name].append(sec)
- self.sections_by_index[sec.index] = sec
- self._expand_references()
-
-
- def item_count(self, name):
- if name in self.sections_by_name:
- return len(self.sections_by_name[name])
- return 0
-
-
- def get_value(self, name, idx, key):
- if name in self.sections_by_name:
- sec = self.sections_by_name[name]
- if idx <= len(sec):
- if key in sec[idx].values:
- return sec[idx].values[key]
- return None
-
-
- def _expand_references(self):
- for name, sec_list in self.sections_by_name.items():
- for sec in sec_list:
- for k,v in sec.values.items():
- if sec.schema_section.is_expandable(k):
- ref_name = "%s:%s" % (k, v)
- if ref_name in self.sections_by_index:
- ref_section = self.sections_by_index[ref_name]
- for ek,ev in ref_section.values.items():
- if ref_section.schema_section.expand_copy(ek):
- sec.values[ek] = ev
-
-
-SECTION_SINGLETON = 0
-SECTION_VALUES = 1
-
-VALUE_TYPE = 0
-VALUE_INDEX = 1
-VALUE_FLAGS = 2
-VALUE_DEFAULT = 3
-
-
-class SchemaSection:
- """
- """
-
- def __init__(self, name, section_tuple):
- self.name = name
- self.singleton = section_tuple[SECTION_SINGLETON]
- self.values = section_tuple[SECTION_VALUES]
- self.index_keys = []
- finding_index = True
- index_ord = 0
- while finding_index:
- finding_index = False
- for k,v in self.values.items():
- if v[VALUE_INDEX] == index_ord:
- self.index_keys.append(k)
- index_ord += 1
- finding_index = True
-
-
- def is_mandatory(self, key):
- return self.values[key][VALUE_FLAGS].find('M') >= 0
-
-
- def is_expandable(self, key):
- return self.values[key][VALUE_FLAGS].find('E') >= 0
-
-
- def expand_copy(self, key):
- return self.values[key][VALUE_FLAGS].find('S') >= 0
-
-
- def default_value(self, key):
- return self.values[key][VALUE_DEFAULT]
-
-
- def check_and_default(self, kv_map):
- copy = {}
- for k,v in self.values.items():
- if k not in kv_map:
- if self.is_mandatory(k):
- raise Exception("In section '%s', missing mandatory key '%s'" % (self.name, k))
- else:
- copy[k] = self.default_value(k)
- for k,v in kv_map.items():
- if k not in self.values:
- raise Exception("In section '%s', unknown key '%s'" % (self.name, k))
- copy[k] = v
- return copy
-
-
- def index_of(self, kv_map):
- result = self.name
- for key in self.index_keys:
- result += ':%s' % kv_map[key]
- if result == "":
- result = "SINGLE"
- return result
-
-
-class Schema:
- """
- """
-
- def __init__(self):
- self.sections = {}
- for k,v in config_schema.items():
- self.sections[k] = SchemaSection(k, v)
-
-
-
-class DXConfig:
- """
- Configuration File Parser for Qpid Dispatch
-
- Configuration files are made up of "sections" having the following form:
-
- section-name {
- key0: value0
- key1: value1
- ...
- keyN: valueN
- }
-
- Sections may be repeated (i.e. there may be multiple instances with the same section name).
- The keys must be unique within a section. Values can be of string or integer types. No
- quoting is necessary anywhere in the configuration file. Values may contain whitespace.
-
- Comment lines starting with the '#' character will be ignored.
-
- This parser converts the configuration file into a json string where the file is represented
- as a list of maps. Each map has one item, the key being the section name and the value being
- a nested map of keys and values from the file. This json string is parsed into a data
- structure that may then be queried.
-
- """
-
- def __init__(self, path):
- self.path = path
- self.raw_config = None
- self.config = None
- self.schema = Schema()
- self.log = LogAdapter('config.parser')
-
-
- def read_file(self):
- try:
- self.log.log(LOG_INFO, "Reading Configuration File: %s" % self.path)
- cfile = open(self.path)
- text = cfile.read()
- cfile.close()
-
- self.json_text = "[" + self._toJson(text) + "]"
- self.raw_config = json.loads(self.json_text);
- self._validate_raw_config()
- self._process_schema()
- except Exception, E:
- print "Exception in read_file: %r" % E
- raise
-
-
- def __repr__(self):
- return "%r" % self.config
-
-
- def _toJson(self, text):
- lines = text.split('\n')
- stripped = ""
- for line in lines:
- sline = line.strip()
-
- #
- # Ignore empty lines
- #
- if len(sline) == 0:
- continue
-
- #
- # Ignore comment lines
- #
- if sline.find('#') == 0:
- continue
-
- #
- # Convert section opens, closes, and colon-separated key:value lines into json
- #
- if sline[-1:] == '{':
- sline = '{"' + sline[:-1].strip() + '" : {'
- elif sline == '}':
- sline = '}},'
- else:
- colon = sline.find(':')
- if colon > 1:
- sline = '"' + sline[:colon] + '":"' + sline[colon+1:].strip() + '",'
- stripped += sline
-
- #
- # Remove the trailing commas in map entries
- #
- stripped = stripped.replace(",}", "}")
-
- #
- # Return the entire document minus the trailing comma
- #
- return stripped[:-1]
-
-
- def _validate_raw_config(self):
- """
- Ensure that the configuration is well-formed. Once this is validated,
- further functions can assume a well-formed data structure is in place.
- """
- if self.raw_config.__class__ != list:
- raise Exception("Invalid Config: Expected List at top level")
- for section in self.raw_config:
- if section.__class__ != dict:
- raise Exception("Invalid Config: List items must be maps")
- if len(section) != 1:
- raise Exception("Invalid Config: Map must have only one entry")
- for key,val in section.items():
- if key.__class__ != str and key.__class__ != unicode:
- raise Exception("Invalid Config: Key in map must be a string")
- if val.__class__ != dict:
- raise Exception("Invalid Config: Value in map must be a map")
- for k,v in val.items():
- if k.__class__ != str and k.__class__ != unicode:
- raise Exception("Invalid Config: Key in section must be a string")
- if v.__class__ != str and v.__class__ != unicode:
- raise Exception("Invalid Config: Value in section must be a string")
-
-
- def _process_schema(self):
- self.config = ConfigMain(self.schema)
- self.config.update(self.raw_config)
- self.raw_config = None
-
-
- def item_count(self, section):
- """
- Return the number of items in a section (i.e. the number if instances of a section-name).
- """
- result = self.config.item_count(section)
- return result
-
-
- def _value(self, section, idx, key):
- return self.config.get_value(section, idx, key)
-
-
- def value_string(self, section, idx, key):
- """
- Return the string value for the key in the idx'th item in the section.
- """
- value = self._value(section, idx, key)
- if value:
- return str(value)
- return None
-
-
- def value_int(self, section, idx, key):
- """
- Return the integer value for the key in the idx'th item in the section.
- """
- value = self._value(section, idx, key)
- return long(value)
-
-
- def value_bool(self, section, idx, key):
- """
- Return the boolean value for the key in the idx'th item in the section.
- """
- value = self._value(section, idx, key)
- if value:
- if str(value) != "no":
- return True
- return None
diff --git a/extras/dispatch/python/qpid/dispatch/config/schema.py b/extras/dispatch/python/qpid/dispatch/config/schema.py
deleted file mode 100644
index 7b00000c99..0000000000
--- a/extras/dispatch/python/qpid/dispatch/config/schema.py
+++ /dev/null
@@ -1,85 +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
-##
-
-#
-# config_schema =
-# { <section_name> :
-# (<singleton>,
-# {<key> : (<value-type>, <index>, <flags>, <default-value>)
-# )
-# }
-#
-# <section-name> = String name of a configuration section
-# <singleton> = False => There may be 0 or more sections with this name
-# True => There must be exactly one section with this name
-# <key> = String key of a section's key-value pair
-# <value-type> = Python type for the value
-# <index> = None => This value is not an index for multiple sections
-# >= 0 => Ordinal of this value in the section primary-key
-# <flags> = Set of characters:
-# M = Mandatory (no default value)
-# E = Expand referenced section into this record
-# S = During expansion, this key should be copied
-# <default-value> = If not mandatory and not specified, the value defaults to this
-# value
-#
-
-config_schema = {
- 'container' : (True, {
- 'worker-threads' : (int, None, "", 1),
- 'container-name' : (str, None, "", None)
- }),
- 'ssl-profile' : (False, {
- 'name' : (str, 0, "M"),
- 'cert-db' : (str, None, "S", None),
- 'cert-file' : (str, None, "S", None),
- 'key-file' : (str, None, "S", None),
- 'password-file' : (str, None, "S", None),
- 'password' : (str, None, "S", None)
- }),
- 'listener' : (False, {
- 'addr' : (str, 0, "M"),
- 'port' : (str, 1, "M"),
- 'label' : (str, None, "", None),
- 'role' : (str, None, "", 'normal'),
- 'sasl-mechanisms' : (str, None, "M"),
- 'ssl-profile' : (str, None, "E", None),
- 'require-peer-auth' : (bool, None, "", True),
- 'allow-unsecured' : (bool, None, "", False)
- }),
- 'connector' : (False, {
- 'addr' : (str, 0, "M"),
- 'port' : (str, 1, "M"),
- 'label' : (str, None, "", None),
- 'role' : (str, None, "", 'normal'),
- 'sasl-mechanisms' : (str, None, "M"),
- 'ssl-profile' : (str, None, "E", None),
- 'allow-redirect' : (bool, None, "", True)
- }),
- 'router' : (True, {
- 'mode' : (str, None, "", 'standalone'),
- 'router-id' : (str, None, "M"),
- 'area' : (str, None, "", None),
- 'hello-interval' : (int, None, "", 1),
- 'hello-max-age' : (int, None, "", 3),
- 'ra-interval' : (int, None, "", 30),
- 'remote-ls-max-age' : (int, None, "", 60),
- 'mobile-addr-max-age' : (int, None, "", 60)
- })}
-
diff --git a/extras/dispatch/python/qpid/dispatch/router/__init__.py b/extras/dispatch/python/qpid/dispatch/router/__init__.py
deleted file mode 100644
index bdb26a0c11..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/__init__.py
+++ /dev/null
@@ -1,20 +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.
-#
-
-from .router_engine import *
diff --git a/extras/dispatch/python/qpid/dispatch/router/configuration.py b/extras/dispatch/python/qpid/dispatch/router/configuration.py
deleted file mode 100644
index e0fd060b82..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/configuration.py
+++ /dev/null
@@ -1,47 +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.
-#
-
-class Configuration(object):
- """
- This module manages and holds the configuration and tuning parameters for a router.
- """
- def __init__(self, overrides={}):
- ##
- ## Load default values
- ##
- self.values = { 'hello_interval' : 1.0,
- 'hello_max_age' : 3.0,
- 'ra_interval' : 30.0,
- 'remote_ls_max_age' : 60.0,
- 'mobile_addr_max_age' : 60.0 }
-
- ##
- ## Apply supplied overrides
- ##
- for k, v in overrides.items():
- self.values[k] = v
-
- def __getattr__(self, key):
- if key in self.values:
- return self.values[key]
- raise KeyError
-
- def __repr__(self):
- return "%r" % self.values
-
diff --git a/extras/dispatch/python/qpid/dispatch/router/data.py b/extras/dispatch/python/qpid/dispatch/router/data.py
deleted file mode 100644
index 812369768f..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/data.py
+++ /dev/null
@@ -1,275 +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.
-#
-
-
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-
-def getMandatory(data, key, cls=None):
- """
- Get the value mapped to the requested key. If it's not present, raise an exception.
- """
- if key in data:
- value = data[key]
- if cls and value.__class__ != cls:
- raise Exception("Protocol field has wrong data type: '%s' type=%r expected=%r" % (key, value.__class__, cls))
- return value
- raise Exception("Mandatory protocol field missing: '%s'" % key)
-
-
-def getOptional(data, key, default=None, cls=None):
- """
- Get the value mapped to the requested key. If it's not present, return the default value.
- """
- if key in data:
- value = data[key]
- if cls and value.__class__ != cls:
- raise Exception("Protocol field has wrong data type: '%s' type=%r expected=%r" % (key, value.__class__, cls))
- return value
- return default
-
-
-class LinkState(object):
- """
- The link-state of a single router. The link state consists of a list of neighbor routers reachable from
- the reporting router. The link-state-sequence number is incremented each time the link state changes.
- """
- def __init__(self, body, _id=None, _area=None, _ls_seq=None, _peers=None):
- self.last_seen = 0
- if body:
- self.id = getMandatory(body, 'id', str)
- self.area = getMandatory(body, 'area', str)
- self.ls_seq = getMandatory(body, 'ls_seq', long)
- self.peers = getMandatory(body, 'peers', list)
- else:
- self.id = _id
- self.area = _area
- self.ls_seq = long(_ls_seq)
- self.peers = _peers
-
- def __repr__(self):
- return "LS(id=%s area=%s ls_seq=%d peers=%r)" % (self.id, self.area, self.ls_seq, self.peers)
-
- def to_dict(self):
- return {'id' : self.id,
- 'area' : self.area,
- 'ls_seq' : self.ls_seq,
- 'peers' : self.peers}
-
- def add_peer(self, _id):
- if self.peers.count(_id) == 0:
- self.peers.append(_id)
- return True
- return False
-
- def del_peer(self, _id):
- if self.peers.count(_id) > 0:
- self.peers.remove(_id)
- return True
- return False
-
- def bump_sequence(self):
- self.ls_seq += 1
-
-
-class MessageHELLO(object):
- """
- HELLO Message
- scope: neighbors only - HELLO messages travel at most one hop
- This message is used by directly connected routers to determine with whom they have
- bidirectional connectivity.
- """
- def __init__(self, body, _id=None, _area=None, _seen_peers=None):
- if body:
- self.id = getMandatory(body, 'id', str)
- self.area = getMandatory(body, 'area', str)
- self.seen_peers = getMandatory(body, 'seen', list)
- else:
- self.id = _id
- self.area = _area
- self.seen_peers = _seen_peers
-
- def __repr__(self):
- return "HELLO(id=%s area=%s seen=%r)" % (self.id, self.area, self.seen_peers)
-
- def get_opcode(self):
- return 'HELLO'
-
- def to_dict(self):
- return {'id' : self.id,
- 'area' : self.area,
- 'seen' : self.seen_peers}
-
- def is_seen(self, _id):
- return self.seen_peers.count(_id) > 0
-
-
-class MessageRA(object):
- """
- Router Advertisement (RA) Message
- scope: all routers in the area and all designated routers
- This message is sent periodically to indicate the originating router's sequence numbers
- for link-state and mobile-address-state.
- """
- def __init__(self, body, _id=None, _area=None, _ls_seq=None, _mobile_seq=None):
- if body:
- self.id = getMandatory(body, 'id', str)
- self.area = getMandatory(body, 'area', str)
- self.ls_seq = getMandatory(body, 'ls_seq', long)
- self.mobile_seq = getMandatory(body, 'mobile_seq', long)
- else:
- self.id = _id
- self.area = _area
- self.ls_seq = long(_ls_seq)
- self.mobile_seq = long(_mobile_seq)
-
- def get_opcode(self):
- return 'RA'
-
- def __repr__(self):
- return "RA(id=%s area=%s ls_seq=%d mobile_seq=%d)" % \
- (self.id, self.area, self.ls_seq, self.mobile_seq)
-
- def to_dict(self):
- return {'id' : self.id,
- 'area' : self.area,
- 'ls_seq' : self.ls_seq,
- 'mobile_seq' : self.mobile_seq}
-
-
-class MessageLSU(object):
- """
- """
- def __init__(self, body, _id=None, _area=None, _ls_seq=None, _ls=None):
- if body:
- self.id = getMandatory(body, 'id', str)
- self.area = getMandatory(body, 'area', str)
- self.ls_seq = getMandatory(body, 'ls_seq', long)
- self.ls = LinkState(getMandatory(body, 'ls', dict))
- else:
- self.id = _id
- self.area = _area
- self.ls_seq = long(_ls_seq)
- self.ls = _ls
-
- def get_opcode(self):
- return 'LSU'
-
- def __repr__(self):
- return "LSU(id=%s area=%s ls_seq=%d ls=%r)" % \
- (self.id, self.area, self.ls_seq, self.ls)
-
- def to_dict(self):
- return {'id' : self.id,
- 'area' : self.area,
- 'ls_seq' : self.ls_seq,
- 'ls' : self.ls.to_dict()}
-
-
-class MessageLSR(object):
- """
- """
- def __init__(self, body, _id=None, _area=None):
- if body:
- self.id = getMandatory(body, 'id', str)
- self.area = getMandatory(body, 'area', str)
- else:
- self.id = _id
- self.area = _area
-
- def get_opcode(self):
- return 'LSR'
-
- def __repr__(self):
- return "LSR(id=%s area=%s)" % (self.id, self.area)
-
- def to_dict(self):
- return {'id' : self.id,
- 'area' : self.area}
-
-
-class MessageMAU(object):
- """
- """
- def __init__(self, body, _id=None, _area=None, _seq=None, _add_list=None, _del_list=None, _exist_list=None):
- if body:
- self.id = getMandatory(body, 'id', str)
- self.area = getMandatory(body, 'area', str)
- self.mobile_seq = getMandatory(body, 'mobile_seq', long)
- self.add_list = getOptional(body, 'add', None, list)
- self.del_list = getOptional(body, 'del', None, list)
- self.exist_list = getOptional(body, 'exist', None, list)
- else:
- self.id = _id
- self.area = _area
- self.mobile_seq = long(_seq)
- self.add_list = _add_list
- self.del_list = _del_list
- self.exist_list = _exist_list
-
- def get_opcode(self):
- return 'MAU'
-
- def __repr__(self):
- _add = ''
- _del = ''
- _exist = ''
- if self.add_list: _add = ' add=%r' % self.add_list
- if self.del_list: _del = ' del=%r' % self.del_list
- if self.exist_list: _exist = ' exist=%r' % self.exist_list
- return "MAU(id=%s area=%s mobile_seq=%d%s%s%s)" % \
- (self.id, self.area, self.mobile_seq, _add, _del, _exist)
-
- def to_dict(self):
- body = { 'id' : self.id,
- 'area' : self.area,
- 'mobile_seq' : self.mobile_seq }
- if self.add_list: body['add'] = self.add_list
- if self.del_list: body['del'] = self.del_list
- if self.exist_list: body['exist'] = self.exist_list
- return body
-
-
-class MessageMAR(object):
- """
- """
- def __init__(self, body, _id=None, _area=None, _have_seq=None):
- if body:
- self.id = getMandatory(body, 'id', str)
- self.area = getMandatory(body, 'area', str)
- self.have_seq = getMandatory(body, 'have_seq', long)
- else:
- self.id = _id
- self.area = _area
- self.have_seq = long(_have_seq)
-
- def get_opcode(self):
- return 'MAR'
-
- def __repr__(self):
- return "MAR(id=%s area=%s have_seq=%d)" % (self.id, self.area, self.have_seq)
-
- def to_dict(self):
- return {'id' : self.id,
- 'area' : self.area,
- 'have_seq' : self.have_seq}
-
diff --git a/extras/dispatch/python/qpid/dispatch/router/link.py b/extras/dispatch/python/qpid/dispatch/router/link.py
deleted file mode 100644
index 11307cd079..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/link.py
+++ /dev/null
@@ -1,144 +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.
-#
-
-from data import MessageRA, MessageLSU, MessageLSR
-from time import time
-
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-class LinkStateEngine(object):
- """
- This module is responsible for running the Link State protocol and maintaining the set
- of link states that are gathered from the domain. It notifies outbound when changes to
- the link-state-collection are detected.
- """
- def __init__(self, container):
- self.container = container
- self.id = self.container.id
- self.area = self.container.area
- self.ra_interval = self.container.config.ra_interval
- self.remote_ls_max_age = self.container.config.remote_ls_max_age
- self.last_ra_time = 0
- self.collection = {}
- self.collection_changed = False
- self.mobile_seq = 0
- self.needed_lsrs = {}
-
-
- def tick(self, now):
- self._expire_ls(now)
- self._send_lsrs()
-
- if now - self.last_ra_time >= self.ra_interval:
- self.last_ra_time = now
- self._send_ra()
-
- if self.collection_changed:
- self.collection_changed = False
- self.container.log(LOG_INFO, "New Link-State Collection:")
- for a,b in self.collection.items():
- self.container.log(LOG_INFO, " %s => %r" % (a, b.peers))
- self.container.ls_collection_changed(self.collection)
-
-
- def handle_ra(self, msg, now):
- if msg.id == self.id:
- return
- if msg.id in self.collection:
- ls = self.collection[msg.id]
- ls.last_seen = now
- if ls.ls_seq < msg.ls_seq:
- self.needed_lsrs[(msg.area, msg.id)] = None
- else:
- self.needed_lsrs[(msg.area, msg.id)] = None
-
-
- def handle_lsu(self, msg, now):
- if msg.id == self.id:
- return
- if msg.id in self.collection:
- ls = self.collection[msg.id]
- if ls.ls_seq < msg.ls_seq:
- ls = msg.ls
- self.collection[msg.id] = ls
- self.collection_changed = True
- ls.last_seen = now
- else:
- ls = msg.ls
- self.collection[msg.id] = ls
- self.collection_changed = True
- ls.last_seen = now
- self.container.new_node(msg.id)
- self.container.log(LOG_INFO, "Learned link-state from new router: %s" % msg.id)
- # Schedule LSRs for any routers referenced in this LS that we don't know about
- for _id in msg.ls.peers:
- if _id not in self.collection:
- self.container.new_node(_id)
- self.needed_lsrs[(msg.area, _id)] = None
-
-
- def handle_lsr(self, msg, now):
- if msg.id == self.id:
- return
- if self.id not in self.collection:
- return
- my_ls = self.collection[self.id]
- self.container.send('amqp:/_topo/%s/%s/qdxrouter' % (msg.area, msg.id), MessageLSU(None, self.id, self.area, my_ls.ls_seq, my_ls))
-
-
- def new_local_link_state(self, link_state):
- self.collection[self.id] = link_state
- self.collection_changed = True
- self._send_ra()
-
-
- def set_mobile_sequence(self, seq):
- self.mobile_seq = seq
-
-
- def get_collection(self):
- return self.collection
-
-
- def _expire_ls(self, now):
- to_delete = []
- for key, ls in self.collection.items():
- if key != self.id and now - ls.last_seen > self.remote_ls_max_age:
- to_delete.append(key)
- for key in to_delete:
- ls = self.collection.pop(key)
- self.collection_changed = True
- self.container.lost_node(key)
- self.container.log(LOG_INFO, "Expired link-state from router: %s" % key)
-
-
- def _send_lsrs(self):
- for (_area, _id) in self.needed_lsrs.keys():
- self.container.send('amqp:/_topo/%s/%s/qdxrouter' % (_area, _id), MessageLSR(None, self.id, self.area))
- self.needed_lsrs = {}
-
-
- def _send_ra(self):
- ls_seq = 0
- if self.id in self.collection:
- ls_seq = self.collection[self.id].ls_seq
- self.container.send('amqp:/_topo/%s/all/qdxrouter' % self.area, MessageRA(None, self.id, self.area, ls_seq, self.mobile_seq))
diff --git a/extras/dispatch/python/qpid/dispatch/router/mobile.py b/extras/dispatch/python/qpid/dispatch/router/mobile.py
deleted file mode 100644
index 117cf98c22..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/mobile.py
+++ /dev/null
@@ -1,189 +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.
-#
-
-from data import MessageRA, MessageMAR, MessageMAU
-
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-class MobileAddressEngine(object):
- """
- This module is responsible for maintaining an up-to-date list of mobile addresses in the domain.
- It runs the Mobile-Address protocol and generates an un-optimized routing table for mobile addresses.
- Note that this routing table maps from the mobile address to the remote router where that address
- is directly bound.
- """
- def __init__(self, container, node_tracker):
- self.container = container
- self.node_tracker = node_tracker
- self.id = self.container.id
- self.area = self.container.area
- self.mobile_addr_max_age = self.container.config.mobile_addr_max_age
- self.mobile_seq = 0
- self.local_addrs = []
- self.added_addrs = []
- self.deleted_addrs = []
- self.remote_lists = {} # map router_id => (sequence, list of addrs)
- self.remote_last_seen = {} # map router_id => time of last seen advertizement/update
- self.needed_mars = {}
-
-
- def tick(self, now):
- self._expire_remotes(now)
- self._send_mars()
-
- ##
- ## If local addrs have changed, collect the changes and send a MAU with the diffs
- ## Note: it is important that the differential-MAU be sent before a RA is sent
- ##
- if len(self.added_addrs) > 0 or len(self.deleted_addrs) > 0:
- self.mobile_seq += 1
- self.container.send('amqp:/_topo/%s/all/qdxrouter' % self.area,
- MessageMAU(None, self.id, self.area, self.mobile_seq, self.added_addrs, self.deleted_addrs))
- self.local_addrs.extend(self.added_addrs)
- for addr in self.deleted_addrs:
- self.local_addrs.remove(addr)
- self.added_addrs = []
- self.deleted_addrs = []
- self.container.mobile_sequence_changed(self.mobile_seq)
-
-
- def add_local_address(self, addr):
- """
- """
- if self.local_addrs.count(addr) == 0:
- if self.added_addrs.count(addr) == 0:
- self.added_addrs.append(addr)
- else:
- if self.deleted_addrs.count(addr) > 0:
- self.deleted_addrs.remove(addr)
-
-
- def del_local_address(self, addr):
- """
- """
- if self.local_addrs.count(addr) > 0:
- if self.deleted_addrs.count(addr) == 0:
- self.deleted_addrs.append(addr)
- else:
- if self.added_addrs.count(addr) > 0:
- self.added_addrs.remove(addr)
-
-
- def handle_ra(self, msg, now):
- if msg.id == self.id:
- return
-
- if msg.mobile_seq == 0:
- return
-
- if msg.id in self.remote_lists:
- _seq, _list = self.remote_lists[msg.id]
- self.remote_last_seen[msg.id] = now
- if _seq < msg.mobile_seq:
- self.needed_mars[(msg.id, msg.area, _seq)] = None
- else:
- self.needed_mars[(msg.id, msg.area, 0)] = None
-
-
- def handle_mau(self, msg, now):
- ##
- ## If the MAU is differential, we can only use it if its sequence is exactly one greater
- ## than our stored sequence. If not, we will ignore the content and schedule a MAR.
- ##
- ## If the MAU is absolute, we can use it in all cases.
- ##
- if msg.id == self.id:
- return
-
- if msg.exist_list:
- ##
- ## Absolute MAU
- ##
- if msg.id in self.remote_lists:
- _seq, _list = self.remote_lists[msg.id]
- if _seq >= msg.mobile_seq: # ignore duplicates
- return
- self.remote_lists[msg.id] = (msg.mobile_seq, msg.exist_list)
- self.remote_last_seen[msg.id] = now
- (add_list, del_list) = self.node_tracker.overwrite_addresses(msg.id, msg.exist_list)
- self._activate_remotes(msg.id, add_list, del_list)
- else:
- ##
- ## Differential MAU
- ##
- if msg.id in self.remote_lists:
- _seq, _list = self.remote_lists[msg.id]
- if _seq == msg.mobile_seq: # ignore duplicates
- return
- self.remote_last_seen[msg.id] = now
- if _seq + 1 == msg.mobile_seq:
- ##
- ## This is one greater than our stored value, incorporate the deltas
- ##
- if msg.add_list and msg.add_list.__class__ == list:
- _list.extend(msg.add_list)
- if msg.del_list and msg.del_list.__class__ == list:
- for addr in msg.del_list:
- _list.remove(addr)
- self.remote_lists[msg.id] = (msg.mobile_seq, _list)
- if msg.add_list:
- self.node_tracker.add_addresses(msg.id, msg.add_list)
- if msg.del_list:
- self.node_tracker.del_addresses(msg.id, msg.del_list)
- self._activate_remotes(msg.id, msg.add_list, msg.del_list)
- else:
- self.needed_mars[(msg.id, msg.area, _seq)] = None
- else:
- self.needed_mars[(msg.id, msg.area, 0)] = None
-
-
- def handle_mar(self, msg, now):
- if msg.id == self.id:
- return
- if msg.have_seq < self.mobile_seq:
- self.container.send('amqp:/_topo/%s/%s/qdxrouter' % (msg.area, msg.id),
- MessageMAU(None, self.id, self.area, self.mobile_seq, None, None, self.local_addrs))
-
-
- def _expire_remotes(self, now):
- for _id, t in self.remote_last_seen.items():
- if now - t > self.mobile_addr_max_age:
- self.remote_lists.pop(_id)
- self.remote_last_seen.pop(_id)
- self.remote_changed = True
-
-
- def _send_mars(self):
- for _id, _area, _seq in self.needed_mars.keys():
- self.container.send('amqp:/_topo/%s/%s/qdxrouter' % (_area, _id), MessageMAR(None, self.id, self.area, _seq))
- self.needed_mars = {}
-
-
- def _activate_remotes(self, _id, added, deleted):
- bit = self.node_tracker.maskbit_for_node(_id)
- if added:
- for a in added:
- self.container.router_adapter.map_destination(a, bit)
- if deleted:
- for d in deleted:
- self.container.router_adapter.unmap_destination(d, bit)
-
diff --git a/extras/dispatch/python/qpid/dispatch/router/neighbor.py b/extras/dispatch/python/qpid/dispatch/router/neighbor.py
deleted file mode 100644
index 37b7888efe..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/neighbor.py
+++ /dev/null
@@ -1,83 +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.
-#
-
-from data import LinkState, MessageHELLO
-from time import time
-
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-
-class NeighborEngine(object):
- """
- This module is responsible for maintaining this router's link-state. It runs the HELLO protocol
- with the router's neighbors and notifies outbound when the list of neighbors-in-good-standing (the
- link-state) changes.
- """
- def __init__(self, container):
- self.container = container
- self.id = self.container.id
- self.area = self.container.area
- self.last_hello_time = 0.0
- self.hello_interval = container.config.hello_interval
- self.hello_max_age = container.config.hello_max_age
- self.hellos = {}
- self.link_state_changed = False
- self.link_state = LinkState(None, self.id, self.area, 0, [])
-
-
- def tick(self, now):
- self._expire_hellos(now)
-
- if now - self.last_hello_time >= self.hello_interval:
- self.last_hello_time = now
- self.container.send('amqp:/_local/qdxhello', MessageHELLO(None, self.id, self.area, self.hellos.keys()))
-
- if self.link_state_changed:
- self.link_state_changed = False
- self.link_state.bump_sequence()
- self.container.local_link_state_changed(self.link_state)
-
-
- def handle_hello(self, msg, now, link_id):
- if msg.id == self.id:
- return
- self.hellos[msg.id] = now
- if msg.is_seen(self.id):
- if self.link_state.add_peer(msg.id):
- self.link_state_changed = True
- self.container.new_neighbor(msg.id, link_id)
- self.container.log(LOG_INFO, "New neighbor established: %s on link: %d" % (msg.id, link_id))
- ##
- ## TODO - Use this function to detect area boundaries
- ##
-
- def _expire_hellos(self, now):
- to_delete = []
- for key, last_seen in self.hellos.items():
- if now - last_seen > self.hello_max_age:
- to_delete.append(key)
- for key in to_delete:
- self.hellos.pop(key)
- if self.link_state.del_peer(key):
- self.link_state_changed = True
- self.container.lost_neighbor(key)
- self.container.log(LOG_INFO, "Neighbor lost: %s" % key)
diff --git a/extras/dispatch/python/qpid/dispatch/router/node.py b/extras/dispatch/python/qpid/dispatch/router/node.py
deleted file mode 100644
index ef697428da..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/node.py
+++ /dev/null
@@ -1,174 +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.
-#
-
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-
-class NodeTracker(object):
- """
- This module is responsible for tracking the set of router nodes that are known to this
- router. It tracks whether they are neighbor or remote and whether they are reachable.
-
- This module is also responsible for assigning a unique mask bit value to each router.
- The mask bit is used in the main router to represent sets of valid destinations for addresses.
- """
- def __init__(self, container, max_routers):
- self.container = container
- self.max_routers = max_routers
- self.nodes = {} # id => RemoteNode
- self.maskbits = []
- self.next_maskbit = 1 # Reserve bit '0' to represent this router
- for i in range(max_routers):
- self.maskbits.append(None)
- self.maskbits[0] = True
-
-
- def tick(self, now):
- pass
-
-
- def new_neighbor(self, node_id, link_maskbit):
- """
- A node, designated by node_id, has been discovered as a neighbor over a link with
- a maskbit of link_maskbit.
- """
- if node_id in self.nodes:
- node = self.nodes[node_id]
- if node.neighbor:
- return
- self.container.del_remote_router(node.maskbit)
- node.neighbor = True
- else:
- node = RemoteNode(node_id, self._allocate_maskbit(), True)
- self.nodes[node_id] = node
- self.container.add_neighbor_router(self._address(node_id), node.maskbit, link_maskbit)
-
-
- def lost_neighbor(self, node_id):
- """
- We have lost contact with a neighboring node node_id.
- """
- node = self.nodes[node_id]
- node.neighbor = False
- self.container.del_neighbor_router(node.maskbit)
- if node.remote:
- self.container.add_remote_router(self._address(node.id), node.maskbit)
- else:
- self._free_maskbit(node.maskbit)
- self.nodes.pop(node_id)
-
-
- def new_node(self, node_id):
- """
- A node, designated by node_id, has been discovered through the an advertisement from a
- remote peer.
- """
- if node_id not in self.nodes:
- node = RemoteNode(node_id, self._allocate_maskbit(), False)
- self.nodes[node_id] = node
- self.container.add_remote_router(self._address(node.id), node.maskbit)
- else:
- node = self.nodes[node_id]
- node.remote = True
-
-
- def lost_node(self, node_id):
- """
- A remote node, node_id, has not been heard from for too long and is being deemed lost.
- """
- node = self.nodes[node_id]
- if node.remote:
- node.remote = False
- if not node.neighbor:
- self.container.del_remote_router(node.maskbit)
- self._free_maskbit(node.maskbit)
- self.nodes.pop(node_id)
-
-
- def maskbit_for_node(self, node_id):
- """
- """
- node = self.nodes[node_id]
- if node:
- return node.maskbit
- return None
-
-
- def add_addresses(self, node_id, addrs):
- node = self.nodes[node_id]
- for a in addrs:
- node.addrs[a] = 1
-
-
- def del_addresses(self, node_id, addrs):
- node = self.nodes[node_id]
- for a in addrs:
- node.addrs.pop(a)
-
-
- def overwrite_addresses(self, node_id, addrs):
- node = self.nodes[node_id]
- added = []
- deleted = []
- for a in addrs:
- if a not in node.addrs.keys():
- added.append(a)
- for a in node.addrs.keys():
- if a not in addrs:
- deleted.append(a)
- for a in addrs:
- node.addrs[a] = 1
- return (added, deleted)
-
-
- def _allocate_maskbit(self):
- if self.next_maskbit == None:
- raise Exception("Exceeded Maximum Router Count")
- result = self.next_maskbit
- self.next_maskbit = None
- self.maskbits[result] = True
- for n in range(result + 1, self.max_routers):
- if self.maskbits[n] == None:
- self.next_maskbit = n
- break
- return result
-
-
- def _free_maskbit(self, i):
- self.maskbits[i] = None
- if self.next_maskbit == None or i < self.next_maskbit:
- self.next_maskbit = i
-
-
- def _address(self, node_id):
- return "amqp:/_topo/%s/%s" % (self.container.area, node_id)
-
-
-class RemoteNode(object):
-
- def __init__(self, node_id, maskbit, neighbor):
- self.id = node_id
- self.maskbit = maskbit
- self.neighbor = neighbor
- self.remote = not neighbor
- self.addrs = {} # Address => Count at Node (1 only for the present)
-
diff --git a/extras/dispatch/python/qpid/dispatch/router/path.py b/extras/dispatch/python/qpid/dispatch/router/path.py
deleted file mode 100644
index da04474e75..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/path.py
+++ /dev/null
@@ -1,235 +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.
-#
-
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-class PathEngine(object):
- """
- This module is responsible for computing the next-hop for every router/area in the domain
- based on the collection of link states that have been gathered.
- """
- def __init__(self, container):
- self.container = container
- self.id = self.container.id
- self.area = self.container.area
- self.recalculate = False
- self.collection = None
-
-
- def tick(self, now_unused):
- if self.recalculate:
- self.recalculate = False
- self._calculate_routes()
-
-
- def ls_collection_changed(self, collection):
- self.recalculate = True
- self.collection = collection
-
-
- def _calculate_tree_from_root(self, root):
- ##
- ## Make a copy of the current collection of link-states that contains
- ## a fake link-state for nodes that are known-peers but are not in the
- ## collection currently. This is needed to establish routes to those nodes
- ## so we can trade link-state information with them.
- ##
- link_states = {}
- for _id, ls in self.collection.items():
- link_states[_id] = ls.peers
- for p in ls.peers:
- if p not in link_states:
- link_states[p] = [_id]
-
- ##
- ## Setup Dijkstra's Algorithm
- ##
- cost = {}
- prev = {}
- for _id in link_states:
- cost[_id] = None # infinite
- prev[_id] = None # undefined
- cost[root] = 0 # no cost to the root node
- unresolved = NodeSet(cost)
-
- ##
- ## Process unresolved nodes until lowest cost paths to all reachable nodes have been found.
- ##
- while not unresolved.empty():
- u = unresolved.lowest_cost()
- if cost[u] == None:
- # There are no more reachable nodes in unresolved
- break
- for v in link_states[u]:
- if unresolved.contains(v):
- alt = cost[u] + 1 # TODO - Use link cost instead of 1
- if cost[v] == None or alt < cost[v]:
- cost[v] = alt
- prev[v] = u
- unresolved.set_cost(v, alt)
-
- ##
- ## Remove unreachable nodes from the map. Note that this will also remove the
- ## root node (has no previous node) from the map.
- ##
- for u, val in prev.items():
- if not val:
- prev.pop(u)
-
- ##
- ## Return previous-node map. This is a map of all reachable, remote nodes to
- ## their predecessor node.
- ##
- return prev
-
-
- def _calculate_valid_origins(self, nodeset):
- ##
- ## Calculate the tree from each origin, determine the set of origins-per-dest
- ## for which the path from origin to dest passes through us. This is the set
- ## of valid origins for forwarding to the destination.
- ##
- valid_origin = {} # Map of destination => List of Valid Origins
- for node in nodeset:
- if node != self.id:
- valid_origin[node] = []
-
- for root in valid_origin.keys():
- prev = self._calculate_tree_from_root(root)
- nodes = prev.keys()
- while len(nodes) > 0:
- u = nodes[0]
- path = [u]
- nodes.remove(u)
- v = prev[u]
- while v != root:
- if v in nodes:
- if v != self.id:
- path.append(v)
- nodes.remove(v)
- if v == self.id:
- valid_origin[root].extend(path)
- u = v
- v = prev[u]
- return valid_origin
-
-
- def _calculate_routes(self):
- ##
- ## Generate the shortest-path tree with the local node as root
- ##
- prev = self._calculate_tree_from_root(self.id)
- nodes = prev.keys()
-
- ##
- ## Distill the path tree into a map of next hops for each node
- ##
- next_hops = {}
- while len(nodes) > 0:
- u = nodes[0] # pick any destination
- path = [u]
- nodes.remove(u)
- v = prev[u]
- while v != self.id: # build a list of nodes in the path back to the root
- if v in nodes:
- path.append(v)
- nodes.remove(v)
- u = v
- v = prev[u]
- for w in path: # mark each node in the path as reachable via the next hop
- next_hops[w] = u
-
- self.container.next_hops_changed(next_hops)
-
- ##
- ## Calculate the valid origins for remote routers
- ##
- valid_origin = self._calculate_valid_origins(prev.keys())
- self.container.valid_origins_changed(valid_origin)
-
-
-
-class NodeSet(object):
- """
- This data structure is an ordered list of node IDs, sorted in increasing order by their cost.
- Equal cost nodes are secondarily sorted by their ID in order to provide deterministic and
- repeatable ordering.
- """
- def __init__(self, cost_map):
- self.nodes = []
- for _id, cost in cost_map.items():
- ##
- ## Assume that nodes are either unreachable (cost = None) or local (cost = 0)
- ## during this initialization.
- ##
- if cost == 0:
- self.nodes.insert(0, (_id, cost))
- else:
- ##
- ## There is no need to sort unreachable nodes by ID
- ##
- self.nodes.append((_id, cost))
-
-
- def __repr__(self):
- return self.nodes.__repr__()
-
-
- def empty(self):
- return len(self.nodes) == 0
-
-
- def contains(self, _id):
- for a, b in self.nodes:
- if a == _id:
- return True
- return False
-
-
- def lowest_cost(self):
- """
- Remove and return the lowest cost node ID.
- """
- _id, cost = self.nodes.pop(0)
- return _id
-
-
- def set_cost(self, _id, new_cost):
- """
- Set the cost for an ID in the NodeSet and re-insert the ID so that the list
- remains sorted in increasing cost order.
- """
- index = 0
- for i, c in self.nodes:
- if i == _id:
- break
- index += 1
- self.nodes.pop(index)
-
- index = 0
- for i, c in self.nodes:
- if c == None or new_cost < c or (new_cost == c and _id < i):
- break
- index += 1
-
- self.nodes.insert(index, (_id, new_cost))
-
diff --git a/extras/dispatch/python/qpid/dispatch/router/router_engine.py b/extras/dispatch/python/qpid/dispatch/router/router_engine.py
deleted file mode 100644
index 0bc7ba72c2..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/router_engine.py
+++ /dev/null
@@ -1,301 +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.
-#
-
-from time import time
-from uuid import uuid4
-
-from configuration import Configuration
-from data import *
-from neighbor import NeighborEngine
-from link import LinkStateEngine
-from path import PathEngine
-from mobile import MobileAddressEngine
-from routing import RoutingTableEngine
-from node import NodeTracker
-
-import sys
-import traceback
-
-##
-## Import the Dispatch adapters from the environment. If they are not found
-## (i.e. we are in a test bench, etc.), load the stub versions.
-##
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-
-class RouterEngine:
- """
- """
-
- def __init__(self, router_adapter, router_id, area, max_routers, config_override={}):
- """
- Initialize an instance of a router for a domain.
- """
- ##
- ## Record important information about this router instance
- ##
- self.domain = "domain"
- self.router_adapter = router_adapter
- self.log_adapter = LogAdapter("dispatch.router")
- self.io_adapter = IoAdapter(self, ("qdxrouter", "qdxhello"))
- self.max_routers = max_routers
- self.id = router_id
- self.area = area
- self.log(LOG_INFO, "Router Engine Instantiated: area=%s id=%s max_routers=%d" %
- (self.area, self.id, self.max_routers))
-
- ##
- ## Setup configuration
- ##
- self.config = Configuration(config_override)
- self.log(LOG_INFO, "Config: %r" % self.config)
-
- ##
- ## Launch the sub-module engines
- ##
- self.node_tracker = NodeTracker(self, self.max_routers)
- self.neighbor_engine = NeighborEngine(self)
- self.link_state_engine = LinkStateEngine(self)
- self.path_engine = PathEngine(self)
- self.mobile_address_engine = MobileAddressEngine(self, self.node_tracker)
- self.routing_table_engine = RoutingTableEngine(self, self.node_tracker)
-
-
-
- ##========================================================================================
- ## Adapter Entry Points - invoked from the adapter
- ##========================================================================================
- def getId(self):
- """
- Return the router's ID
- """
- return self.id
-
-
- def addressAdded(self, addr):
- """
- """
- try:
- if addr.find('Mtemp.') == 0: ## This is a temporary measure until dynamic is added to Messenger
- return
- if addr.find('M') == 0:
- self.mobile_address_engine.add_local_address(addr[1:])
- except Exception, e:
- self.log(LOG_ERROR, "Exception in new-address processing: exception=%r" % e)
- exc_type, exc_value, exc_traceback = sys.exc_info()
- traceback.print_tb(exc_traceback)
-
-
- def addressRemoved(self, addr):
- """
- """
- try:
- if addr.find('Mtemp.') == 0:
- return
- if addr.find('M') == 0:
- self.mobile_address_engine.del_local_address(addr[1:])
- except Exception, e:
- self.log(LOG_ERROR, "Exception in del-address processing: exception=%r" % e)
- exc_type, exc_value, exc_traceback = sys.exc_info()
- traceback.print_tb(exc_traceback)
-
-
- def handleTimerTick(self):
- """
- """
- try:
- now = time()
- self.neighbor_engine.tick(now)
- self.link_state_engine.tick(now)
- self.path_engine.tick(now)
- self.mobile_address_engine.tick(now)
- self.routing_table_engine.tick(now)
- self.node_tracker.tick(now)
- except Exception, e:
- self.log(LOG_ERROR, "Exception in timer processing: exception=%r" % e)
- exc_type, exc_value, exc_traceback = sys.exc_info()
- traceback.print_tb(exc_traceback)
-
-
- def handleControlMessage(self, opcode, body, link_id):
- """
- """
- try:
- now = time()
- if opcode == 'HELLO':
- msg = MessageHELLO(body)
- self.log(LOG_TRACE, "RCVD: %r" % msg)
- self.neighbor_engine.handle_hello(msg, now, link_id)
-
- elif opcode == 'RA':
- msg = MessageRA(body)
- self.log(LOG_DEBUG, "RCVD: %r" % msg)
- self.link_state_engine.handle_ra(msg, now)
- self.mobile_address_engine.handle_ra(msg, now)
-
- elif opcode == 'LSU':
- msg = MessageLSU(body)
- self.log(LOG_DEBUG, "RCVD: %r" % msg)
- self.link_state_engine.handle_lsu(msg, now)
-
- elif opcode == 'LSR':
- msg = MessageLSR(body)
- self.log(LOG_DEBUG, "RCVD: %r" % msg)
- self.link_state_engine.handle_lsr(msg, now)
-
- elif opcode == 'MAU':
- msg = MessageMAU(body)
- self.log(LOG_DEBUG, "RCVD: %r" % msg)
- self.mobile_address_engine.handle_mau(msg, now)
-
- elif opcode == 'MAR':
- msg = MessageMAR(body)
- self.log(LOG_DEBUG, "RCVD: %r" % msg)
- self.mobile_address_engine.handle_mar(msg, now)
-
- except Exception, e:
- self.log(LOG_ERROR, "Exception in message processing: opcode=%s body=%r exception=%r" % (opcode, body, e))
- exc_type, exc_value, exc_traceback = sys.exc_info()
- traceback.print_tb(exc_traceback)
-
-
- def receive(self, message_properties, body, link_id):
- """
- This is the IoAdapter message-receive handler
- """
- try:
- #self.log(LOG_DEBUG, "Raw Receive: mp=%r body=%r link_id=%r" % (message_properties, body, link_id))
- self.handleControlMessage(message_properties['opcode'], body, link_id)
- except Exception, e:
- self.log(LOG_ERROR, "Exception in raw message processing: properties=%r body=%r exception=%r" %
- (message_properties, body, e))
- exc_type, exc_value, exc_traceback = sys.exc_info()
- traceback.print_tb(exc_traceback)
-
-
- def getRouterData(self, kind):
- """
- """
- if kind == 'help':
- return { 'help' : "Get list of supported values for kind",
- 'link-state' : "This router's link state",
- 'link-state-set' : "The set of link states from known routers",
- 'next-hops' : "Next hops to each known router"
- }
- if kind == 'link-state' : return self.neighbor_engine.link_state.to_dict()
- if kind == 'next-hops' : return self.routing_table_engine.next_hops
- if kind == 'link-state-set' :
- copy = {}
- for _id,_ls in self.link_state_engine.collection.items():
- copy[_id] = _ls.to_dict()
- return copy
-
- return {'notice':'Use kind="help" to get a list of possibilities'}
-
-
- ##========================================================================================
- ## Adapter Calls - outbound calls to Dispatch
- ##========================================================================================
- def log(self, level, text):
- """
- Emit a log message to the host's event log
- """
- self.log_adapter.log(level, text)
-
-
- def send(self, dest, msg):
- """
- Send a control message to another router.
- """
- app_props = {'opcode' : msg.get_opcode() }
- self.io_adapter.send(dest, app_props, msg.to_dict())
- if "qdxhello" in dest:
- self.log(LOG_TRACE, "SENT: %r dest=%s" % (msg, dest))
- else:
- self.log(LOG_DEBUG, "SENT: %r dest=%s" % (msg, dest))
-
-
- def node_updated(self, addr, reachable, neighbor):
- """
- """
- self.router_adapter(addr, reachable, neighbor)
-
-
- ##========================================================================================
- ## Interconnect between the Sub-Modules
- ##========================================================================================
- def local_link_state_changed(self, link_state):
- self.log(LOG_DEBUG, "Event: local_link_state_changed: %r" % link_state)
- self.link_state_engine.new_local_link_state(link_state)
-
- def ls_collection_changed(self, collection):
- self.log(LOG_DEBUG, "Event: ls_collection_changed: %r" % collection)
- self.path_engine.ls_collection_changed(collection)
-
- def next_hops_changed(self, next_hop_table):
- self.log(LOG_DEBUG, "Event: next_hops_changed: %r" % next_hop_table)
- self.routing_table_engine.next_hops_changed(next_hop_table)
-
- def valid_origins_changed(self, valid_origins):
- self.log(LOG_DEBUG, "Event: valid_origins_changed: %r" % valid_origins)
- self.routing_table_engine.valid_origins_changed(valid_origins)
-
- def mobile_sequence_changed(self, mobile_seq):
- self.log(LOG_DEBUG, "Event: mobile_sequence_changed: %d" % mobile_seq)
- self.link_state_engine.set_mobile_sequence(mobile_seq)
-
- def get_next_hops(self):
- return self.routing_table_engine.get_next_hops()
-
- def new_neighbor(self, rid, link_id):
- self.log(LOG_DEBUG, "Event: new_neighbor: id=%s link_id=%d" % (rid, link_id))
- self.node_tracker.new_neighbor(rid, link_id)
-
- def lost_neighbor(self, rid):
- self.log(LOG_DEBUG, "Event: lost_neighbor: id=%s" % rid)
- self.node_tracker.lost_neighbor(rid)
-
- def new_node(self, rid):
- self.log(LOG_DEBUG, "Event: new_node: id=%s" % rid)
- self.node_tracker.new_node(rid)
-
- def lost_node(self, rid):
- self.log(LOG_DEBUG, "Event: lost_node: id=%s" % rid)
- self.node_tracker.lost_node(rid)
-
- def add_neighbor_router(self, address, router_bit, link_bit):
- self.log(LOG_DEBUG, "Event: add_neighbor_router: address=%s, router_bit=%d, link_bit=%d" % \
- (address, router_bit, link_bit))
- self.router_adapter.add_neighbor_router(address, router_bit, link_bit)
-
- def del_neighbor_router(self, router_bit):
- self.log(LOG_DEBUG, "Event: del_neighbor_router: router_bit=%d" % router_bit)
- self.router_adapter.del_neighbor_router(router_bit)
-
- def add_remote_router(self, address, router_bit):
- self.log(LOG_DEBUG, "Event: add_remote_router: address=%s, router_bit=%d" % (address, router_bit))
- self.router_adapter.add_remote_router(address, router_bit)
-
- def del_remote_router(self, router_bit):
- self.log(LOG_DEBUG, "Event: del_remote_router: router_bit=%d" % router_bit)
- self.router_adapter.del_remote_router(router_bit)
-
diff --git a/extras/dispatch/python/qpid/dispatch/router/routing.py b/extras/dispatch/python/qpid/dispatch/router/routing.py
deleted file mode 100644
index a4b3e5484a..0000000000
--- a/extras/dispatch/python/qpid/dispatch/router/routing.py
+++ /dev/null
@@ -1,62 +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.
-#
-
-try:
- from dispatch import *
-except ImportError:
- from ..stubs import *
-
-class RoutingTableEngine(object):
- """
- This module is responsible for converting the set of next hops to remote routers to a routing
- table in the "topological" address class.
- """
- def __init__(self, container, node_tracker):
- self.container = container
- self.node_tracker = node_tracker
- self.id = self.container.id
- self.area = self.container.area
- self.next_hops = {}
-
-
- def tick(self, now):
- pass
-
-
- def next_hops_changed(self, next_hops):
- # Convert next_hops into routing table
- self.next_hops = next_hops
- for _id, next_hop in next_hops.items():
- mb_id = self.node_tracker.maskbit_for_node(_id)
- mb_nh = self.node_tracker.maskbit_for_node(next_hop)
- self.container.router_adapter.set_next_hop(mb_id, mb_nh)
-
-
- def valid_origins_changed(self, valid_origins):
- for _id, vo in valid_origins.items():
- mb_id = self.node_tracker.maskbit_for_node(_id)
- mb_vo = []
- for o in vo:
- mb_vo.append(self.node_tracker.maskbit_for_node(o))
- self.container.router_adapter.set_valid_origins(mb_id, mb_vo)
-
-
- def get_next_hops(self):
- return self.next_hops
-
diff --git a/extras/dispatch/python/qpid/dispatch/stubs/__init__.py b/extras/dispatch/python/qpid/dispatch/stubs/__init__.py
deleted file mode 100644
index 85100d26df..0000000000
--- a/extras/dispatch/python/qpid/dispatch/stubs/__init__.py
+++ /dev/null
@@ -1,22 +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.
-#
-
-from .logadapter import *
-from .ioadapter import *
-
diff --git a/extras/dispatch/python/qpid/dispatch/stubs/ioadapter.py b/extras/dispatch/python/qpid/dispatch/stubs/ioadapter.py
deleted file mode 100644
index 1e465f98c3..0000000000
--- a/extras/dispatch/python/qpid/dispatch/stubs/ioadapter.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-class IoAdapter:
- def __init__(self, handler, address):
- self.handler = handler
- self.address = address
-
- def send(self, address, app_properties, body):
- print "IO: send(addr=%s props=%r body=%r" % (address, app_properties, body)
-
diff --git a/extras/dispatch/python/qpid/dispatch/stubs/logadapter.py b/extras/dispatch/python/qpid/dispatch/stubs/logadapter.py
deleted file mode 100644
index 3d717d3ed2..0000000000
--- a/extras/dispatch/python/qpid/dispatch/stubs/logadapter.py
+++ /dev/null
@@ -1,33 +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.
-#
-
-LOG_TRACE = 1
-LOG_DEBUG = 2
-LOG_INFO = 4
-LOG_NOTICE = 8
-LOG_WARNING = 16
-LOG_ERROR = 32
-LOG_CRITICAL = 64
-
-class LogAdapter:
- def __init__(self, mod_name):
- self.mod_name = mod_name
-
- def log(self, level, text):
- print "LOG: mod=%s level=%d text=%s" % (self.mod_name, level, text)
diff --git a/extras/dispatch/release.sh b/extras/dispatch/release.sh
deleted file mode 100755
index 9b76a9c562..0000000000
--- a/extras/dispatch/release.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/bash
-#
-# 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.
-#
-#
-# Script to pull together an Apache Release
-#
-
-ME=$(basename $0)
-
-usage() {
- cat <<-EOF
-USAGE: ${ME} [options] SVNPATH SVNREV VERSION
-Creates an Apache release tarball.
-
-Mandatory arguments:
- SVNPATH The path within the source code repository.
- SVNREV The revision at which to create the release.
- VERSION The release version.
-
-Optional arguments:
- -h This help screen
-EOF
-}
-
-while getopts "h" opt; do
- case $opt in
- h)
- usage
- exit 0
- ;;
-
- \?)
- echo "Invalid option: -$OPTARG" >&2
- usage
- exit 1
- ;;
-
- :)
- echo "Option -$OPTARG requires an argument." >&2
- usage
- exit 1
- ;;
- esac
-done
-
-SVNPATH=${1-}
-SVNREV=${2-}
-VERSION=${3-}
-
-if [[ -z "$SVNPATH" ]] || [[ -z "$SVNREV" ]] || [[ -z "$VERSION" ]]; then
- printf "Missing one or more required argument.\n\n" >&2
- usage
- exit 1
-fi
-
-URL=http://svn.apache.org/repos/asf/qpid/${SVNPATH}
-
-WORKDIR=$(mktemp -d)
-BASENAME=qpid-dispatch-${VERSION}
-FILENAME=$PWD/${BASENAME}.tar.gz
-
-if [ -f $FILENAME ]; then rm -f $FILENAME; fi
-
-(
-echo "Checking out to ${WORKDIR}..."
-cd $WORKDIR
-svn export -r ${SVNREV} ${URL}/extras/dispatch ${BASENAME} >/dev/null
-
-echo "Building source tarball..."
-cd $WORKDIR
-tar --exclude release.sh -zcvf $FILENAME ${BASENAME} >/dev/null
-)
-
-echo "Done!"
diff --git a/extras/dispatch/router/CMakeLists.txt b/extras/dispatch/router/CMakeLists.txt
deleted file mode 100644
index 388e0d7119..0000000000
--- a/extras/dispatch/router/CMakeLists.txt
+++ /dev/null
@@ -1,38 +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.
-##
-
-
-set(DEFAULT_CONFIG_PATH "/etc/qpid/qpid-dispatch.conf" CACHE string "Default Config File Path")
-
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-##
-## Build the router application
-##
-set(router_SOURCES
- src/main.c
- )
-
-add_executable(dispatch-router ${router_SOURCES})
-target_link_libraries(dispatch-router qpid-dispatch ${proton_lib})
-
-install(TARGETS dispatch-router RUNTIME DESTINATION bin)
-
diff --git a/extras/dispatch/router/src/config.h.in b/extras/dispatch/router/src/config.h.in
deleted file mode 100644
index dab91c5004..0000000000
--- a/extras/dispatch/router/src/config.h.in
+++ /dev/null
@@ -1,21 +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.
- */
-
-#cmakedefine DEFAULT_CONFIG_PATH "${DEFAULT_CONFIG_PATH}"
-
diff --git a/extras/dispatch/router/src/main.c b/extras/dispatch/router/src/main.c
deleted file mode 100644
index e0d6849d1b..0000000000
--- a/extras/dispatch/router/src/main.c
+++ /dev/null
@@ -1,145 +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 <stdio.h>
-#include <qpid/dispatch.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <getopt.h>
-#include "config.h"
-
-static int exit_with_sigint = 0;
-static dx_dispatch_t *dispatch;
-
-
-/**
- * The thread_start_handler is invoked once for each server thread at thread startup.
- */
-static void thread_start_handler(void* context, int thread_id)
-{
-}
-
-
-/**
- * This is the OS signal handler, invoked on an undetermined thread at a completely
- * arbitrary point of time. It is not safe to do anything here but signal the dispatch
- * server with the signal number.
- */
-static void signal_handler(int signum)
-{
- dx_server_signal(dispatch, signum);
-}
-
-
-/**
- * This signal handler is called cleanly by one of the server's worker threads in
- * response to an earlier call to dx_server_signal.
- */
-static void server_signal_handler(void* context, int signum)
-{
- dx_server_pause(dispatch);
-
- switch (signum) {
- case SIGINT:
- exit_with_sigint = 1;
-
- case SIGQUIT:
- case SIGTERM:
- fflush(stdout);
- dx_server_stop(dispatch);
- break;
-
- case SIGHUP:
- break;
-
- default:
- break;
- }
-
- dx_server_resume(dispatch);
-}
-
-
-static void startup(void *context)
-{
- dx_server_pause(dispatch);
- dx_dispatch_configure(dispatch);
- dx_server_resume(dispatch);
-}
-
-
-int main(int argc, char **argv)
-{
- const char *config_path = DEFAULT_CONFIG_PATH;
-
- static struct option long_options[] = {
- {"config", required_argument, 0, 'c'},
- {"help", no_argument, 0, 'h'},
- {0, 0, 0, 0}
- };
-
- while (1) {
- int c = getopt_long(argc, argv, "c:h", long_options, 0);
- if (c == -1)
- break;
-
- switch (c) {
- case 'c' :
- config_path = optarg;
- break;
-
- case 'h' :
- printf("Usage: %s [OPTION]\n\n", argv[0]);
- printf(" -c, --config=PATH (%s)\n", DEFAULT_CONFIG_PATH);
- printf(" Load configuration from file at PATH\n");
- printf(" -h, --help Print this help\n");
- exit(0);
-
- case '?' :
- exit(1);
- }
- }
-
- dx_log_set_mask(0xFFFFFFFE);
-
- dispatch = dx_dispatch(config_path);
-
- dx_server_set_signal_handler(dispatch, server_signal_handler, 0);
- dx_server_set_start_handler(dispatch, thread_start_handler, 0);
-
- dx_timer_t *startup_timer = dx_timer(dispatch, startup, 0);
- dx_timer_schedule(startup_timer, 0);
-
- signal(SIGHUP, signal_handler);
- signal(SIGQUIT, signal_handler);
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
-
- dx_server_run(dispatch);
- dx_dispatch_free(dispatch);
-
- if (exit_with_sigint) {
- signal(SIGINT, SIG_DFL);
- kill(getpid(), SIGINT);
- }
-
- return 0;
-}
-
diff --git a/extras/dispatch/src/agent.c b/extras/dispatch/src/agent.c
deleted file mode 100644
index 784c333ec4..0000000000
--- a/extras/dispatch/src/agent.c
+++ /dev/null
@@ -1,525 +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 "dispatch_private.h"
-#include <qpid/dispatch/error.h>
-#include <qpid/dispatch/agent.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/hash.h>
-#include <qpid/dispatch/container.h>
-#include <qpid/dispatch/message.h>
-#include <qpid/dispatch/threading.h>
-#include <qpid/dispatch/timer.h>
-#include <qpid/dispatch/router.h>
-#include <qpid/dispatch/log.h>
-#include <qpid/dispatch/compose.h>
-#include <qpid/dispatch/parse.h>
-#include <qpid/dispatch/amqp.h>
-#include <string.h>
-#include <stdio.h>
-
-struct dx_agent_class_t {
- DEQ_LINKS(dx_agent_class_t);
- dx_hash_handle_t *hash_handle;
- void *context;
- dx_agent_schema_cb_t schema_handler;
- dx_agent_query_cb_t query_handler; // 0 iff class is an event.
-};
-
-DEQ_DECLARE(dx_agent_class_t, dx_agent_class_list_t);
-
-
-struct dx_agent_t {
- dx_dispatch_t *dx;
- dx_hash_t *class_hash;
- dx_agent_class_list_t class_list;
- dx_message_list_t in_fifo;
- dx_message_list_t out_fifo;
- sys_mutex_t *lock;
- dx_timer_t *timer;
- dx_address_t *address;
- dx_agent_class_t *container_class;
-};
-
-
-typedef struct {
- dx_agent_t *agent;
- dx_composed_field_t *response;
-} dx_agent_request_t;
-
-
-static char *log_module = "AGENT";
-
-
-static dx_composed_field_t *dx_agent_setup_response(dx_field_iterator_t *reply_to)
-{
- //
- // Compose the header
- //
- dx_composed_field_t *field = dx_compose(DX_PERFORMATIVE_HEADER, 0);
- dx_compose_start_list(field);
- dx_compose_insert_bool(field, 0); // durable
- dx_compose_end_list(field);
-
- //
- // Compose the Properties
- //
- field = dx_compose(DX_PERFORMATIVE_PROPERTIES, field);
- dx_compose_start_list(field);
- dx_compose_insert_null(field); // message-id
- dx_compose_insert_null(field); // user-id
- dx_compose_insert_string_iterator(field, reply_to); // to
- dx_compose_insert_null(field); // subject
- dx_compose_insert_null(field); // reply-to
- dx_compose_insert_string(field, "1"); // correlation-id // TODO - fix
- dx_compose_end_list(field);
-
- //
- // Compose the Application Properties
- //
- field = dx_compose(DX_PERFORMATIVE_APPLICATION_PROPERTIES, field);
- dx_compose_start_map(field);
- dx_compose_insert_string(field, "status-code");
- dx_compose_insert_uint(field, 200);
-
- dx_compose_insert_string(field, "status-descriptor");
- dx_compose_insert_string(field, "OK");
- dx_compose_end_map(field);
-
- return field;
-}
-
-
-static void dx_agent_process_get(dx_agent_t *agent, dx_parsed_field_t *map, dx_field_iterator_t *reply_to)
-{
- dx_parsed_field_t *cls = dx_parse_value_by_key(map, "type");
- if (cls == 0)
- return;
-
- dx_field_iterator_t *cls_string = dx_parse_raw(cls);
- const dx_agent_class_t *cls_record;
- dx_hash_retrieve_const(agent->class_hash, cls_string, (const void**) &cls_record);
- if (cls_record == 0)
- return;
-
- dx_log(log_module, LOG_TRACE, "Received GET request for type: %s", dx_hash_key_by_handle(cls_record->hash_handle));
-
- dx_composed_field_t *field = dx_agent_setup_response(reply_to);
-
- //
- // Open the Body (AMQP Value) to be filled in by the handler.
- //
- field = dx_compose(DX_PERFORMATIVE_BODY_AMQP_VALUE, field);
- dx_compose_start_list(field);
- dx_compose_start_map(field);
-
- //
- // The request record is allocated locally because the entire processing of the request
- // will be done synchronously.
- //
- dx_agent_request_t request;
- request.agent = agent;
- request.response = field;
-
- cls_record->query_handler(cls_record->context, 0, &request);
-
- //
- // The response is complete, close the list.
- //
- dx_compose_end_list(field);
-
- //
- // Create a message and send it.
- //
- dx_message_t *msg = dx_message();
- dx_message_compose_2(msg, field);
- dx_router_send(agent->dx, reply_to, msg);
-
- dx_message_free(msg);
- dx_compose_free(field);
-}
-
-
-static void dx_agent_process_discover_types(dx_agent_t *agent, dx_parsed_field_t *map, dx_field_iterator_t *reply_to)
-{
- dx_log(log_module, LOG_TRACE, "Received DISCOVER-TYPES request");
-
- dx_composed_field_t *field = dx_agent_setup_response(reply_to);
-
- //
- // Open the Body (AMQP Value) to be filled in by the handler.
- //
- field = dx_compose(DX_PERFORMATIVE_BODY_AMQP_VALUE, field);
- dx_compose_start_map(field);
-
- //
- // Put entries into the map for each known entity type
- //
- sys_mutex_lock(agent->lock);
- dx_agent_class_t *cls = DEQ_HEAD(agent->class_list);
- while (cls) {
- dx_compose_insert_string(field, (const char*) dx_hash_key_by_handle(cls->hash_handle));
- dx_compose_insert_null(field); // TODO - https://tools.oasis-open.org/issues/browse/AMQP-87
- cls = DEQ_NEXT(cls);
- }
- sys_mutex_unlock(agent->lock);
- dx_compose_end_map(field);
-
- //
- // Create a message and send it.
- //
- dx_message_t *msg = dx_message();
- dx_message_compose_2(msg, field);
- dx_router_send(agent->dx, reply_to, msg);
-
- dx_message_free(msg);
- dx_compose_free(field);
-}
-
-
-static void dx_agent_process_discover_operations(dx_agent_t *agent, dx_parsed_field_t *map, dx_field_iterator_t *reply_to)
-{
- dx_log(log_module, LOG_TRACE, "Received DISCOVER-OPERATIONS request");
-
- dx_composed_field_t *field = dx_agent_setup_response(reply_to);
-
- //
- // Open the Body (AMQP Value) to be filled in by the handler.
- //
- field = dx_compose(DX_PERFORMATIVE_BODY_AMQP_VALUE, field);
- dx_compose_start_map(field);
-
- //
- // Put entries into the map for each known entity type
- //
- sys_mutex_lock(agent->lock);
- dx_agent_class_t *cls = DEQ_HEAD(agent->class_list);
- while (cls) {
- dx_compose_insert_string(field, (const char*) dx_hash_key_by_handle(cls->hash_handle));
- dx_compose_start_list(field);
- dx_compose_insert_string(field, "READ");
- dx_compose_end_list(field);
- cls = DEQ_NEXT(cls);
- }
- sys_mutex_unlock(agent->lock);
- dx_compose_end_map(field);
-
- //
- // Create a message and send it.
- //
- dx_message_t *msg = dx_message();
- dx_message_compose_2(msg, field);
- dx_router_send(agent->dx, reply_to, msg);
-
- dx_message_free(msg);
- dx_compose_free(field);
-}
-
-
-static void dx_agent_process_discover_nodes(dx_agent_t *agent, dx_parsed_field_t *map, dx_field_iterator_t *reply_to)
-{
- dx_log(log_module, LOG_TRACE, "Received DISCOVER-MGMT-NODES request");
-
- dx_composed_field_t *field = dx_agent_setup_response(reply_to);
-
- //
- // Open the Body (AMQP Value) to be filled in by the handler.
- //
- field = dx_compose(DX_PERFORMATIVE_BODY_AMQP_VALUE, field);
-
- //
- // Put entries into the list for each known management node
- //
- dx_compose_start_list(field);
- dx_compose_insert_string(field, "amqp:/_local/$management");
- dx_router_build_node_list(agent->dx, field);
- dx_compose_end_list(field);
-
- //
- // Create a message and send it.
- //
- dx_message_t *msg = dx_message();
- dx_message_compose_2(msg, field);
- dx_router_send(agent->dx, reply_to, msg);
-
- dx_message_free(msg);
- dx_compose_free(field);
-}
-
-
-static void dx_agent_process_request(dx_agent_t *agent, dx_message_t *msg)
-{
- //
- // Parse the message through the body and exit if the message is not well formed.
- //
- if (!dx_message_check(msg, DX_DEPTH_BODY))
- return;
-
- //
- // Get an iterator for the application-properties. Exit if the message has none.
- //
- dx_field_iterator_t *ap = dx_message_field_iterator(msg, DX_FIELD_APPLICATION_PROPERTIES);
- if (ap == 0)
- return;
-
- //
- // Get an iterator for the reply-to. Exit if not found.
- //
- dx_field_iterator_t *reply_to = dx_message_field_iterator(msg, DX_FIELD_REPLY_TO);
- if (reply_to == 0)
- return;
-
- //
- // Try to get a map-view of the application-properties.
- //
- dx_parsed_field_t *map = dx_parse(ap);
- if (map == 0) {
- dx_field_iterator_free(ap);
- return;
- }
-
- //
- // Exit if there was a parsing error.
- //
- if (!dx_parse_ok(map)) {
- dx_log(log_module, LOG_TRACE, "Received unparsable App Properties: %s", dx_parse_error(map));
- dx_field_iterator_free(ap);
- dx_parse_free(map);
- return;
- }
-
- //
- // Exit if it is not a map.
- //
- if (!dx_parse_is_map(map)) {
- dx_field_iterator_free(ap);
- dx_parse_free(map);
- return;
- }
-
- //
- // Get an iterator for the "operation" field in the map. Exit if the key is not found.
- //
- dx_parsed_field_t *operation = dx_parse_value_by_key(map, "operation");
- if (operation == 0) {
- dx_parse_free(map);
- dx_field_iterator_free(ap);
- return;
- }
-
- //
- // Dispatch the operation to the appropriate handler
- //
- dx_field_iterator_t *operation_string = dx_parse_raw(operation);
- if (dx_field_iterator_equal(operation_string, (unsigned char*) "GET"))
- dx_agent_process_get(agent, map, reply_to);
- if (dx_field_iterator_equal(operation_string, (unsigned char*) "DISCOVER-TYPES"))
- dx_agent_process_discover_types(agent, map, reply_to);
- if (dx_field_iterator_equal(operation_string, (unsigned char*) "DISCOVER-OPERATIONS"))
- dx_agent_process_discover_operations(agent, map, reply_to);
- if (dx_field_iterator_equal(operation_string, (unsigned char*) "DISCOVER-MGMT-NODES"))
- dx_agent_process_discover_nodes(agent, map, reply_to);
-
- dx_parse_free(map);
- dx_field_iterator_free(ap);
- dx_field_iterator_free(reply_to);
-}
-
-
-static void dx_agent_deferred_handler(void *context)
-{
- dx_agent_t *agent = (dx_agent_t*) context;
- dx_message_t *msg;
-
- do {
- sys_mutex_lock(agent->lock);
- msg = DEQ_HEAD(agent->in_fifo);
- if (msg)
- DEQ_REMOVE_HEAD(agent->in_fifo);
- sys_mutex_unlock(agent->lock);
-
- if (msg) {
- dx_agent_process_request(agent, msg);
- dx_message_free(msg);
- }
- } while (msg);
-}
-
-
-static void dx_agent_rx_handler(void *context, dx_message_t *msg, int unused_link_id)
-{
- dx_agent_t *agent = (dx_agent_t*) context;
- dx_message_t *copy = dx_message_copy(msg);
-
- sys_mutex_lock(agent->lock);
- DEQ_INSERT_TAIL(agent->in_fifo, copy);
- sys_mutex_unlock(agent->lock);
-
- dx_timer_schedule(agent->timer, 0);
-}
-
-
-static dx_agent_class_t *dx_agent_register_class_LH(dx_agent_t *agent,
- const char *fqname,
- void *context,
- dx_agent_schema_cb_t schema_handler,
- dx_agent_query_cb_t query_handler)
-{
- dx_agent_class_t *cls = NEW(dx_agent_class_t);
- assert(cls);
- DEQ_ITEM_INIT(cls);
- cls->context = context;
- cls->schema_handler = schema_handler;
- cls->query_handler = query_handler;
-
- dx_field_iterator_t *iter = dx_field_iterator_string(fqname, ITER_VIEW_ALL);
- int result = dx_hash_insert_const(agent->class_hash, iter, cls, &cls->hash_handle);
- dx_field_iterator_free(iter);
- if (result < 0)
- assert(false);
-
- DEQ_INSERT_TAIL(agent->class_list, cls);
-
- dx_log(log_module, LOG_INFO, "Manageable Entity Type (%s) %s", query_handler ? "object" : "event", fqname);
- return cls;
-}
-
-
-dx_agent_t *dx_agent(dx_dispatch_t *dx)
-{
- dx_agent_t *agent = NEW(dx_agent_t);
- agent->dx = dx;
- agent->class_hash = dx_hash(6, 10, 1);
- DEQ_INIT(agent->class_list);
- DEQ_INIT(agent->in_fifo);
- DEQ_INIT(agent->out_fifo);
- agent->lock = sys_mutex();
- agent->timer = dx_timer(dx, dx_agent_deferred_handler, agent);
- agent->address = dx_router_register_address(dx, "$management", dx_agent_rx_handler, agent);
-
- return agent;
-}
-
-
-void dx_agent_free(dx_agent_t *agent)
-{
- dx_router_unregister_address(agent->address);
- sys_mutex_free(agent->lock);
- dx_timer_free(agent->timer);
- dx_hash_free(agent->class_hash);
- free(agent);
-}
-
-
-dx_agent_class_t *dx_agent_register_class(dx_dispatch_t *dx,
- const char *fqname,
- void *context,
- dx_agent_schema_cb_t schema_handler,
- dx_agent_query_cb_t query_handler)
-{
- dx_agent_t *agent = dx->agent;
- dx_agent_class_t *cls;
-
- sys_mutex_lock(agent->lock);
- cls = dx_agent_register_class_LH(agent, fqname, context, schema_handler, query_handler);
- sys_mutex_unlock(agent->lock);
- return cls;
-}
-
-
-dx_agent_class_t *dx_agent_register_event(dx_dispatch_t *dx,
- const char *fqname,
- void *context,
- dx_agent_schema_cb_t schema_handler)
-{
- return dx_agent_register_class(dx, fqname, context, schema_handler, 0);
-}
-
-
-void dx_agent_value_string(void *correlator, const char *key, const char *value)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_insert_string(request->response, key);
- dx_compose_insert_string(request->response, value);
-}
-
-
-void dx_agent_value_uint(void *correlator, const char *key, uint64_t value)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_insert_string(request->response, key);
- dx_compose_insert_uint(request->response, value);
-}
-
-
-void dx_agent_value_null(void *correlator, const char *key)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_insert_string(request->response, key);
- dx_compose_insert_null(request->response);
-}
-
-
-void dx_agent_value_boolean(void *correlator, const char *key, bool value)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_insert_string(request->response, key);
- dx_compose_insert_bool(request->response, value);
-}
-
-
-void dx_agent_value_binary(void *correlator, const char *key, const uint8_t *value, size_t len)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_insert_string(request->response, key);
- dx_compose_insert_binary(request->response, value, len);
-}
-
-
-void dx_agent_value_uuid(void *correlator, const char *key, const uint8_t *value)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_insert_string(request->response, key);
- dx_compose_insert_uuid(request->response, value);
-}
-
-
-void dx_agent_value_timestamp(void *correlator, const char *key, uint64_t value)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_insert_string(request->response, key);
- dx_compose_insert_timestamp(request->response, value);
-}
-
-
-void dx_agent_value_complete(void *correlator, bool more)
-{
- dx_agent_request_t *request = (dx_agent_request_t*) correlator;
- dx_compose_end_map(request->response);
- if (more)
- dx_compose_start_map(request->response);
-}
-
-
-void *dx_agent_raise_event(dx_dispatch_t *dx, dx_agent_class_t *event)
-{
- return 0;
-}
-
diff --git a/extras/dispatch/src/alloc.c b/extras/dispatch/src/alloc.c
deleted file mode 100644
index bf10f03633..0000000000
--- a/extras/dispatch/src/alloc.c
+++ /dev/null
@@ -1,253 +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/dispatch/alloc.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/log.h>
-#include <qpid/dispatch/agent.h>
-#include <memory.h>
-#include <stdio.h>
-
-typedef struct dx_alloc_type_t dx_alloc_type_t;
-typedef struct dx_alloc_item_t dx_alloc_item_t;
-
-struct dx_alloc_type_t {
- DEQ_LINKS(dx_alloc_type_t);
- dx_alloc_type_desc_t *desc;
-};
-
-DEQ_DECLARE(dx_alloc_type_t, dx_alloc_type_list_t);
-
-
-struct dx_alloc_item_t {
- DEQ_LINKS(dx_alloc_item_t);
-};
-
-DEQ_DECLARE(dx_alloc_item_t, dx_alloc_item_list_t);
-
-
-struct dx_alloc_pool_t {
- dx_alloc_item_list_t free_list;
-};
-
-dx_alloc_config_t dx_alloc_default_config_big = {16, 32, 0};
-dx_alloc_config_t dx_alloc_default_config_small = {64, 128, 0};
-#define BIG_THRESHOLD 256
-
-static sys_mutex_t *init_lock;
-static dx_alloc_type_list_t type_list;
-
-static void dx_alloc_init(dx_alloc_type_desc_t *desc)
-{
- sys_mutex_lock(init_lock);
-
- desc->total_size = desc->type_size;
- if (desc->additional_size)
- desc->total_size += *desc->additional_size;
-
- //dx_log("ALLOC", LOG_TRACE, "Initialized Allocator - type=%s type-size=%d total-size=%d",
- // desc->type_name, desc->type_size, desc->total_size);
-
- if (!desc->global_pool) {
- if (desc->config == 0)
- desc->config = desc->total_size > BIG_THRESHOLD ?
- &dx_alloc_default_config_big : &dx_alloc_default_config_small;
-
- assert (desc->config->local_free_list_max >= desc->config->transfer_batch_size);
-
- desc->global_pool = NEW(dx_alloc_pool_t);
- DEQ_INIT(desc->global_pool->free_list);
- desc->lock = sys_mutex();
- desc->stats = NEW(dx_alloc_stats_t);
- memset(desc->stats, 0, sizeof(dx_alloc_stats_t));
-
- dx_alloc_type_t *type_item = NEW(dx_alloc_type_t);
- DEQ_ITEM_INIT(type_item);
- type_item->desc = desc;
- DEQ_INSERT_TAIL(type_list, type_item);
- }
-
- sys_mutex_unlock(init_lock);
-}
-
-
-void *dx_alloc(dx_alloc_type_desc_t *desc, dx_alloc_pool_t **tpool)
-{
- int idx;
-
- //
- // If the descriptor is not initialized, set it up now.
- //
- if (!desc->global_pool)
- dx_alloc_init(desc);
-
- //
- // If this is the thread's first pass through here, allocate the
- // thread-local pool for this type.
- //
- if (*tpool == 0) {
- *tpool = NEW(dx_alloc_pool_t);
- DEQ_INIT((*tpool)->free_list);
- }
-
- dx_alloc_pool_t *pool = *tpool;
-
- //
- // Fast case: If there's an item on the local free list, take it off the
- // list and return it. Since everything we've touched is thread-local,
- // there is no need to acquire a lock.
- //
- dx_alloc_item_t *item = DEQ_HEAD(pool->free_list);
- if (item) {
- DEQ_REMOVE_HEAD(pool->free_list);
- return &item[1];
- }
-
- //
- // The local free list is empty, we need to either rebalance a batch
- // of items from the global list or go to the heap to get new memory.
- //
- sys_mutex_lock(desc->lock);
- if (DEQ_SIZE(desc->global_pool->free_list) >= desc->config->transfer_batch_size) {
- //
- // Rebalance a full batch from the global free list to the thread list.
- //
- desc->stats->batches_rebalanced_to_threads++;
- desc->stats->held_by_threads += desc->config->transfer_batch_size;
- for (idx = 0; idx < desc->config->transfer_batch_size; idx++) {
- item = DEQ_HEAD(desc->global_pool->free_list);
- DEQ_REMOVE_HEAD(desc->global_pool->free_list);
- DEQ_INSERT_TAIL(pool->free_list, item);
- }
- } else {
- //
- // Allocate a full batch from the heap and put it on the thread list.
- //
- for (idx = 0; idx < desc->config->transfer_batch_size; idx++) {
- item = (dx_alloc_item_t*) malloc(sizeof(dx_alloc_item_t) + desc->total_size);
- if (item == 0)
- break;
- DEQ_ITEM_INIT(item);
- DEQ_INSERT_TAIL(pool->free_list, item);
- desc->stats->held_by_threads++;
- desc->stats->total_alloc_from_heap++;
- }
- }
- sys_mutex_unlock(desc->lock);
-
- item = DEQ_HEAD(pool->free_list);
- if (item) {
- DEQ_REMOVE_HEAD(pool->free_list);
- return &item[1];
- }
-
- return 0;
-}
-
-
-void dx_dealloc(dx_alloc_type_desc_t *desc, dx_alloc_pool_t **tpool, void *p)
-{
- dx_alloc_item_t *item = ((dx_alloc_item_t*) p) - 1;
- int idx;
-
- //
- // If this is the thread's first pass through here, allocate the
- // thread-local pool for this type.
- //
- if (*tpool == 0) {
- *tpool = NEW(dx_alloc_pool_t);
- DEQ_INIT((*tpool)->free_list);
- }
-
- dx_alloc_pool_t *pool = *tpool;
-
- DEQ_INSERT_TAIL(pool->free_list, item);
-
- if (DEQ_SIZE(pool->free_list) <= desc->config->local_free_list_max)
- return;
-
- //
- // We've exceeded the maximum size of the local free list. A batch must be
- // rebalanced back to the global list.
- //
- sys_mutex_lock(desc->lock);
- desc->stats->batches_rebalanced_to_global++;
- desc->stats->held_by_threads -= desc->config->transfer_batch_size;
- for (idx = 0; idx < desc->config->transfer_batch_size; idx++) {
- item = DEQ_HEAD(pool->free_list);
- DEQ_REMOVE_HEAD(pool->free_list);
- DEQ_INSERT_TAIL(desc->global_pool->free_list, item);
- }
-
- //
- // If there's a global_free_list size limit, remove items until the limit is
- // not exceeded.
- //
- if (desc->config->global_free_list_max != 0) {
- while (DEQ_SIZE(desc->global_pool->free_list) > desc->config->global_free_list_max) {
- item = DEQ_HEAD(desc->global_pool->free_list);
- DEQ_REMOVE_HEAD(desc->global_pool->free_list);
- free(item);
- desc->stats->total_free_to_heap++;
- }
- }
-
- sys_mutex_unlock(desc->lock);
-}
-
-
-void dx_alloc_initialize(void)
-{
- init_lock = sys_mutex();
- DEQ_INIT(type_list);
-}
-
-
-static void alloc_schema_handler(void *context, void *correlator)
-{
-}
-
-
-static void alloc_query_handler(void* context, const char *id, void *cor)
-{
- dx_alloc_type_t *item = DEQ_HEAD(type_list);
-
- while (item) {
- dx_agent_value_string(cor, "name", item->desc->type_name);
- dx_agent_value_uint(cor, "type_size", item->desc->total_size);
- dx_agent_value_uint(cor, "transfer_batch_size", item->desc->config->transfer_batch_size);
- dx_agent_value_uint(cor, "local_free_list_max", item->desc->config->local_free_list_max);
- dx_agent_value_uint(cor, "global_free_list_max", item->desc->config->global_free_list_max);
- dx_agent_value_uint(cor, "total_alloc_from_heap", item->desc->stats->total_alloc_from_heap);
- dx_agent_value_uint(cor, "total_free_to_heap", item->desc->stats->total_free_to_heap);
- dx_agent_value_uint(cor, "held_by_threads", item->desc->stats->held_by_threads);
- dx_agent_value_uint(cor, "batches_rebalanced_to_threads", item->desc->stats->batches_rebalanced_to_threads);
- dx_agent_value_uint(cor, "batches_rebalanced_to_global", item->desc->stats->batches_rebalanced_to_global);
-
- item = DEQ_NEXT(item);
- dx_agent_value_complete(cor, item != 0);
- }
-}
-
-
-void dx_alloc_setup_agent(dx_dispatch_t *dx)
-{
- dx_agent_register_class(dx, "org.apache.qpid.dispatch.allocator", 0, alloc_schema_handler, alloc_query_handler);
-}
-
diff --git a/extras/dispatch/src/alloc_private.h b/extras/dispatch/src/alloc_private.h
deleted file mode 100644
index da773fef25..0000000000
--- a/extras/dispatch/src/alloc_private.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef __dispatch_alloc_private_h__
-#define __dispatch_alloc_private_h__ 1
-/*
- * 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/dispatch/alloc.h>
-#include <qpid/dispatch/dispatch.h>
-
-void dx_alloc_initialize(void);
-void dx_alloc_setup_agent(dx_dispatch_t *dx);
-
-#endif
diff --git a/extras/dispatch/src/amqp.c b/extras/dispatch/src/amqp.c
deleted file mode 100644
index 6a8545b757..0000000000
--- a/extras/dispatch/src/amqp.c
+++ /dev/null
@@ -1,30 +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/dispatch/amqp.h>
-
-const char * const DX_DA_INGRESS = "qdx.ingress";
-const char * const DX_DA_TRACE = "qdx.trace";
-const char * const DX_DA_TO = "qdx.to";
-
-const char * const DX_CAPABILITY_ROUTER = "qdx.router";
-
-const char * const DX_INTERNODE_LINK_NAME_1 = "qdx.internode.1";
-const char * const DX_INTERNODE_LINK_NAME_2 = "qdx.internode.2";
-
diff --git a/extras/dispatch/src/bitmask.c b/extras/dispatch/src/bitmask.c
deleted file mode 100644
index 88ba69dde1..0000000000
--- a/extras/dispatch/src/bitmask.c
+++ /dev/null
@@ -1,124 +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/dispatch/bitmask.h>
-#include <qpid/dispatch/alloc.h>
-#include <assert.h>
-
-#define DX_BITMASK_LONGS 16
-#define DX_BITMASK_BITS (DX_BITMASK_LONGS * 64)
-
-struct dx_bitmask_t {
- uint64_t array[DX_BITMASK_LONGS];
- int first_set;
-};
-
-ALLOC_DECLARE(dx_bitmask_t);
-ALLOC_DEFINE(dx_bitmask_t);
-
-#define MASK_INDEX(num) (num / 64)
-#define MASK_ONEHOT(num) (((uint64_t) 1) << (num % 64))
-#define FIRST_NONE -1
-#define FIRST_UNKNOWN -2
-
-
-int dx_bitmask_width()
-{
- return DX_BITMASK_BITS;
-}
-
-
-dx_bitmask_t *dx_bitmask(int initial)
-{
- dx_bitmask_t *b = new_dx_bitmask_t();
- if (initial)
- dx_bitmask_set_all(b);
- else
- dx_bitmask_clear_all(b);
- return b;
-}
-
-
-void dx_bitmask_free(dx_bitmask_t *b)
-{
- free_dx_bitmask_t(b);
-}
-
-
-void dx_bitmask_set_all(dx_bitmask_t *b)
-{
- for (int i = 0; i < DX_BITMASK_LONGS; i++)
- b->array[i] = 0xFFFFFFFFFFFFFFFF;
- b->first_set = 0;
-}
-
-
-void dx_bitmask_clear_all(dx_bitmask_t *b)
-{
- for (int i = 0; i < DX_BITMASK_LONGS; i++)
- b->array[i] = 0;
- b->first_set = FIRST_NONE;
-}
-
-
-void dx_bitmask_set_bit(dx_bitmask_t *b, int bitnum)
-{
- assert(bitnum < DX_BITMASK_BITS);
- b->array[MASK_INDEX(bitnum)] |= MASK_ONEHOT(bitnum);
- if (b->first_set > bitnum || b->first_set < 0)
- b->first_set = bitnum;
-}
-
-
-void dx_bitmask_clear_bit(dx_bitmask_t *b, int bitnum)
-{
- assert(bitnum < DX_BITMASK_BITS);
- b->array[MASK_INDEX(bitnum)] &= ~(MASK_ONEHOT(bitnum));
- if (b->first_set == bitnum)
- b->first_set = FIRST_UNKNOWN;
-}
-
-
-int dx_bitmask_value(dx_bitmask_t *b, int bitnum)
-{
- return (b->array[MASK_INDEX(bitnum)] & MASK_ONEHOT(bitnum)) ? 1 : 0;
-}
-
-
-int dx_bitmask_first_set(dx_bitmask_t *b, int *bitnum)
-{
- if (b->first_set == FIRST_UNKNOWN) {
- b->first_set = FIRST_NONE;
- for (int i = 0; i < DX_BITMASK_LONGS; i++)
- if (b->array[i]) {
- for (int j = 0; j < 64; j++)
- if ((((uint64_t) 1) << j) & b->array[i]) {
- b->first_set = i * 64 + j;
- break;
- }
- break;
- }
- }
-
- if (b->first_set == FIRST_NONE)
- return 0;
- *bitnum = b->first_set;
- return 1;
-}
-
diff --git a/extras/dispatch/src/buffer.c b/extras/dispatch/src/buffer.c
deleted file mode 100644
index d0bbd13cb3..0000000000
--- a/extras/dispatch/src/buffer.c
+++ /dev/null
@@ -1,83 +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/dispatch/buffer.h>
-#include <qpid/dispatch/alloc.h>
-
-static size_t buffer_size = 512;
-static int size_locked = 0;
-
-ALLOC_DECLARE(dx_buffer_t);
-ALLOC_DEFINE_CONFIG(dx_buffer_t, sizeof(dx_buffer_t), &buffer_size, 0);
-
-
-void dx_buffer_set_size(size_t size)
-{
- assert(!size_locked);
- buffer_size = size;
-}
-
-
-dx_buffer_t *dx_buffer(void)
-{
- size_locked = 1;
- dx_buffer_t *buf = new_dx_buffer_t();
-
- DEQ_ITEM_INIT(buf);
- buf->size = 0;
- return buf;
-}
-
-
-void dx_buffer_free(dx_buffer_t *buf)
-{
- free_dx_buffer_t(buf);
-}
-
-
-unsigned char *dx_buffer_base(dx_buffer_t *buf)
-{
- return (unsigned char*) &buf[1];
-}
-
-
-unsigned char *dx_buffer_cursor(dx_buffer_t *buf)
-{
- return ((unsigned char*) &buf[1]) + buf->size;
-}
-
-
-size_t dx_buffer_capacity(dx_buffer_t *buf)
-{
- return buffer_size - buf->size;
-}
-
-
-size_t dx_buffer_size(dx_buffer_t *buf)
-{
- return buf->size;
-}
-
-
-void dx_buffer_insert(dx_buffer_t *buf, size_t len)
-{
- buf->size += len;
- assert(buf->size <= buffer_size);
-}
-
diff --git a/extras/dispatch/src/compose.c b/extras/dispatch/src/compose.c
deleted file mode 100644
index 66b2336e06..0000000000
--- a/extras/dispatch/src/compose.c
+++ /dev/null
@@ -1,454 +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/dispatch/ctools.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/buffer.h>
-#include <qpid/dispatch/amqp.h>
-#include "compose_private.h"
-#include <memory.h>
-
-ALLOC_DEFINE(dx_composite_t);
-ALLOC_DEFINE(dx_composed_field_t);
-
-
-static void bump_count(dx_composed_field_t *field)
-{
- dx_composite_t *comp = DEQ_HEAD(field->fieldStack);
- if (comp)
- comp->count++;
-}
-
-
-static void dx_insert(dx_composed_field_t *field, const uint8_t *seq, size_t len)
-{
- dx_buffer_t *buf = DEQ_TAIL(field->buffers);
- dx_composite_t *comp = DEQ_HEAD(field->fieldStack);
-
- while (len > 0) {
- if (buf == 0 || dx_buffer_capacity(buf) == 0) {
- buf = dx_buffer();
- if (buf == 0)
- return;
- DEQ_INSERT_TAIL(field->buffers, buf);
- }
-
- size_t to_copy = dx_buffer_capacity(buf);
- if (to_copy > len)
- to_copy = len;
- memcpy(dx_buffer_cursor(buf), seq, to_copy);
- dx_buffer_insert(buf, to_copy);
- len -= to_copy;
- seq += to_copy;
- if (comp)
- comp->length += to_copy;
- }
-}
-
-
-static void dx_insert_8(dx_composed_field_t *field, uint8_t value)
-{
- dx_insert(field, &value, 1);
-}
-
-
-static void dx_insert_32(dx_composed_field_t *field, uint32_t value)
-{
- uint8_t buf[4];
- buf[0] = (uint8_t) ((value & 0xFF000000) >> 24);
- buf[1] = (uint8_t) ((value & 0x00FF0000) >> 16);
- buf[2] = (uint8_t) ((value & 0x0000FF00) >> 8);
- buf[3] = (uint8_t) (value & 0x000000FF);
- dx_insert(field, buf, 4);
-}
-
-
-static void dx_insert_64(dx_composed_field_t *field, uint64_t value)
-{
- uint8_t buf[8];
- buf[0] = (uint8_t) ((value & 0xFF00000000000000L) >> 56);
- buf[1] = (uint8_t) ((value & 0x00FF000000000000L) >> 48);
- buf[2] = (uint8_t) ((value & 0x0000FF0000000000L) >> 40);
- buf[3] = (uint8_t) ((value & 0x000000FF00000000L) >> 32);
- buf[4] = (uint8_t) ((value & 0x00000000FF000000L) >> 24);
- buf[5] = (uint8_t) ((value & 0x0000000000FF0000L) >> 16);
- buf[6] = (uint8_t) ((value & 0x000000000000FF00L) >> 8);
- buf[7] = (uint8_t) (value & 0x00000000000000FFL);
- dx_insert(field, buf, 8);
-}
-
-
-static void dx_overwrite(dx_buffer_t **buf, size_t *cursor, uint8_t value)
-{
- while (*buf) {
- if (*cursor >= dx_buffer_size(*buf)) {
- *buf = (*buf)->next;
- *cursor = 0;
- } else {
- dx_buffer_base(*buf)[*cursor] = value;
- (*cursor)++;
- return;
- }
- }
-}
-
-
-static void dx_overwrite_32(dx_field_location_t *field, uint32_t value)
-{
- dx_buffer_t *buf = field->buffer;
- size_t cursor = field->offset;
-
- dx_overwrite(&buf, &cursor, (uint8_t) ((value & 0xFF000000) >> 24));
- dx_overwrite(&buf, &cursor, (uint8_t) ((value & 0x00FF0000) >> 16));
- dx_overwrite(&buf, &cursor, (uint8_t) ((value & 0x0000FF00) >> 8));
- dx_overwrite(&buf, &cursor, (uint8_t) (value & 0x000000FF));
-}
-
-
-static void dx_compose_start_composite(dx_composed_field_t *field, int isMap)
-{
- if (isMap)
- dx_insert_8(field, DX_AMQP_MAP32);
- else
- dx_insert_8(field, DX_AMQP_LIST32);
-
- //
- // Push a composite descriptor on the field stack
- //
- dx_composite_t *comp = new_dx_composite_t();
- DEQ_ITEM_INIT(comp);
- comp->isMap = isMap;
-
- //
- // Mark the current location to later overwrite the length
- //
- comp->length_location.buffer = DEQ_TAIL(field->buffers);
- comp->length_location.offset = dx_buffer_size(comp->length_location.buffer);
- comp->length_location.length = 4;
- comp->length_location.parsed = 1;
-
- dx_insert(field, (const uint8_t*) "\x00\x00\x00\x00", 4);
-
- //
- // Mark the current location to later overwrite the count
- //
- comp->count_location.buffer = DEQ_TAIL(field->buffers);
- comp->count_location.offset = dx_buffer_size(comp->count_location.buffer);
- comp->count_location.length = 4;
- comp->count_location.parsed = 1;
-
- dx_insert(field, (const uint8_t*) "\x00\x00\x00\x00", 4);
-
- comp->length = 4; // Include the length of the count field
- comp->count = 0;
-
- DEQ_INSERT_HEAD(field->fieldStack, comp);
-}
-
-
-static void dx_compose_end_composite(dx_composed_field_t *field)
-{
- dx_composite_t *comp = DEQ_HEAD(field->fieldStack);
- assert(comp);
-
- dx_overwrite_32(&comp->length_location, comp->length);
- dx_overwrite_32(&comp->count_location, comp->count);
-
- DEQ_REMOVE_HEAD(field->fieldStack);
-
- //
- // If there is an enclosing composite, update its length and count
- //
- dx_composite_t *enclosing = DEQ_HEAD(field->fieldStack);
- if (enclosing) {
- enclosing->length += (comp->length - 4); // the length and count were already accounted for
- enclosing->count++;
- }
-
- free_dx_composite_t(comp);
-}
-
-
-dx_composed_field_t *dx_compose(uint64_t performative, dx_composed_field_t *extend)
-{
- dx_composed_field_t *field = extend;
-
- if (field) {
- assert(DEQ_SIZE(field->fieldStack) == 0);
- } else {
- field = new_dx_composed_field_t();
- if (!field)
- return 0;
-
- DEQ_INIT(field->buffers);
- DEQ_INIT(field->fieldStack);
- }
-
- dx_insert_8(field, 0x00);
- dx_compose_insert_ulong(field, performative);
-
- return field;
-}
-
-
-void dx_compose_free(dx_composed_field_t *field)
-{
- dx_buffer_t *buf = DEQ_HEAD(field->buffers);
- while (buf) {
- DEQ_REMOVE_HEAD(field->buffers);
- dx_buffer_free(buf);
- buf = DEQ_HEAD(field->buffers);
- }
-
- dx_composite_t *comp = DEQ_HEAD(field->fieldStack);
- while (comp) {
- DEQ_REMOVE_HEAD(field->fieldStack);
- free_dx_composite_t(comp);
- comp = DEQ_HEAD(field->fieldStack);
- }
-
- free_dx_composed_field_t(field);
-}
-
-
-void dx_compose_start_list(dx_composed_field_t *field)
-{
- dx_compose_start_composite(field, 0);
-}
-
-
-void dx_compose_end_list(dx_composed_field_t *field)
-{
- dx_compose_end_composite(field);
-}
-
-
-void dx_compose_start_map(dx_composed_field_t *field)
-{
- dx_compose_start_composite(field, 1);
-}
-
-
-void dx_compose_end_map(dx_composed_field_t *field)
-{
- dx_compose_end_composite(field);
-}
-
-
-void dx_compose_insert_null(dx_composed_field_t *field)
-{
- dx_insert_8(field, DX_AMQP_NULL);
- bump_count(field);
-}
-
-
-void dx_compose_insert_bool(dx_composed_field_t *field, int value)
-{
- dx_insert_8(field, value ? DX_AMQP_TRUE : DX_AMQP_FALSE);
- bump_count(field);
-}
-
-
-void dx_compose_insert_uint(dx_composed_field_t *field, uint32_t value)
-{
- if (value == 0) {
- dx_insert_8(field, DX_AMQP_UINT0);
- } else if (value < 256) {
- dx_insert_8(field, DX_AMQP_SMALLUINT);
- dx_insert_8(field, (uint8_t) value);
- } else {
- dx_insert_8(field, DX_AMQP_UINT);
- dx_insert_32(field, value);
- }
- bump_count(field);
-}
-
-
-void dx_compose_insert_ulong(dx_composed_field_t *field, uint64_t value)
-{
- if (value == 0) {
- dx_insert_8(field, DX_AMQP_ULONG0);
- } else if (value < 256) {
- dx_insert_8(field, DX_AMQP_SMALLULONG);
- dx_insert_8(field, (uint8_t) value);
- } else {
- dx_insert_8(field, DX_AMQP_ULONG);
- dx_insert_64(field, value);
- }
- bump_count(field);
-}
-
-
-void dx_compose_insert_int(dx_composed_field_t *field, int32_t value)
-{
- if (value >= -128 && value <= 127) {
- dx_insert_8(field, DX_AMQP_SMALLINT);
- dx_insert_8(field, (uint8_t) value);
- } else {
- dx_insert_8(field, DX_AMQP_INT);
- dx_insert_32(field, (uint32_t) value);
- }
- bump_count(field);
-}
-
-
-void dx_compose_insert_long(dx_composed_field_t *field, int64_t value)
-{
- if (value >= -128 && value <= 127) {
- dx_insert_8(field, DX_AMQP_SMALLLONG);
- dx_insert_8(field, (uint8_t) value);
- } else {
- dx_insert_8(field, DX_AMQP_LONG);
- dx_insert_64(field, (uint64_t) value);
- }
- bump_count(field);
-}
-
-
-void dx_compose_insert_timestamp(dx_composed_field_t *field, uint64_t value)
-{
- dx_insert_8(field, DX_AMQP_TIMESTAMP);
- dx_insert_64(field, value);
- bump_count(field);
-}
-
-
-void dx_compose_insert_uuid(dx_composed_field_t *field, const uint8_t *value)
-{
- dx_insert_8(field, DX_AMQP_UUID);
- dx_insert(field, value, 16);
- bump_count(field);
-}
-
-
-void dx_compose_insert_binary(dx_composed_field_t *field, const uint8_t *value, uint32_t len)
-{
- if (len < 256) {
- dx_insert_8(field, DX_AMQP_VBIN8);
- dx_insert_8(field, (uint8_t) len);
- } else {
- dx_insert_8(field, DX_AMQP_VBIN32);
- dx_insert_32(field, len);
- }
- dx_insert(field, value, len);
- bump_count(field);
-}
-
-
-void dx_compose_insert_binary_buffers(dx_composed_field_t *field, dx_buffer_list_t *buffers)
-{
- dx_buffer_t *buf = DEQ_HEAD(*buffers);
- uint32_t len = 0;
-
- //
- // Calculate the size of the binary field to be appended.
- //
- while (buf) {
- len += dx_buffer_size(buf);
- buf = DEQ_NEXT(buf);
- }
-
- //
- // Supply the appropriate binary tag for the length.
- //
- if (len < 256) {
- dx_insert_8(field, DX_AMQP_VBIN8);
- dx_insert_8(field, (uint8_t) len);
- } else {
- dx_insert_8(field, DX_AMQP_VBIN32);
- dx_insert_32(field, len);
- }
-
- //
- // Move the supplied buffers to the tail of the field's buffer list.
- //
- buf = DEQ_HEAD(*buffers);
- while (buf) {
- DEQ_REMOVE_HEAD(*buffers);
- DEQ_INSERT_TAIL(field->buffers, buf);
- buf = DEQ_HEAD(*buffers);
- }
-}
-
-
-void dx_compose_insert_string(dx_composed_field_t *field, const char *value)
-{
- uint32_t len = strlen(value);
-
- if (len < 256) {
- dx_insert_8(field, DX_AMQP_STR8_UTF8);
- dx_insert_8(field, (uint8_t) len);
- } else {
- dx_insert_8(field, DX_AMQP_STR32_UTF8);
- dx_insert_32(field, len);
- }
- dx_insert(field, (const uint8_t*) value, len);
- bump_count(field);
-}
-
-
-void dx_compose_insert_string_iterator(dx_composed_field_t *field, dx_field_iterator_t *iter)
-{
- uint32_t len = 0;
-
- while (!dx_field_iterator_end(iter)) {
- dx_field_iterator_octet(iter);
- len++;
- }
-
- dx_field_iterator_reset(iter);
-
- if (len < 256) {
- dx_insert_8(field, DX_AMQP_STR8_UTF8);
- dx_insert_8(field, (uint8_t) len);
- } else {
- dx_insert_8(field, DX_AMQP_STR32_UTF8);
- dx_insert_32(field, len);
- }
-
- while (!dx_field_iterator_end(iter)) {
- uint8_t octet = dx_field_iterator_octet(iter);
- dx_insert_8(field, octet);
- }
-
- bump_count(field);
-}
-
-
-void dx_compose_insert_symbol(dx_composed_field_t *field, const char *value)
-{
- uint32_t len = strlen(value);
-
- if (len < 256) {
- dx_insert_8(field, DX_AMQP_SYM8);
- dx_insert_8(field, (uint8_t) len);
- } else {
- dx_insert_8(field, DX_AMQP_SYM32);
- dx_insert_32(field, len);
- }
- dx_insert(field, (const uint8_t*) value, len);
- bump_count(field);
-}
-
-
-dx_buffer_list_t *dx_compose_buffers(dx_composed_field_t *field)
-{
- return &field->buffers;
-}
-
diff --git a/extras/dispatch/src/compose_private.h b/extras/dispatch/src/compose_private.h
deleted file mode 100644
index 6e72185f3c..0000000000
--- a/extras/dispatch/src/compose_private.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef __compose_private_h__
-#define __compose_private_h__ 1
-/*
- * 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/dispatch/compose.h>
-#include "message_private.h"
-
-dx_buffer_list_t *dx_compose_buffers(dx_composed_field_t *field);
-
-typedef struct dx_composite_t {
- DEQ_LINKS(struct dx_composite_t);
- int isMap;
- uint32_t count;
- uint32_t length;
- dx_field_location_t length_location;
- dx_field_location_t count_location;
-} dx_composite_t;
-
-ALLOC_DECLARE(dx_composite_t);
-DEQ_DECLARE(dx_composite_t, dx_field_stack_t);
-
-
-struct dx_composed_field_t {
- dx_buffer_list_t buffers;
- dx_field_stack_t fieldStack;
-};
-
-ALLOC_DECLARE(dx_composed_field_t);
-
-#endif
diff --git a/extras/dispatch/src/config.c b/extras/dispatch/src/config.c
deleted file mode 100644
index 9390115251..0000000000
--- a/extras/dispatch/src/config.c
+++ /dev/null
@@ -1,260 +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/dispatch/python_embedded.h>
-#include "config_private.h"
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/log.h>
-
-#define PYTHON_MODULE "qpid.dispatch.config"
-
-static const char *log_module = "CONFIG";
-
-struct dx_config_t {
- PyObject *pModule;
- PyObject *pClass;
- PyObject *pObject;
-};
-
-ALLOC_DECLARE(dx_config_t);
-ALLOC_DEFINE(dx_config_t);
-
-void dx_config_initialize()
-{
- dx_python_start();
-}
-
-
-void dx_config_finalize()
-{
- dx_python_stop();
-}
-
-
-dx_config_t *dx_config(const char *filename)
-{
- dx_config_t *config = new_dx_config_t();
-
- //
- // Load the Python configuration module and get a reference to the config class.
- //
- PyObject *pName = PyString_FromString(PYTHON_MODULE);
- config->pModule = PyImport_Import(pName);
- Py_DECREF(pName);
-
- if (!config->pModule) {
- PyErr_Print();
- free_dx_config_t(config);
- dx_log(log_module, LOG_ERROR, "Unable to load configuration module: %s", PYTHON_MODULE);
- return 0;
- }
-
- config->pClass = PyObject_GetAttrString(config->pModule, "DXConfig");
- if (!config->pClass || !PyClass_Check(config->pClass)) {
- PyErr_Print();
- Py_DECREF(config->pModule);
- free_dx_config_t(config);
- dx_log(log_module, LOG_ERROR, "Problem with configuration module: Missing DXConfig class");
- return 0;
- }
-
- //
- // Instantiate the DXConfig class, passing in the configuration file name.
- //
- PyObject *pArgs = PyTuple_New(1);
- PyObject *fname = PyString_FromString(filename);
- PyTuple_SetItem(pArgs, 0, fname);
- config->pObject = PyInstance_New(config->pClass, pArgs, 0);
- Py_DECREF(pArgs);
-
- if (config->pObject == 0) {
- PyErr_Print();
- Py_DECREF(config->pModule);
- free_dx_config_t(config);
- dx_log(log_module, LOG_ERROR, "Configuration file '%s' could not be read", filename);
- return 0;
- }
-
- return config;
-}
-
-
-void dx_config_read(dx_config_t *config)
-{
- PyObject *pMethod;
- PyObject *pArgs;
- PyObject *pResult;
-
- if (!config)
- return;
-
- pMethod = PyObject_GetAttrString(config->pObject, "read_file");
- if (!pMethod || !PyCallable_Check(pMethod)) {
- dx_log(log_module, LOG_ERROR, "Problem with configuration module: No callable 'item_count'");
- if (pMethod) {
- Py_DECREF(pMethod);
- }
- return;
- }
-
- pArgs = PyTuple_New(0);
- pResult = PyObject_CallObject(pMethod, pArgs);
- Py_DECREF(pArgs);
- if (pResult) {
- Py_DECREF(pResult);
- } else {
- PyErr_Print();
- }
- Py_DECREF(pMethod);
-}
-
-
-void dx_config_free(dx_config_t *config)
-{
- if (config) {
- Py_DECREF(config->pClass);
- Py_DECREF(config->pModule);
- free_dx_config_t(config);
- }
-}
-
-
-int dx_config_item_count(const dx_config_t *config, const char *section)
-{
- PyObject *pSection;
- PyObject *pMethod;
- PyObject *pArgs;
- PyObject *pResult;
- int result = 0;
-
- if (!config)
- return 0;
-
- pMethod = PyObject_GetAttrString(config->pObject, "item_count");
- if (!pMethod || !PyCallable_Check(pMethod)) {
- dx_log(log_module, LOG_ERROR, "Problem with configuration module: No callable 'item_count'");
- if (pMethod) {
- Py_DECREF(pMethod);
- }
- return 0;
- }
-
- pSection = PyString_FromString(section);
- pArgs = PyTuple_New(1);
- PyTuple_SetItem(pArgs, 0, pSection);
- pResult = PyObject_CallObject(pMethod, pArgs);
- Py_DECREF(pArgs);
- if (pResult && PyInt_Check(pResult))
- result = (int) PyInt_AsLong(pResult);
- if (pResult) {
- Py_DECREF(pResult);
- }
- Py_DECREF(pMethod);
-
- return result;
-}
-
-
-static PyObject *item_value(const dx_config_t *config, const char *section, int index, const char* key, const char* method)
-{
- PyObject *pSection;
- PyObject *pIndex;
- PyObject *pKey;
- PyObject *pMethod;
- PyObject *pArgs;
- PyObject *pResult;
-
- if (!config)
- return 0;
-
- pMethod = PyObject_GetAttrString(config->pObject, method);
- if (!pMethod || !PyCallable_Check(pMethod)) {
- dx_log(log_module, LOG_ERROR, "Problem with configuration module: No callable '%s'", method);
- if (pMethod) {
- Py_DECREF(pMethod);
- }
- return 0;
- }
-
- pSection = PyString_FromString(section);
- pIndex = PyInt_FromLong((long) index);
- pKey = PyString_FromString(key);
- pArgs = PyTuple_New(3);
- PyTuple_SetItem(pArgs, 0, pSection);
- PyTuple_SetItem(pArgs, 1, pIndex);
- PyTuple_SetItem(pArgs, 2, pKey);
- pResult = PyObject_CallObject(pMethod, pArgs);
- Py_DECREF(pArgs);
- Py_DECREF(pMethod);
-
- return pResult;
-}
-
-
-const char *dx_config_item_value_string(const dx_config_t *config, const char *section, int index, const char* key)
-{
- PyObject *pResult = item_value(config, section, index, key, "value_string");
- char *value = 0;
-
- if (pResult && PyString_Check(pResult)) {
- Py_ssize_t size = PyString_Size(pResult);
- value = (char*) malloc(size + 1);
- strncpy(value, PyString_AsString(pResult), size + 1);
- }
-
- if (pResult) {
- Py_DECREF(pResult);
- }
-
- return value;
-}
-
-
-uint32_t dx_config_item_value_int(const dx_config_t *config, const char *section, int index, const char* key)
-{
- PyObject *pResult = item_value(config, section, index, key, "value_int");
- uint32_t value = 0;
-
- if (pResult && PyLong_Check(pResult))
- value = (uint32_t) PyLong_AsLong(pResult);
-
- if (pResult) {
- Py_DECREF(pResult);
- }
-
- return value;
-}
-
-
-int dx_config_item_value_bool(const dx_config_t *config, const char *section, int index, const char* key)
-{
- PyObject *pResult = item_value(config, section, index, key, "value_bool");
- int value = 0;
-
- if (pResult && pResult != Py_None)
- value = 1;
-
- if (pResult) {
- Py_DECREF(pResult);
- }
-
- return value;
-}
-
-
diff --git a/extras/dispatch/src/config_private.h b/extras/dispatch/src/config_private.h
deleted file mode 100644
index f4ecc64e4c..0000000000
--- a/extras/dispatch/src/config_private.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __config_private_h__
-#define __config_private_h__ 1
-/*
- * 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/dispatch/config.h>
-
-void dx_config_initialize();
-void dx_config_finalize();
-dx_config_t *dx_config(const char *filename);
-void dx_config_read(dx_config_t *config);
-void dx_config_free(dx_config_t *config);
-
-#endif
diff --git a/extras/dispatch/src/container.c b/extras/dispatch/src/container.c
deleted file mode 100644
index 3ae24d81b0..0000000000
--- a/extras/dispatch/src/container.c
+++ /dev/null
@@ -1,868 +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 <stdio.h>
-#include <string.h>
-#include "dispatch_private.h"
-#include <qpid/dispatch/container.h>
-#include <qpid/dispatch/server.h>
-#include <qpid/dispatch/message.h>
-#include <proton/engine.h>
-#include <proton/message.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/hash.h>
-#include <qpid/dispatch/threading.h>
-#include <qpid/dispatch/iterator.h>
-#include <qpid/dispatch/log.h>
-#include <qpid/dispatch/agent.h>
-
-static char *module="CONTAINER";
-
-struct dx_node_t {
- dx_container_t *container;
- const dx_node_type_t *ntype;
- char *name;
- void *context;
- dx_dist_mode_t supported_dist;
- dx_lifetime_policy_t life_policy;
-};
-
-ALLOC_DECLARE(dx_node_t);
-ALLOC_DEFINE(dx_node_t);
-ALLOC_DEFINE(dx_link_item_t);
-
-
-struct dx_link_t {
- pn_link_t *pn_link;
- void *context;
- dx_node_t *node;
-};
-
-ALLOC_DECLARE(dx_link_t);
-ALLOC_DEFINE(dx_link_t);
-
-
-struct dx_delivery_t {
- pn_delivery_t *pn_delivery;
- dx_delivery_t *peer;
- void *context;
- uint64_t disposition;
- dx_link_t *link;
-};
-
-ALLOC_DECLARE(dx_delivery_t);
-ALLOC_DEFINE(dx_delivery_t);
-
-
-typedef struct dxc_node_type_t {
- DEQ_LINKS(struct dxc_node_type_t);
- const dx_node_type_t *ntype;
-} dxc_node_type_t;
-DEQ_DECLARE(dxc_node_type_t, dxc_node_type_list_t);
-
-static int DX_CONTAINER_CLASS_CONTAINER = 1;
-static int DX_CONTAINER_CLASS_NODE_TYPE = 2;
-static int DX_CONTAINER_CLASS_NODE = 3;
-
-typedef struct container_class_t {
- dx_container_t *container;
- int class_id;
-} container_class_t;
-
-struct dx_container_t {
- dx_dispatch_t *dx;
- dx_server_t *server;
- dx_hash_t *node_type_map;
- dx_hash_t *node_map;
- sys_mutex_t *lock;
- dx_node_t *default_node;
- dxc_node_type_list_t node_type_list;
- dx_agent_class_t *class_container;
- dx_agent_class_t *class_node_type;
- dx_agent_class_t *class_node;
-};
-
-static void setup_outgoing_link(dx_container_t *container, pn_link_t *pn_link)
-{
- sys_mutex_lock(container->lock);
- dx_node_t *node = 0;
- const char *source = pn_terminus_get_address(pn_link_remote_source(pn_link));
- dx_field_iterator_t *iter;
- // TODO - Extract the name from the structured source
-
- if (source) {
- iter = dx_field_iterator_string(source, ITER_VIEW_NODE_ID);
- dx_hash_retrieve(container->node_map, iter, (void*) &node);
- dx_field_iterator_free(iter);
- }
- sys_mutex_unlock(container->lock);
-
- if (node == 0) {
- if (container->default_node)
- node = container->default_node;
- else {
- // Reject the link
- // TODO - When the API allows, add an error message for "no available node"
- pn_link_close(pn_link);
- return;
- }
- }
-
- dx_link_t *link = new_dx_link_t();
- if (!link) {
- pn_link_close(pn_link);
- return;
- }
-
- link->pn_link = pn_link;
- link->context = 0;
- link->node = node;
-
- pn_link_set_context(pn_link, link);
- node->ntype->outgoing_handler(node->context, link);
-}
-
-
-static void setup_incoming_link(dx_container_t *container, pn_link_t *pn_link)
-{
- sys_mutex_lock(container->lock);
- dx_node_t *node = 0;
- const char *target = pn_terminus_get_address(pn_link_remote_target(pn_link));
- dx_field_iterator_t *iter;
- // TODO - Extract the name from the structured target
-
- if (target) {
- iter = dx_field_iterator_string(target, ITER_VIEW_NODE_ID);
- dx_hash_retrieve(container->node_map, iter, (void*) &node);
- dx_field_iterator_free(iter);
- }
- sys_mutex_unlock(container->lock);
-
- if (node == 0) {
- if (container->default_node)
- node = container->default_node;
- else {
- // Reject the link
- // TODO - When the API allows, add an error message for "no available node"
- pn_link_close(pn_link);
- return;
- }
- }
-
- dx_link_t *link = new_dx_link_t();
- if (!link) {
- pn_link_close(pn_link);
- return;
- }
-
- link->pn_link = pn_link;
- link->context = 0;
- link->node = node;
-
- pn_link_set_context(pn_link, link);
- node->ntype->incoming_handler(node->context, link);
-}
-
-
-static int do_writable(pn_link_t *pn_link)
-{
- dx_link_t *link = (dx_link_t*) pn_link_get_context(pn_link);
- if (!link)
- return 0;
-
- dx_node_t *node = link->node;
- if (!node)
- return 0;
-
- return node->ntype->writable_handler(node->context, link);
-}
-
-
-static void do_receive(pn_delivery_t *pnd)
-{
- pn_link_t *pn_link = pn_delivery_link(pnd);
- dx_link_t *link = (dx_link_t*) pn_link_get_context(pn_link);
- dx_delivery_t *delivery = (dx_delivery_t*) pn_delivery_get_context(pnd);
-
- if (link) {
- dx_node_t *node = link->node;
- if (node) {
- if (!delivery) {
- delivery = new_dx_delivery_t();
- delivery->pn_delivery = pnd;
- delivery->peer = 0;
- delivery->context = 0;
- delivery->disposition = 0;
- delivery->link = link;
- pn_delivery_set_context(pnd, delivery);
- }
-
- node->ntype->rx_handler(node->context, link, delivery);
- return;
- }
- }
-
- //
- // Reject the delivery if we couldn't find a node to handle it
- //
- pn_link_advance(pn_link);
- pn_link_flow(pn_link, 1);
- pn_delivery_update(pnd, PN_REJECTED);
- pn_delivery_settle(pnd);
-}
-
-
-static void do_updated(pn_delivery_t *pnd)
-{
- pn_link_t *pn_link = pn_delivery_link(pnd);
- dx_link_t *link = (dx_link_t*) pn_link_get_context(pn_link);
- dx_delivery_t *delivery = (dx_delivery_t*) pn_delivery_get_context(pnd);
-
- if (link && delivery) {
- dx_node_t *node = link->node;
- if (node)
- node->ntype->disp_handler(node->context, link, delivery);
- }
-}
-
-
-static int close_handler(void* unused, pn_connection_t *conn)
-{
- //
- // Close all links, passing False as the 'closed' argument. These links are not
- // being properly 'detached'. They are being orphaned.
- //
- pn_link_t *pn_link = pn_link_head(conn, PN_LOCAL_ACTIVE);
- while (pn_link) {
- dx_link_t *link = (dx_link_t*) pn_link_get_context(pn_link);
- dx_node_t *node = link->node;
- if (node && link)
- node->ntype->link_detach_handler(node->context, link, 0);
- pn_link_close(pn_link);
- free_dx_link_t(link);
- pn_link = pn_link_next(pn_link, PN_LOCAL_ACTIVE);
- }
-
- // teardown all sessions
- pn_session_t *ssn = pn_session_head(conn, 0);
- while (ssn) {
- pn_session_close(ssn);
- ssn = pn_session_next(ssn, 0);
- }
-
- // teardown the connection
- pn_connection_close(conn);
- return 0;
-}
-
-
-static int process_handler(dx_container_t *container, void* unused, pn_connection_t *conn)
-{
- pn_session_t *ssn;
- pn_link_t *pn_link;
- pn_delivery_t *delivery;
- int event_count = 0;
-
- // Step 1: setup the engine's connection, and any sessions and links
- // that may be pending.
-
- // initialize the connection if it's new
- if (pn_connection_state(conn) & PN_LOCAL_UNINIT) {
- pn_connection_open(conn);
- event_count++;
- }
-
- // open all pending sessions
- ssn = pn_session_head(conn, PN_LOCAL_UNINIT);
- while (ssn) {
- pn_session_open(ssn);
- ssn = pn_session_next(ssn, PN_LOCAL_UNINIT);
- event_count++;
- }
-
- // configure and open any pending links
- pn_link = pn_link_head(conn, PN_LOCAL_UNINIT);
- while (pn_link) {
- if (pn_link_is_sender(pn_link))
- setup_outgoing_link(container, pn_link);
- else
- setup_incoming_link(container, pn_link);
- pn_link = pn_link_next(pn_link, PN_LOCAL_UNINIT);
- event_count++;
- }
-
-
- // Step 2: Now drain all the pending deliveries from the connection's
- // work queue and process them
-
- delivery = pn_work_head(conn);
- while (delivery) {
- if (pn_delivery_readable(delivery))
- do_receive(delivery);
-
- if (pn_delivery_updated(delivery)) {
- do_updated(delivery);
- pn_delivery_clear(delivery);
- }
- delivery = pn_work_next(delivery);
- event_count++;
- }
-
- //
- // Step 2.5: Call the attached node's writable handler for all active links
- // on the connection. Note that in Dispatch, links are considered
- // bidirectional. Incoming and outgoing only pertains to deliveries and
- // deliveries are a subset of the traffic that flows both directions on links.
- //
- pn_link = pn_link_head(conn, PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE);
- while (pn_link) {
- assert(pn_session_connection(pn_link_session(pn_link)) == conn);
- event_count += do_writable(pn_link);
- pn_link = pn_link_next(pn_link, PN_LOCAL_ACTIVE | PN_REMOTE_ACTIVE);
- }
-
- // Step 3: Clean up any links or sessions that have been closed by the
- // remote. If the connection has been closed remotely, clean that up
- // also.
-
- // teardown any terminating links
- pn_link = pn_link_head(conn, PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED);
- while (pn_link) {
- dx_link_t *link = (dx_link_t*) pn_link_get_context(pn_link);
- dx_node_t *node = link->node;
- if (node)
- node->ntype->link_detach_handler(node->context, link, 1); // TODO - get 'closed' from detach message
- pn_link_close(pn_link);
- pn_link = pn_link_next(pn_link, PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED);
- event_count++;
- }
-
- // teardown any terminating sessions
- ssn = pn_session_head(conn, PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED);
- while (ssn) {
- pn_session_close(ssn);
- ssn = pn_session_next(ssn, PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED);
- event_count++;
- }
-
- // teardown the connection if it's terminating
- if (pn_connection_state(conn) == (PN_LOCAL_ACTIVE | PN_REMOTE_CLOSED)) {
- pn_connection_close(conn);
- event_count++;
- }
-
- return event_count;
-}
-
-
-static void open_handler(dx_container_t *container, dx_connection_t *conn, dx_direction_t dir)
-{
- const dx_node_type_t *nt;
-
- //
- // Note the locking structure in this function. Generally this would be unsafe, but since
- // this particular list is only ever appended to and never has items inserted or deleted,
- // this usage is safe in this case.
- //
- sys_mutex_lock(container->lock);
- dxc_node_type_t *nt_item = DEQ_HEAD(container->node_type_list);
- sys_mutex_unlock(container->lock);
-
- pn_connection_open(dx_connection_pn(conn));
-
- while (nt_item) {
- nt = nt_item->ntype;
- if (dir == DX_INCOMING) {
- if (nt->inbound_conn_open_handler)
- nt->inbound_conn_open_handler(nt->type_context, conn);
- } else {
- if (nt->outbound_conn_open_handler)
- nt->outbound_conn_open_handler(nt->type_context, conn);
- }
-
- sys_mutex_lock(container->lock);
- nt_item = DEQ_NEXT(nt_item);
- sys_mutex_unlock(container->lock);
- }
-}
-
-
-static int handler(void *handler_context, void *conn_context, dx_conn_event_t event, dx_connection_t *dx_conn)
-{
- dx_container_t *container = (dx_container_t*) handler_context;
- pn_connection_t *conn = dx_connection_pn(dx_conn);
-
- switch (event) {
- case DX_CONN_EVENT_LISTENER_OPEN: open_handler(container, dx_conn, DX_INCOMING); break;
- case DX_CONN_EVENT_CONNECTOR_OPEN: open_handler(container, dx_conn, DX_OUTGOING); break;
- case DX_CONN_EVENT_CLOSE: return close_handler(conn_context, conn);
- case DX_CONN_EVENT_PROCESS: return process_handler(container, conn_context, conn);
- }
-
- return 0;
-}
-
-
-static void container_schema_handler(void *context, void *correlator)
-{
-}
-
-
-static void container_query_handler(void* context, const char *id, void *correlator)
-{
- container_class_t *cls = (container_class_t*) context;
-
- if (cls->class_id == DX_CONTAINER_CLASS_CONTAINER) {
- dx_agent_value_uint(correlator, "node_type_count", dx_hash_size(cls->container->node_type_map));
- dx_agent_value_uint(correlator, "node_count", dx_hash_size(cls->container->node_map));
- if (cls->container->default_node)
- dx_agent_value_string(correlator, "default_node_type", cls->container->default_node->ntype->type_name);
- else
- dx_agent_value_null(correlator, "default_node_type");
- dx_agent_value_complete(correlator, false);
-
- } else if (cls->class_id == DX_CONTAINER_CLASS_NODE_TYPE) {
-
- } else if (cls->class_id == DX_CONTAINER_CLASS_NODE) {
-
- }
-}
-
-
-dx_agent_class_t *setup_class(dx_container_t *container, const char *fqname, int id)
-{
- container_class_t *cls = NEW(container_class_t);
- cls->container = container;
- cls->class_id = id;
-
- return dx_agent_register_class(container->dx, fqname, cls,
- container_schema_handler,
- container_query_handler);
-}
-
-
-dx_container_t *dx_container(dx_dispatch_t *dx)
-{
- dx_container_t *container = NEW(dx_container_t);
-
- container->dx = dx;
- container->server = dx->server;
- container->node_type_map = dx_hash(6, 4, 1); // 64 buckets, item batches of 4
- container->node_map = dx_hash(10, 32, 0); // 1K buckets, item batches of 32
- container->lock = sys_mutex();
- container->default_node = 0;
- DEQ_INIT(container->node_type_list);
-
- dx_log(module, LOG_TRACE, "Container Initializing");
- dx_server_set_conn_handler(dx, handler, container);
-
- return container;
-}
-
-
-void dx_container_setup_agent(dx_dispatch_t *dx)
-{
- dx->container->class_container =
- setup_class(dx->container, "org.apache.qpid.dispatch.container", DX_CONTAINER_CLASS_CONTAINER);
- dx->container->class_node_type =
- setup_class(dx->container, "org.apache.qpid.dispatch.container.node_type", DX_CONTAINER_CLASS_NODE_TYPE);
- dx->container->class_node =
- setup_class(dx->container, "org.apache.qpid.dispatch.container.node", DX_CONTAINER_CLASS_NODE);
-}
-
-
-void dx_container_free(dx_container_t *container)
-{
- // TODO - Free the nodes
- // TODO - Free the node types
- sys_mutex_free(container->lock);
- free(container);
-}
-
-
-int dx_container_register_node_type(dx_dispatch_t *dx, const dx_node_type_t *nt)
-{
- dx_container_t *container = dx->container;
-
- int result;
- dx_field_iterator_t *iter = dx_field_iterator_string(nt->type_name, ITER_VIEW_ALL);
- dxc_node_type_t *nt_item = NEW(dxc_node_type_t);
- DEQ_ITEM_INIT(nt_item);
- nt_item->ntype = nt;
-
- sys_mutex_lock(container->lock);
- result = dx_hash_insert_const(container->node_type_map, iter, nt, 0);
- DEQ_INSERT_TAIL(container->node_type_list, nt_item);
- sys_mutex_unlock(container->lock);
-
- dx_field_iterator_free(iter);
- if (result < 0)
- return result;
- dx_log(module, LOG_TRACE, "Node Type Registered - %s", nt->type_name);
-
- return 0;
-}
-
-
-dx_node_t *dx_container_set_default_node_type(dx_dispatch_t *dx,
- const dx_node_type_t *nt,
- void *context,
- dx_dist_mode_t supported_dist)
-{
- dx_container_t *container = dx->container;
-
- if (container->default_node)
- dx_container_destroy_node(container->default_node);
-
- if (nt) {
- container->default_node = dx_container_create_node(dx, nt, 0, context, supported_dist, DX_LIFE_PERMANENT);
- dx_log(module, LOG_TRACE, "Node of type '%s' installed as default node", nt->type_name);
- } else {
- container->default_node = 0;
- dx_log(module, LOG_TRACE, "Default node removed");
- }
-
- return container->default_node;
-}
-
-
-dx_node_t *dx_container_create_node(dx_dispatch_t *dx,
- const dx_node_type_t *nt,
- const char *name,
- void *context,
- dx_dist_mode_t supported_dist,
- dx_lifetime_policy_t life_policy)
-{
- dx_container_t *container = dx->container;
- int result;
- dx_node_t *node = new_dx_node_t();
- if (!node)
- return 0;
-
- node->container = container;
- node->ntype = nt;
- node->name = 0;
- node->context = context;
- node->supported_dist = supported_dist;
- node->life_policy = life_policy;
-
- if (name) {
- dx_field_iterator_t *iter = dx_field_iterator_string(name, ITER_VIEW_ALL);
- sys_mutex_lock(container->lock);
- result = dx_hash_insert(container->node_map, iter, node, 0);
- sys_mutex_unlock(container->lock);
- dx_field_iterator_free(iter);
- if (result < 0) {
- free_dx_node_t(node);
- return 0;
- }
-
- node->name = (char*) malloc(strlen(name) + 1);
- strcpy(node->name, name);
- }
-
- if (name)
- dx_log(module, LOG_TRACE, "Node of type '%s' created with name '%s'", nt->type_name, name);
-
- return node;
-}
-
-
-void dx_container_destroy_node(dx_node_t *node)
-{
- dx_container_t *container = node->container;
-
- if (node->name) {
- dx_field_iterator_t *iter = dx_field_iterator_string(node->name, ITER_VIEW_ALL);
- sys_mutex_lock(container->lock);
- dx_hash_remove(container->node_map, iter);
- sys_mutex_unlock(container->lock);
- dx_field_iterator_free(iter);
- free(node->name);
- }
-
- free_dx_node_t(node);
-}
-
-
-void dx_container_node_set_context(dx_node_t *node, void *node_context)
-{
- node->context = node_context;
-}
-
-
-dx_dist_mode_t dx_container_node_get_dist_modes(const dx_node_t *node)
-{
- return node->supported_dist;
-}
-
-
-dx_lifetime_policy_t dx_container_node_get_life_policy(const dx_node_t *node)
-{
- return node->life_policy;
-}
-
-
-dx_link_t *dx_link(dx_node_t *node, dx_connection_t *conn, dx_direction_t dir, const char* name)
-{
- pn_session_t *sess = pn_session(dx_connection_pn(conn));
- dx_link_t *link = new_dx_link_t();
-
- if (dir == DX_OUTGOING)
- link->pn_link = pn_sender(sess, name);
- else
- link->pn_link = pn_receiver(sess, name);
- link->context = node->context;
- link->node = node;
-
- pn_link_set_context(link->pn_link, link);
-
- pn_session_open(sess);
-
- return link;
-}
-
-
-void dx_link_set_context(dx_link_t *link, void *context)
-{
- link->context = context;
-}
-
-
-void *dx_link_get_context(dx_link_t *link)
-{
- return link->context;
-}
-
-
-void dx_link_set_conn_context(dx_link_t *link, void *context)
-{
- pn_session_t *pn_sess = pn_link_session(link->pn_link);
- if (!pn_sess)
- return;
- pn_connection_t *pn_conn = pn_session_connection(pn_sess);
- if (!pn_conn)
- return;
- dx_connection_t *conn = (dx_connection_t*) pn_connection_get_context(pn_conn);
- if (!conn)
- return;
- dx_connection_set_link_context(conn, context);
-}
-
-
-void *dx_link_get_conn_context(dx_link_t *link)
-{
- pn_session_t *pn_sess = pn_link_session(link->pn_link);
- if (!pn_sess)
- return 0;
- pn_connection_t *pn_conn = pn_session_connection(pn_sess);
- if (!pn_conn)
- return 0;
- dx_connection_t *conn = (dx_connection_t*) pn_connection_get_context(pn_conn);
- if (!conn)
- return 0;
- return dx_connection_get_link_context(conn);
-}
-
-
-pn_link_t *dx_link_pn(dx_link_t *link)
-{
- return link->pn_link;
-}
-
-
-dx_connection_t *dx_link_connection(dx_link_t *link)
-{
- if (!link || !link->pn_link)
- return 0;
-
- pn_session_t *sess = pn_link_session(link->pn_link);
- if (!sess)
- return 0;
-
- pn_connection_t *conn = pn_session_connection(sess);
- if (!conn)
- return 0;
-
- dx_connection_t *ctx = pn_connection_get_context(conn);
- if (!ctx)
- return 0;
-
- return ctx;
-}
-
-
-pn_terminus_t *dx_link_source(dx_link_t *link)
-{
- return pn_link_source(link->pn_link);
-}
-
-
-pn_terminus_t *dx_link_target(dx_link_t *link)
-{
- return pn_link_target(link->pn_link);
-}
-
-
-pn_terminus_t *dx_link_remote_source(dx_link_t *link)
-{
- return pn_link_remote_source(link->pn_link);
-}
-
-
-pn_terminus_t *dx_link_remote_target(dx_link_t *link)
-{
- return pn_link_remote_target(link->pn_link);
-}
-
-
-void dx_link_activate(dx_link_t *link)
-{
- if (!link || !link->pn_link)
- return;
-
- pn_session_t *sess = pn_link_session(link->pn_link);
- if (!sess)
- return;
-
- pn_connection_t *conn = pn_session_connection(sess);
- if (!conn)
- return;
-
- dx_connection_t *ctx = pn_connection_get_context(conn);
- if (!ctx)
- return;
-
- dx_server_activate(ctx);
-}
-
-
-void dx_link_close(dx_link_t *link)
-{
- pn_link_close(link->pn_link);
-}
-
-
-dx_delivery_t *dx_delivery(dx_link_t *link, pn_delivery_tag_t tag)
-{
- pn_link_t *pnl = dx_link_pn(link);
-
- //
- // If there is a current delivery on this outgoing link, something
- // is wrong with the delivey algorithm. We assume that the current
- // delivery ('pnd' below) is the one created by pn_delivery. If it is
- // not, then my understanding of how proton works is incorrect.
- //
- assert(!pn_link_current(pnl));
-
- pn_delivery(pnl, tag);
- pn_delivery_t *pnd = pn_link_current(pnl);
-
- if (!pnd)
- return 0;
-
- dx_delivery_t *delivery = new_dx_delivery_t();
- delivery->pn_delivery = pnd;
- delivery->peer = 0;
- delivery->context = 0;
- delivery->disposition = 0;
- delivery->link = link;
- pn_delivery_set_context(pnd, delivery);
-
- return delivery;
-}
-
-
-void dx_delivery_free(dx_delivery_t *delivery, uint64_t final_disposition)
-{
- if (delivery->pn_delivery) {
- if (final_disposition > 0)
- pn_delivery_update(delivery->pn_delivery, final_disposition);
- pn_delivery_set_context(delivery->pn_delivery, 0);
- pn_delivery_settle(delivery->pn_delivery);
- }
- if (delivery->peer)
- delivery->peer->peer = 0;
- free_dx_delivery_t(delivery);
-}
-
-
-void dx_delivery_set_peer(dx_delivery_t *delivery, dx_delivery_t *peer)
-{
- delivery->peer = peer;
-}
-
-
-void dx_delivery_set_context(dx_delivery_t *delivery, void *context)
-{
- delivery->context = context;
-}
-
-
-void *dx_delivery_context(dx_delivery_t *delivery)
-{
- return delivery->context;
-}
-
-
-dx_delivery_t *dx_delivery_peer(dx_delivery_t *delivery)
-{
- return delivery->peer;
-}
-
-
-pn_delivery_t *dx_delivery_pn(dx_delivery_t *delivery)
-{
- return delivery->pn_delivery;
-}
-
-
-void dx_delivery_settle(dx_delivery_t *delivery)
-{
- if (delivery->pn_delivery) {
- pn_delivery_settle(delivery->pn_delivery);
- delivery->pn_delivery = 0;
- }
-}
-
-
-bool dx_delivery_settled(dx_delivery_t *delivery)
-{
- return pn_delivery_settled(delivery->pn_delivery);
-}
-
-
-bool dx_delivery_disp_changed(dx_delivery_t *delivery)
-{
- return delivery->disposition != pn_delivery_remote_state(delivery->pn_delivery);
-}
-
-
-uint64_t dx_delivery_disp(dx_delivery_t *delivery)
-{
- delivery->disposition = pn_delivery_remote_state(delivery->pn_delivery);
- return delivery->disposition;
-}
-
-
-dx_link_t *dx_delivery_link(dx_delivery_t *delivery)
-{
- return delivery->link;
-}
-
diff --git a/extras/dispatch/src/dispatch.c b/extras/dispatch/src/dispatch.c
deleted file mode 100644
index 46c256a603..0000000000
--- a/extras/dispatch/src/dispatch.c
+++ /dev/null
@@ -1,227 +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/dispatch/python_embedded.h>
-#include <qpid/dispatch.h>
-#include <qpid/dispatch/server.h>
-#include <qpid/dispatch/ctools.h>
-#include "dispatch_private.h"
-#include "alloc_private.h"
-#include "log_private.h"
-#include "router_private.h"
-
-/**
- * Private Function Prototypes
- */
-dx_server_t *dx_server(int tc, const char *container_name);
-void dx_server_setup_agent(dx_dispatch_t *dx);
-void dx_server_free(dx_server_t *server);
-dx_container_t *dx_container(dx_dispatch_t *dx);
-void dx_container_setup_agent(dx_dispatch_t *dx);
-void dx_container_free(dx_container_t *container);
-dx_router_t *dx_router(dx_dispatch_t *dx, dx_router_mode_t mode, const char *area, const char *id);
-void dx_router_setup_late(dx_dispatch_t *dx);
-void dx_router_free(dx_router_t *router);
-dx_agent_t *dx_agent(dx_dispatch_t *dx);
-void dx_agent_free(dx_agent_t *agent);
-
-ALLOC_DEFINE(dx_config_listener_t);
-ALLOC_DEFINE(dx_config_connector_t);
-
-static const char *CONF_CONTAINER = "container";
-static const char *CONF_ROUTER = "router";
-static const char *CONF_LISTENER = "listener";
-static const char *CONF_CONNECTOR = "connector";
-
-
-dx_dispatch_t *dx_dispatch(const char *config_path)
-{
- dx_dispatch_t *dx = NEW(dx_dispatch_t);
-
- int thread_count = 0;
- const char *container_name = 0;
- const char *router_mode_str = 0;
- const char *router_area = "0";
- const char *router_id = 0;
-
- dx_router_mode_t router_mode = DX_ROUTER_MODE_STANDALONE;
-
- DEQ_INIT(dx->config_listeners);
- DEQ_INIT(dx->config_connectors);
-
- dx_python_initialize(dx);
- dx_log_initialize();
- dx_alloc_initialize();
-
- dx_config_initialize();
- dx->config = dx_config(config_path);
- dx_config_read(dx->config);
-
- if (dx->config) {
- int count = dx_config_item_count(dx->config, CONF_CONTAINER);
- if (count == 1) {
- thread_count = dx_config_item_value_int(dx->config, CONF_CONTAINER, 0, "worker-threads");
- container_name = dx_config_item_value_string(dx->config, CONF_CONTAINER, 0, "container-name");
- }
-
- count = dx_config_item_count(dx->config, CONF_ROUTER);
- if (count == 1) {
- router_mode_str = dx_config_item_value_string(dx->config, CONF_ROUTER, 0, "mode");
- //router_area = dx_config_item_value_string(dx->config, CONF_ROUTER, 0, "0");
- router_id = dx_config_item_value_string(dx->config, CONF_ROUTER, 0, "router-id");
- }
- }
-
- if (thread_count == 0)
- thread_count = 1;
-
- if (!container_name)
- container_name = "00000000-0000-0000-0000-000000000000"; // TODO - gen a real uuid
-
- if (router_mode_str && strcmp(router_mode_str, "interior") == 0)
- router_mode = DX_ROUTER_MODE_INTERIOR;
-
- if (router_mode_str && strcmp(router_mode_str, "edge") == 0)
- router_mode = DX_ROUTER_MODE_EDGE;
-
- if (!router_area)
- router_area = "area";
-
- if (!router_id)
- router_id = container_name;
-
- dx->server = dx_server(thread_count, container_name);
- dx->container = dx_container(dx);
- dx->router = dx_router(dx, router_mode, router_area, router_id);
- dx->agent = dx_agent(dx);
-
- dx_alloc_setup_agent(dx);
- dx_server_setup_agent(dx);
- dx_container_setup_agent(dx);
- dx_router_setup_late(dx);
-
- return dx;
-}
-
-
-void dx_dispatch_free(dx_dispatch_t *dx)
-{
- dx_config_free(dx->config);
- dx_config_finalize();
- dx_agent_free(dx->agent);
- dx_router_free(dx->router);
- dx_container_free(dx->container);
- dx_server_free(dx->server);
- dx_log_finalize();
- dx_python_finalize();
-}
-
-
-static void load_server_config(dx_dispatch_t *dx, dx_server_config_t *config, const char *section, int i)
-{
- config->host = dx_config_item_value_string(dx->config, section, i, "addr");
- config->port = dx_config_item_value_string(dx->config, section, i, "port");
- config->role = dx_config_item_value_string(dx->config, section, i, "role");
- config->sasl_mechanisms =
- dx_config_item_value_string(dx->config, section, i, "sasl-mechanisms");
- config->ssl_enabled =
- dx_config_item_value_bool(dx->config, section, i, "ssl-profile");
- if (config->ssl_enabled) {
- config->ssl_server = 1;
- config->ssl_allow_unsecured_client =
- dx_config_item_value_bool(dx->config, section, i, "allow-unsecured");
- config->ssl_certificate_file =
- dx_config_item_value_string(dx->config, section, i, "cert-file");
- config->ssl_private_key_file =
- dx_config_item_value_string(dx->config, section, i, "key-file");
- config->ssl_password =
- dx_config_item_value_string(dx->config, section, i, "password");
- config->ssl_trusted_certificate_db =
- dx_config_item_value_string(dx->config, section, i, "cert-db");
- config->ssl_require_peer_authentication =
- dx_config_item_value_bool(dx->config, section, i, "require-peer-auth");
- }
-}
-
-
-static void configure_listeners(dx_dispatch_t *dx)
-{
- int count;
-
- if (!dx->config)
- return;
-
- count = dx_config_item_count(dx->config, CONF_LISTENER);
- for (int i = 0; i < count; i++) {
- dx_config_listener_t *cl = new_dx_config_listener_t();
- load_server_config(dx, &cl->configuration, CONF_LISTENER, i);
-
- printf("\nListener : %s:%s\n", cl->configuration.host, cl->configuration.port);
- printf(" SASL: %s\n", cl->configuration.sasl_mechanisms);
- printf(" SSL: %d\n", cl->configuration.ssl_enabled);
- if (cl->configuration.ssl_enabled) {
- printf(" unsec: %d\n", cl->configuration.ssl_allow_unsecured_client);
- printf(" cert-file: %s\n", cl->configuration.ssl_certificate_file);
- printf(" key-file: %s\n", cl->configuration.ssl_private_key_file);
- printf(" cert-db: %s\n", cl->configuration.ssl_trusted_certificate_db);
- printf(" peer-auth: %d\n", cl->configuration.ssl_require_peer_authentication);
- }
-
- cl->listener = dx_server_listen(dx, &cl->configuration, cl);
- DEQ_ITEM_INIT(cl);
- DEQ_INSERT_TAIL(dx->config_listeners, cl);
- }
-}
-
-
-static void configure_connectors(dx_dispatch_t *dx)
-{
- int count;
-
- if (!dx->config)
- return;
-
- count = dx_config_item_count(dx->config, CONF_CONNECTOR);
- for (int i = 0; i < count; i++) {
- dx_config_connector_t *cc = new_dx_config_connector_t();
- load_server_config(dx, &cc->configuration, CONF_CONNECTOR, i);
-
- printf("\nConnector : %s:%s\n", cc->configuration.host, cc->configuration.port);
- printf(" SASL: %s\n", cc->configuration.sasl_mechanisms);
- printf(" SSL: %d\n", cc->configuration.ssl_enabled);
- if (cc->configuration.ssl_enabled) {
- printf(" cert-file: %s\n", cc->configuration.ssl_certificate_file);
- printf(" key-file: %s\n", cc->configuration.ssl_private_key_file);
- printf(" cert-db: %s\n", cc->configuration.ssl_trusted_certificate_db);
- printf(" peer-auth: %d\n", cc->configuration.ssl_require_peer_authentication);
- }
-
- cc->connector = dx_server_connect(dx, &cc->configuration, cc);
- DEQ_ITEM_INIT(cc);
- DEQ_INSERT_TAIL(dx->config_connectors, cc);
- }
-}
-
-
-void dx_dispatch_configure(dx_dispatch_t *dx)
-{
- configure_listeners(dx);
- configure_connectors(dx);
-}
-
diff --git a/extras/dispatch/src/dispatch_private.h b/extras/dispatch/src/dispatch_private.h
deleted file mode 100644
index d96eb59afe..0000000000
--- a/extras/dispatch/src/dispatch_private.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef __dispatch_private_h__
-#define __dispatch_private_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 "server_private.h"
-#include "config_private.h"
-#include <qpid/dispatch/ctools.h>
-
-typedef struct dx_container_t dx_container_t;
-typedef struct dx_router_t dx_router_t;
-typedef struct dx_agent_t dx_agent_t;
-
-typedef struct dx_config_listener_t {
- DEQ_LINKS(struct dx_config_listener_t);
- dx_listener_t *listener;
- dx_server_config_t configuration;
-} dx_config_listener_t;
-
-DEQ_DECLARE(dx_config_listener_t, dx_config_listener_list_t);
-ALLOC_DECLARE(dx_config_listener_t);
-
-
-typedef struct dx_config_connector_t {
- DEQ_LINKS(struct dx_config_connector_t);
- dx_connector_t *connector;
- dx_server_config_t configuration;
-} dx_config_connector_t;
-
-DEQ_DECLARE(dx_config_connector_t, dx_config_connector_list_t);
-ALLOC_DECLARE(dx_config_connector_t);
-
-struct dx_dispatch_t {
- dx_server_t *server;
- dx_container_t *container;
- dx_router_t *router;
- dx_agent_t *agent;
- dx_config_t *config;
-
- dx_config_listener_list_t config_listeners;
- dx_config_connector_list_t config_connectors;
-};
-
-#endif
-
diff --git a/extras/dispatch/src/hash.c b/extras/dispatch/src/hash.c
deleted file mode 100644
index 0cb32acd05..0000000000
--- a/extras/dispatch/src/hash.c
+++ /dev/null
@@ -1,285 +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/dispatch/hash.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/alloc.h>
-#include <stdio.h>
-#include <string.h>
-
-typedef struct dx_hash_item_t {
- DEQ_LINKS(struct dx_hash_item_t);
- unsigned char *key;
- union {
- void *val;
- const void *val_const;
- } v;
-} dx_hash_item_t;
-
-ALLOC_DECLARE(dx_hash_item_t);
-ALLOC_DEFINE(dx_hash_item_t);
-DEQ_DECLARE(dx_hash_item_t, items_t);
-
-
-typedef struct bucket_t {
- items_t items;
-} bucket_t;
-
-
-struct dx_hash_t {
- bucket_t *buckets;
- unsigned int bucket_count;
- unsigned int bucket_mask;
- int batch_size;
- size_t size;
- int is_const;
-};
-
-
-struct dx_hash_handle_t {
- bucket_t *bucket;
- dx_hash_item_t *item;
-};
-
-ALLOC_DECLARE(dx_hash_handle_t);
-ALLOC_DEFINE(dx_hash_handle_t);
-
-
-// djb2 hash algorithm
-static unsigned long dx_hash_function(dx_field_iterator_t *iter)
-{
- unsigned long hash = 5381;
- int c;
-
- dx_field_iterator_reset(iter);
- while (!dx_field_iterator_end(iter)) {
- c = (int) dx_field_iterator_octet(iter);
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
- }
-
- return hash;
-}
-
-
-dx_hash_t *dx_hash(int bucket_exponent, int batch_size, int value_is_const)
-{
- int i;
- dx_hash_t *h = NEW(dx_hash_t);
-
- if (!h)
- return 0;
-
- h->bucket_count = 1 << bucket_exponent;
- h->bucket_mask = h->bucket_count - 1;
- h->batch_size = batch_size;
- h->size = 0;
- h->is_const = value_is_const;
- h->buckets = NEW_ARRAY(bucket_t, h->bucket_count);
- for (i = 0; i < h->bucket_count; i++) {
- DEQ_INIT(h->buckets[i].items);
- }
-
- return h;
-}
-
-
-void dx_hash_free(dx_hash_t *h)
-{
- // TODO - Implement this
-}
-
-
-size_t dx_hash_size(dx_hash_t *h)
-{
- return h ? h->size : 0;
-}
-
-
-static dx_hash_item_t *dx_hash_internal_insert(dx_hash_t *h, dx_field_iterator_t *key, int *exists, dx_hash_handle_t **handle)
-{
- unsigned long idx = dx_hash_function(key) & h->bucket_mask;
- dx_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
-
- while (item) {
- if (dx_field_iterator_equal(key, item->key))
- break;
- item = item->next;
- }
-
- if (item) {
- *exists = 1;
- if (handle)
- *handle = 0;
- return item;
- }
-
- item = new_dx_hash_item_t();
- if (!item)
- return 0;
-
- DEQ_ITEM_INIT(item);
- item->key = dx_field_iterator_copy(key);
-
- DEQ_INSERT_TAIL(h->buckets[idx].items, item);
- h->size++;
- *exists = 0;
-
- //
- // If a pointer to a handle-pointer was supplied, create a handle for this item.
- //
- if (handle) {
- *handle = new_dx_hash_handle_t();
- (*handle)->bucket = &h->buckets[idx];
- (*handle)->item = item;
- }
-
- return item;
-}
-
-
-dx_error_t dx_hash_insert(dx_hash_t *h, dx_field_iterator_t *key, void *val, dx_hash_handle_t **handle)
-{
- int exists = 0;
- dx_hash_item_t *item = dx_hash_internal_insert(h, key, &exists, handle);
-
- if (!item)
- return DX_ERROR_ALLOC;
-
- if (exists)
- return DX_ERROR_ALREADY_EXISTS;
-
- item->v.val = val;
-
- return DX_ERROR_NONE;
-}
-
-
-dx_error_t dx_hash_insert_const(dx_hash_t *h, dx_field_iterator_t *key, const void *val, dx_hash_handle_t **handle)
-{
- assert(h->is_const);
-
- int error = 0;
- dx_hash_item_t *item = dx_hash_internal_insert(h, key, &error, handle);
-
- if (item)
- item->v.val_const = val;
- return error;
-}
-
-
-static dx_hash_item_t *dx_hash_internal_retrieve(dx_hash_t *h, dx_field_iterator_t *key)
-{
- unsigned long idx = dx_hash_function(key) & h->bucket_mask;
- dx_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
-
- while (item) {
- if (dx_field_iterator_equal(key, item->key))
- break;
- item = item->next;
- }
-
- return item;
-}
-
-
-dx_error_t dx_hash_retrieve(dx_hash_t *h, dx_field_iterator_t *key, void **val)
-{
- dx_hash_item_t *item = dx_hash_internal_retrieve(h, key);
- if (item)
- *val = item->v.val;
- else
- *val = 0;
-
- return DX_ERROR_NONE;
-}
-
-
-dx_error_t dx_hash_retrieve_const(dx_hash_t *h, dx_field_iterator_t *key, const void **val)
-{
- assert(h->is_const);
-
- dx_hash_item_t *item = dx_hash_internal_retrieve(h, key);
- if (item)
- *val = item->v.val_const;
- else
- *val = 0;
-
- return DX_ERROR_NONE;
-}
-
-
-dx_error_t dx_hash_remove(dx_hash_t *h, dx_field_iterator_t *key)
-{
- unsigned long idx = dx_hash_function(key) & h->bucket_mask;
- dx_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
-
- while (item) {
- if (dx_field_iterator_equal(key, item->key))
- break;
- item = item->next;
- }
-
- if (item) {
- free(item->key);
- DEQ_REMOVE(h->buckets[idx].items, item);
- free_dx_hash_item_t(item);
- h->size--;
- return DX_ERROR_NONE;
- }
-
- return DX_ERROR_NOT_FOUND;
-}
-
-
-void dx_hash_handle_free(dx_hash_handle_t *handle)
-{
- if (handle)
- free_dx_hash_handle_t(handle);
-}
-
-
-const unsigned char *dx_hash_key_by_handle(const dx_hash_handle_t *handle)
-{
- if (handle)
- return handle->item->key;
- return 0;
-}
-
-
-dx_error_t dx_hash_remove_by_handle(dx_hash_t *h, dx_hash_handle_t *handle)
-{
- unsigned char *key = 0;
- dx_error_t error = dx_hash_remove_by_handle2(h, handle, &key);
- if (key)
- free(key);
- return error;
-}
-
-
-dx_error_t dx_hash_remove_by_handle2(dx_hash_t *h, dx_hash_handle_t *handle, unsigned char **key)
-{
- if (!handle)
- return DX_ERROR_NOT_FOUND;
- *key = handle->item->key;
- DEQ_REMOVE(handle->bucket->items, handle->item);
- free_dx_hash_item_t(handle->item);
- h->size--;
- return DX_ERROR_NONE;
-}
-
diff --git a/extras/dispatch/src/iovec.c b/extras/dispatch/src/iovec.c
deleted file mode 100644
index a4ce937333..0000000000
--- a/extras/dispatch/src/iovec.c
+++ /dev/null
@@ -1,81 +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/dispatch/iovec.h>
-#include <qpid/dispatch/alloc.h>
-#include <string.h>
-
-#define DX_IOVEC_MAX 64
-
-struct dx_iovec_t {
- struct iovec iov_array[DX_IOVEC_MAX];
- struct iovec *iov;
- int iov_count;
-};
-
-
-ALLOC_DECLARE(dx_iovec_t);
-ALLOC_DEFINE(dx_iovec_t);
-
-
-dx_iovec_t *dx_iovec(int vector_count)
-{
- dx_iovec_t *iov = new_dx_iovec_t();
- if (!iov)
- return 0;
-
- memset(iov, 0, sizeof(dx_iovec_t));
-
- iov->iov_count = vector_count;
- if (vector_count > DX_IOVEC_MAX)
- iov->iov = (struct iovec*) malloc(sizeof(struct iovec) * vector_count);
- else
- iov->iov = &iov->iov_array[0];
-
- return iov;
-}
-
-
-void dx_iovec_free(dx_iovec_t *iov)
-{
- if (!iov)
- return;
-
- if (iov->iov && iov->iov != &iov->iov_array[0])
- free(iov->iov);
-
- free_dx_iovec_t(iov);
-}
-
-
-struct iovec *dx_iovec_array(dx_iovec_t *iov)
-{
- if (!iov)
- return 0;
- return iov->iov;
-}
-
-
-int dx_iovec_count(dx_iovec_t *iov)
-{
- if (!iov)
- return 0;
- return iov->iov_count;
-}
-
diff --git a/extras/dispatch/src/iterator.c b/extras/dispatch/src/iterator.c
deleted file mode 100644
index 7898e04cc9..0000000000
--- a/extras/dispatch/src/iterator.c
+++ /dev/null
@@ -1,519 +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/dispatch/iterator.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/log.h>
-#include "message_private.h"
-#include <stdio.h>
-#include <string.h>
-
-//static const char *log_module = "FIELD";
-
-typedef enum {
- MODE_TO_END,
- MODE_TO_SLASH
-} parse_mode_t;
-
-typedef struct {
- dx_buffer_t *buffer;
- unsigned char *cursor;
- int length;
-} pointer_t;
-
-struct dx_field_iterator_t {
- pointer_t start_pointer;
- pointer_t view_start_pointer;
- pointer_t pointer;
- dx_iterator_view_t view;
- parse_mode_t mode;
- unsigned char prefix;
- int at_prefix;
- int view_prefix;
-};
-
-ALLOC_DECLARE(dx_field_iterator_t);
-ALLOC_DEFINE(dx_field_iterator_t);
-
-
-typedef enum {
- STATE_START,
- STATE_SLASH_LEFT,
- STATE_SKIPPING_TO_NEXT_SLASH,
- STATE_SCANNING,
- STATE_COLON,
- STATE_COLON_SLASH,
- STATE_AT_NODE_ID
-} state_t;
-
-
-static char *my_area = "";
-static char *my_router = "";
-
-
-static void parse_address_view(dx_field_iterator_t *iter)
-{
- //
- // This function starts with an iterator view that is identical to
- // ITER_VIEW_NO_HOST. We will now further refine the view in order
- // to aid the router in looking up addresses.
- //
-
- if (dx_field_iterator_prefix(iter, "_")) {
- if (dx_field_iterator_prefix(iter, "local/")) {
- iter->prefix = 'L';
- iter->at_prefix = 1;
- iter->view_prefix = 1;
- return;
- }
-
- if (dx_field_iterator_prefix(iter, "topo/")) {
- if (dx_field_iterator_prefix(iter, "all/") || dx_field_iterator_prefix(iter, my_area)) {
- if (dx_field_iterator_prefix(iter, "all/") || dx_field_iterator_prefix(iter, my_router)) {
- iter->prefix = 'L';
- iter->at_prefix = 1;
- iter->view_prefix = 1;
- return;
- }
-
- iter->prefix = 'R';
- iter->at_prefix = 1;
- iter->view_prefix = 1;
- iter->mode = MODE_TO_SLASH;
- return;
- }
-
- iter->prefix = 'A';
- iter->at_prefix = 1;
- iter->view_prefix = 1;
- iter->mode = MODE_TO_SLASH;
- return;
- }
- }
-
- iter->prefix = 'M';
- iter->at_prefix = 1;
- iter->view_prefix = 1;
-}
-
-
-static void parse_node_view(dx_field_iterator_t *iter)
-{
- //
- // This function starts with an iterator view that is identical to
- // ITER_VIEW_NO_HOST. We will now further refine the view in order
- // to aid the router in looking up nodes.
- //
-
- if (dx_field_iterator_prefix(iter, my_area)) {
- iter->prefix = 'R';
- iter->at_prefix = 1;
- iter->view_prefix = 1;
- iter->mode = MODE_TO_END;
- return;
- }
-
- iter->prefix = 'A';
- iter->at_prefix = 1;
- iter->view_prefix = 1;
- iter->mode = MODE_TO_SLASH;
-}
-
-
-static void view_initialize(dx_field_iterator_t *iter)
-{
- //
- // The default behavior is for the view to *not* have a prefix.
- // We'll add one if it's needed later.
- //
- iter->at_prefix = 0;
- iter->view_prefix = 0;
- iter->mode = MODE_TO_END;
-
- if (iter->view == ITER_VIEW_ALL)
- return;
-
- //
- // Advance to the node-id.
- //
- state_t state = STATE_START;
- unsigned int octet;
- pointer_t save_pointer = {0,0,0};
-
- while (!dx_field_iterator_end(iter) && state != STATE_AT_NODE_ID) {
- octet = dx_field_iterator_octet(iter);
- switch (state) {
- case STATE_START :
- if (octet == '/')
- state = STATE_SLASH_LEFT;
- else
- state = STATE_SCANNING;
- break;
-
- case STATE_SLASH_LEFT :
- if (octet == '/')
- state = STATE_SKIPPING_TO_NEXT_SLASH;
- else
- state = STATE_AT_NODE_ID;
- break;
-
- case STATE_SKIPPING_TO_NEXT_SLASH :
- if (octet == '/')
- state = STATE_AT_NODE_ID;
- break;
-
- case STATE_SCANNING :
- if (octet == ':')
- state = STATE_COLON;
- break;
-
- case STATE_COLON :
- if (octet == '/') {
- state = STATE_COLON_SLASH;
- save_pointer = iter->pointer;
- } else
- state = STATE_SCANNING;
- break;
-
- case STATE_COLON_SLASH :
- if (octet == '/')
- state = STATE_SKIPPING_TO_NEXT_SLASH;
- else {
- state = STATE_AT_NODE_ID;
- iter->pointer = save_pointer;
- }
- break;
-
- case STATE_AT_NODE_ID :
- break;
- }
- }
-
- if (state != STATE_AT_NODE_ID) {
- //
- // The address string was relative, not absolute. The node-id
- // is at the beginning of the string.
- //
- iter->pointer = iter->start_pointer;
- }
-
- //
- // Cursor is now on the first octet of the node-id
- //
- if (iter->view == ITER_VIEW_NODE_ID) {
- iter->mode = MODE_TO_SLASH;
- return;
- }
-
- if (iter->view == ITER_VIEW_NO_HOST) {
- iter->mode = MODE_TO_END;
- return;
- }
-
- if (iter->view == ITER_VIEW_ADDRESS_HASH) {
- iter->mode = MODE_TO_END;
- parse_address_view(iter);
- return;
- }
-
- if (iter->view == ITER_VIEW_NODE_HASH) {
- iter->mode = MODE_TO_END;
- parse_node_view(iter);
- return;
- }
-
- if (iter->view == ITER_VIEW_NODE_SPECIFIC) {
- iter->mode = MODE_TO_END;
- while (!dx_field_iterator_end(iter)) {
- octet = dx_field_iterator_octet(iter);
- if (octet == '/')
- break;
- }
- return;
- }
-}
-
-
-void dx_field_iterator_set_address(const char *area, const char *router)
-{
- my_area = (char*) malloc(strlen(area) + 2);
- strcpy(my_area, area);
- strcat(my_area, "/");
-
- my_router = (char*) malloc(strlen(router) + 2);
- strcpy(my_router, router);
- strcat(my_router, "/");
-}
-
-
-dx_field_iterator_t* dx_field_iterator_string(const char *text, dx_iterator_view_t view)
-{
- dx_field_iterator_t *iter = new_dx_field_iterator_t();
- if (!iter)
- return 0;
-
- iter->start_pointer.buffer = 0;
- iter->start_pointer.cursor = (unsigned char*) text;
- iter->start_pointer.length = strlen(text);
-
- dx_field_iterator_reset_view(iter, view);
-
- return iter;
-}
-
-
-dx_field_iterator_t* dx_field_iterator_binary(const char *text, int length, dx_iterator_view_t view)
-{
- dx_field_iterator_t *iter = new_dx_field_iterator_t();
- if (!iter)
- return 0;
-
- iter->start_pointer.buffer = 0;
- iter->start_pointer.cursor = (unsigned char*) text;
- iter->start_pointer.length = length;
-
- dx_field_iterator_reset_view(iter, view);
-
- return iter;
-}
-
-
-dx_field_iterator_t *dx_field_iterator_buffer(dx_buffer_t *buffer, int offset, int length, dx_iterator_view_t view)
-{
- dx_field_iterator_t *iter = new_dx_field_iterator_t();
- if (!iter)
- return 0;
-
- iter->start_pointer.buffer = buffer;
- iter->start_pointer.cursor = dx_buffer_base(buffer) + offset;
- iter->start_pointer.length = length;
-
- dx_field_iterator_reset_view(iter, view);
-
- return iter;
-}
-
-
-void dx_field_iterator_free(dx_field_iterator_t *iter)
-{
- free_dx_field_iterator_t(iter);
-}
-
-
-void dx_field_iterator_reset(dx_field_iterator_t *iter)
-{
- iter->pointer = iter->view_start_pointer;
- iter->at_prefix = iter->view_prefix;
-}
-
-
-void dx_field_iterator_reset_view(dx_field_iterator_t *iter, dx_iterator_view_t view)
-{
- iter->pointer = iter->start_pointer;
- iter->view = view;
-
- view_initialize(iter);
-
- iter->view_start_pointer = iter->pointer;
-}
-
-
-unsigned char dx_field_iterator_octet(dx_field_iterator_t *iter)
-{
- if (iter->at_prefix) {
- iter->at_prefix = 0;
- return iter->prefix;
- }
-
- if (iter->pointer.length == 0)
- return (unsigned char) 0;
-
- unsigned char result = *(iter->pointer.cursor);
-
- iter->pointer.cursor++;
- iter->pointer.length--;
-
- if (iter->pointer.length > 0) {
- if (iter->pointer.buffer) {
- if (iter->pointer.cursor - dx_buffer_base(iter->pointer.buffer) == dx_buffer_size(iter->pointer.buffer)) {
- iter->pointer.buffer = iter->pointer.buffer->next;
- if (iter->pointer.buffer == 0)
- iter->pointer.length = 0;
- iter->pointer.cursor = dx_buffer_base(iter->pointer.buffer);
- }
- }
- }
-
- if (iter->pointer.length && iter->mode == MODE_TO_SLASH && *(iter->pointer.cursor) == '/')
- iter->pointer.length = 0;
-
- return result;
-}
-
-
-int dx_field_iterator_end(dx_field_iterator_t *iter)
-{
- return iter->pointer.length == 0;
-}
-
-
-dx_field_iterator_t *dx_field_iterator_sub(dx_field_iterator_t *iter, uint32_t length)
-{
- dx_field_iterator_t *sub = new_dx_field_iterator_t();
- if (!sub)
- return 0;
-
- sub->start_pointer = iter->pointer;
- sub->start_pointer.length = length;
- sub->view_start_pointer = sub->start_pointer;
- sub->pointer = sub->start_pointer;
- sub->view = iter->view;
- sub->mode = iter->mode;
- sub->at_prefix = 0;
- sub->view_prefix = 0;
-
- return sub;
-}
-
-
-void dx_field_iterator_advance(dx_field_iterator_t *iter, uint32_t length)
-{
- // TODO - Make this more efficient.
- for (uint8_t idx = 0; idx < length && !dx_field_iterator_end(iter); idx++)
- dx_field_iterator_octet(iter);
-}
-
-
-uint32_t dx_field_iterator_remaining(dx_field_iterator_t *iter)
-{
- return iter->pointer.length;
-}
-
-
-int dx_field_iterator_equal(dx_field_iterator_t *iter, const unsigned char *string)
-{
- dx_field_iterator_reset(iter);
- while (!dx_field_iterator_end(iter) && *string) {
- if (*string != dx_field_iterator_octet(iter))
- return 0;
- string++;
- }
-
- return (dx_field_iterator_end(iter) && (*string == 0));
-}
-
-
-int dx_field_iterator_prefix(dx_field_iterator_t *iter, const char *prefix)
-{
- pointer_t save_pointer = iter->pointer;
- unsigned char *c = (unsigned char*) prefix;
-
- while(*c) {
- if (*c != dx_field_iterator_octet(iter))
- break;
- c++;
- }
-
- if (*c) {
- iter->pointer = save_pointer;
- return 0;
- }
-
- return 1;
-}
-
-
-unsigned char *dx_field_iterator_copy(dx_field_iterator_t *iter)
-{
- int length = 0;
- int idx = 0;
- unsigned char *copy;
-
- dx_field_iterator_reset(iter);
- while (!dx_field_iterator_end(iter)) {
- dx_field_iterator_octet(iter);
- length++;
- }
-
- dx_field_iterator_reset(iter);
- copy = (unsigned char*) malloc(length + 1);
- while (!dx_field_iterator_end(iter))
- copy[idx++] = dx_field_iterator_octet(iter);
- copy[idx] = '\0';
-
- return copy;
-}
-
-
-dx_iovec_t *dx_field_iterator_iovec(const dx_field_iterator_t *iter)
-{
- assert(!iter->view_prefix); // Not supported for views with a prefix
-
- //
- // Count the number of buffers this field straddles
- //
- pointer_t pointer = iter->view_start_pointer;
- int bufcnt = 1;
- dx_buffer_t *buf = pointer.buffer;
- size_t bufsize = dx_buffer_size(buf) - (pointer.cursor - dx_buffer_base(pointer.buffer));
- ssize_t remaining = pointer.length - bufsize;
-
- while (remaining > 0) {
- bufcnt++;
- buf = buf->next;
- if (!buf)
- return 0;
- remaining -= dx_buffer_size(buf);
- }
-
- //
- // Allocate an iovec object big enough to hold the number of buffers
- //
- dx_iovec_t *iov = dx_iovec(bufcnt);
- if (!iov)
- return 0;
-
- //
- // Build out the io vectors with pointers to the segments of the field in buffers
- //
- bufcnt = 0;
- buf = pointer.buffer;
- bufsize = dx_buffer_size(buf) - (pointer.cursor - dx_buffer_base(pointer.buffer));
- void *base = pointer.cursor;
- remaining = pointer.length;
-
- while (remaining > 0) {
- if (bufsize > remaining)
- bufsize = remaining;
- dx_iovec_array(iov)[bufcnt].iov_base = base;
- dx_iovec_array(iov)[bufcnt].iov_len = bufsize;
- bufcnt++;
- remaining -= bufsize;
- if (remaining > 0) {
- buf = buf->next;
- base = dx_buffer_base(buf);
- bufsize = dx_buffer_size(buf);
- }
- }
-
- return iov;
-}
-
-
diff --git a/extras/dispatch/src/log.c b/extras/dispatch/src/log.c
deleted file mode 100644
index 281603255d..0000000000
--- a/extras/dispatch/src/log.c
+++ /dev/null
@@ -1,116 +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 "log_private.h"
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/threading.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-
-#define TEXT_MAX 512
-#define LIST_MAX 1000
-
-typedef struct dx_log_entry_t dx_log_entry_t;
-
-struct dx_log_entry_t {
- DEQ_LINKS(dx_log_entry_t);
- const char *module;
- int cls;
- const char *file;
- int line;
- struct timeval tv;
- char text[TEXT_MAX];
-};
-
-ALLOC_DECLARE(dx_log_entry_t);
-ALLOC_DEFINE(dx_log_entry_t);
-
-DEQ_DECLARE(dx_log_entry_t, dx_log_list_t);
-
-static int mask = LOG_INFO;
-static dx_log_list_t entries;
-static sys_mutex_t *log_lock = 0;
-
-
-static const char *cls_prefix(int cls)
-{
- switch (cls) {
- case LOG_TRACE : return "TRACE";
- case LOG_DEBUG : return "DEBUG";
- case LOG_INFO : return "INFO";
- case LOG_NOTICE : return "NOTICE";
- case LOG_WARNING : return "WARNING";
- case LOG_ERROR : return "ERROR";
- case LOG_CRITICAL : return "CRITICAL";
- }
-
- return "";
-}
-
-void dx_log_impl(const char *module, int cls, const char *file, int line, const char *fmt, ...)
-{
- if (!(cls & mask))
- return;
-
- dx_log_entry_t *entry = new_dx_log_entry_t();
- DEQ_ITEM_INIT(entry);
- entry->module = module;
- entry->cls = cls;
- entry->file = file;
- entry->line = line;
- gettimeofday(&entry->tv, 0);
-
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(entry->text, TEXT_MAX, fmt, ap);
- va_end(ap);
- fprintf(stderr, "%s (%s) %s\n", module, cls_prefix(cls), entry->text);
-
- sys_mutex_lock(log_lock);
- DEQ_INSERT_TAIL(entries, entry);
- if (DEQ_SIZE(entries) > LIST_MAX) {
- entry = DEQ_HEAD(entries);
- DEQ_REMOVE_HEAD(entries);
- free_dx_log_entry_t(entry);
- }
- sys_mutex_unlock(log_lock);
-}
-
-void dx_log_set_mask(int _mask)
-{
- mask = _mask;
-}
-
-
-void dx_log_initialize(void)
-{
- DEQ_INIT(entries);
- log_lock = sys_mutex();
-}
-
-
-void dx_log_finalize(void)
-{
-}
-
-
diff --git a/extras/dispatch/src/log_private.h b/extras/dispatch/src/log_private.h
deleted file mode 100644
index 0b36bbc9a9..0000000000
--- a/extras/dispatch/src/log_private.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef __log_private_h__
-#define __log_private_h__ 1
-/*
- * 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/dispatch/log.h>
-
-void dx_log_initialize(void);
-void dx_log_finalize(void);
-
-#endif
diff --git a/extras/dispatch/src/message.c b/extras/dispatch/src/message.c
deleted file mode 100644
index 86ffcefcee..0000000000
--- a/extras/dispatch/src/message.c
+++ /dev/null
@@ -1,879 +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/dispatch/ctools.h>
-#include <qpid/dispatch/amqp.h>
-#include <qpid/dispatch/threading.h>
-#include "message_private.h"
-#include "compose_private.h"
-#include <string.h>
-#include <stdio.h>
-
-static const unsigned char * const MSG_HDR_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x70";
-static const unsigned char * const MSG_HDR_SHORT = (unsigned char*) "\x00\x53\x70";
-static const unsigned char * const DELIVERY_ANNOTATION_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x71";
-static const unsigned char * const DELIVERY_ANNOTATION_SHORT = (unsigned char*) "\x00\x53\x71";
-static const unsigned char * const MESSAGE_ANNOTATION_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x72";
-static const unsigned char * const MESSAGE_ANNOTATION_SHORT = (unsigned char*) "\x00\x53\x72";
-static const unsigned char * const PROPERTIES_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x73";
-static const unsigned char * const PROPERTIES_SHORT = (unsigned char*) "\x00\x53\x73";
-static const unsigned char * const APPLICATION_PROPERTIES_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x74";
-static const unsigned char * const APPLICATION_PROPERTIES_SHORT = (unsigned char*) "\x00\x53\x74";
-static const unsigned char * const BODY_DATA_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x75";
-static const unsigned char * const BODY_DATA_SHORT = (unsigned char*) "\x00\x53\x75";
-static const unsigned char * const BODY_SEQUENCE_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x76";
-static const unsigned char * const BODY_SEQUENCE_SHORT = (unsigned char*) "\x00\x53\x76";
-static const unsigned char * const BODY_VALUE_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x77";
-static const unsigned char * const BODY_VALUE_SHORT = (unsigned char*) "\x00\x53\x77";
-static const unsigned char * const FOOTER_LONG = (unsigned char*) "\x00\x80\x00\x00\x00\x00\x00\x00\x00\x78";
-static const unsigned char * const FOOTER_SHORT = (unsigned char*) "\x00\x53\x78";
-static const unsigned char * const TAGS_LIST = (unsigned char*) "\x45\xc0\xd0";
-static const unsigned char * const TAGS_MAP = (unsigned char*) "\xc1\xd1";
-static const unsigned char * const TAGS_BINARY = (unsigned char*) "\xa0\xb0";
-static const unsigned char * const TAGS_ANY = (unsigned char*) "\x45\xc0\xd0\xc1\xd1\xa0\xb0";
-
-ALLOC_DEFINE_CONFIG(dx_message_t, sizeof(dx_message_pvt_t), 0, 0);
-ALLOC_DEFINE(dx_message_content_t);
-
-typedef void (*buffer_process_t) (void *context, const unsigned char *base, int length);
-
-static void advance(unsigned char **cursor, dx_buffer_t **buffer, int consume, buffer_process_t handler, void *context)
-{
- unsigned char *local_cursor = *cursor;
- dx_buffer_t *local_buffer = *buffer;
-
- int remaining = dx_buffer_size(local_buffer) - (local_cursor - dx_buffer_base(local_buffer));
- while (consume > 0) {
- if (consume < remaining) {
- if (handler)
- handler(context, local_cursor, consume);
- local_cursor += consume;
- consume = 0;
- } else {
- if (handler)
- handler(context, local_cursor, remaining);
- consume -= remaining;
- local_buffer = local_buffer->next;
- if (local_buffer == 0){
- local_cursor = 0;
- break;
- }
- local_cursor = dx_buffer_base(local_buffer);
- remaining = dx_buffer_size(local_buffer) - (local_cursor - dx_buffer_base(local_buffer));
- }
- }
-
- *cursor = local_cursor;
- *buffer = local_buffer;
-}
-
-
-static unsigned char next_octet(unsigned char **cursor, dx_buffer_t **buffer)
-{
- unsigned char result = **cursor;
- advance(cursor, buffer, 1, 0, 0);
- return result;
-}
-
-
-static int traverse_field(unsigned char **cursor, dx_buffer_t **buffer, dx_field_location_t *field)
-{
- unsigned char tag = next_octet(cursor, buffer);
- if (!(*cursor)) return 0;
-
- int consume = 0;
- size_t hdr_length = 1;
-
- switch (tag & 0xF0) {
- case 0x40 : consume = 0; break;
- case 0x50 : consume = 1; break;
- case 0x60 : consume = 2; break;
- case 0x70 : consume = 4; break;
- case 0x80 : consume = 8; break;
- case 0x90 : consume = 16; break;
-
- case 0xB0 :
- case 0xD0 :
- case 0xF0 :
- hdr_length += 3;
- consume |= ((int) next_octet(cursor, buffer)) << 24;
- if (!(*cursor)) return 0;
- consume |= ((int) next_octet(cursor, buffer)) << 16;
- if (!(*cursor)) return 0;
- consume |= ((int) next_octet(cursor, buffer)) << 8;
- if (!(*cursor)) return 0;
- // Fall through to the next case...
-
- case 0xA0 :
- case 0xC0 :
- case 0xE0 :
- hdr_length++;
- consume |= (int) next_octet(cursor, buffer);
- if (!(*cursor)) return 0;
- break;
- }
-
- if (field && !field->parsed) {
- field->buffer = *buffer;
- field->offset = *cursor - dx_buffer_base(*buffer);
- field->length = consume;
- field->hdr_length = hdr_length;
- field->parsed = 1;
- }
-
- advance(cursor, buffer, consume, 0, 0);
- return 1;
-}
-
-
-static int start_list(unsigned char **cursor, dx_buffer_t **buffer)
-{
- unsigned char tag = next_octet(cursor, buffer);
- if (!(*cursor)) return 0;
- int length = 0;
- int count = 0;
-
- switch (tag) {
- case 0x45 : // list0
- break;
- case 0xd0 : // list32
- length |= ((int) next_octet(cursor, buffer)) << 24;
- if (!(*cursor)) return 0;
- length |= ((int) next_octet(cursor, buffer)) << 16;
- if (!(*cursor)) return 0;
- length |= ((int) next_octet(cursor, buffer)) << 8;
- if (!(*cursor)) return 0;
- length |= (int) next_octet(cursor, buffer);
- if (!(*cursor)) return 0;
-
- count |= ((int) next_octet(cursor, buffer)) << 24;
- if (!(*cursor)) return 0;
- count |= ((int) next_octet(cursor, buffer)) << 16;
- if (!(*cursor)) return 0;
- count |= ((int) next_octet(cursor, buffer)) << 8;
- if (!(*cursor)) return 0;
- count |= (int) next_octet(cursor, buffer);
- if (!(*cursor)) return 0;
-
- break;
-
- case 0xc0 : // list8
- length |= (int) next_octet(cursor, buffer);
- if (!(*cursor)) return 0;
-
- count |= (int) next_octet(cursor, buffer);
- if (!(*cursor)) return 0;
- break;
- }
-
- return count;
-}
-
-
-//
-// Check the buffer chain, starting at cursor to see if it matches the pattern.
-// If the pattern matches, check the next tag to see if it's in the set of expected
-// tags. If not, return zero. If so, set the location descriptor to the good
-// tag and advance the cursor (and buffer, if needed) to the end of the matched section.
-//
-// If there is no match, don't advance the cursor.
-//
-// Return 0 if the pattern matches but the following tag is unexpected
-// Return 0 if the pattern matches and the location already has a pointer (duplicate section)
-// Return 1 if the pattern matches and we've advanced the cursor/buffer
-// Return 1 if the pattern does not match
-//
-static int dx_check_and_advance(dx_buffer_t **buffer,
- unsigned char **cursor,
- const unsigned char *pattern,
- int pattern_length,
- const unsigned char *expected_tags,
- dx_field_location_t *location)
-{
- dx_buffer_t *test_buffer = *buffer;
- unsigned char *test_cursor = *cursor;
-
- if (!test_cursor)
- return 1; // no match
-
- unsigned char *end_of_buffer = dx_buffer_base(test_buffer) + dx_buffer_size(test_buffer);
- int idx = 0;
-
- while (idx < pattern_length && *test_cursor == pattern[idx]) {
- idx++;
- test_cursor++;
- if (test_cursor == end_of_buffer) {
- test_buffer = test_buffer->next;
- if (test_buffer == 0)
- return 1; // Pattern didn't match
- test_cursor = dx_buffer_base(test_buffer);
- end_of_buffer = test_cursor + dx_buffer_size(test_buffer);
- }
- }
-
- if (idx < pattern_length)
- return 1; // Pattern didn't match
-
- //
- // Pattern matched, check the tag
- //
- while (*expected_tags && *test_cursor != *expected_tags)
- expected_tags++;
- if (*expected_tags == 0)
- return 0; // Unexpected tag
-
- if (location->parsed)
- return 0; // Duplicate section
-
- //
- // Pattern matched and tag is expected. Mark the beginning of the section.
- //
- location->parsed = 1;
- location->buffer = test_buffer;
- location->offset = test_cursor - dx_buffer_base(test_buffer);
- location->length = 0;
- location->hdr_length = pattern_length;
-
- //
- // Advance the pointers to consume the whole section.
- //
- int pre_consume = 1; // Count the already extracted tag
- int consume = 0;
- unsigned char tag = next_octet(&test_cursor, &test_buffer);
- if (!test_cursor) return 0;
- switch (tag) {
- case 0x45 : // list0
- break;
-
- case 0xd0 : // list32
- case 0xd1 : // map32
- case 0xb0 : // vbin32
- pre_consume += 3;
- consume |= ((int) next_octet(&test_cursor, &test_buffer)) << 24;
- if (!test_cursor) return 0;
- consume |= ((int) next_octet(&test_cursor, &test_buffer)) << 16;
- if (!test_cursor) return 0;
- consume |= ((int) next_octet(&test_cursor, &test_buffer)) << 8;
- if (!test_cursor) return 0;
- // Fall through to the next case...
-
- case 0xc0 : // list8
- case 0xc1 : // map8
- case 0xa0 : // vbin8
- pre_consume += 1;
- consume |= (int) next_octet(&test_cursor, &test_buffer);
- if (!test_cursor) return 0;
- break;
- }
-
- location->length = pre_consume + consume;
- if (consume)
- advance(&test_cursor, &test_buffer, consume, 0, 0);
-
- *cursor = test_cursor;
- *buffer = test_buffer;
- return 1;
-}
-
-
-static dx_field_location_t *dx_message_field_location(dx_message_t *msg, dx_message_field_t field)
-{
- dx_message_content_t *content = MSG_CONTENT(msg);
-
- switch (field) {
- case DX_FIELD_TO:
- while (1) {
- if (content->field_to.parsed)
- return &content->field_to;
-
- if (content->section_message_properties.parsed == 0)
- break;
-
- dx_buffer_t *buffer = content->section_message_properties.buffer;
- unsigned char *cursor = dx_buffer_base(buffer) + content->section_message_properties.offset;
-
- int count = start_list(&cursor, &buffer);
- int result;
-
- if (count < 3)
- break;
-
- result = traverse_field(&cursor, &buffer, 0); // message_id
- if (!result) return 0;
- result = traverse_field(&cursor, &buffer, &content->field_user_id); // user_id
- if (!result) return 0;
- result = traverse_field(&cursor, &buffer, &content->field_to); // to
- if (!result) return 0;
- }
- break;
-
- case DX_FIELD_REPLY_TO:
- while (1) {
- if (content->field_reply_to.parsed)
- return &content->field_reply_to;
-
- if (content->section_message_properties.parsed == 0)
- break;
-
- dx_buffer_t *buffer = content->section_message_properties.buffer;
- unsigned char *cursor = dx_buffer_base(buffer) + content->section_message_properties.offset;
-
- int count = start_list(&cursor, &buffer);
- int result;
-
- if (count < 5)
- break;
-
- result = traverse_field(&cursor, &buffer, 0); // message_id
- if (!result) return 0;
- result = traverse_field(&cursor, &buffer, &content->field_user_id); // user_id
- if (!result) return 0;
- result = traverse_field(&cursor, &buffer, &content->field_to); // to
- if (!result) return 0;
- result = traverse_field(&cursor, &buffer, 0); // subject
- if (!result) return 0;
- result = traverse_field(&cursor, &buffer, &content->field_reply_to); // reply_to
- if (!result) return 0;
- }
- break;
-
- case DX_FIELD_DELIVERY_ANNOTATION:
- if (content->section_delivery_annotation.parsed)
- return &content->section_delivery_annotation;
- break;
-
- case DX_FIELD_APPLICATION_PROPERTIES:
- if (content->section_application_properties.parsed)
- return &content->section_application_properties;
- break;
-
- case DX_FIELD_BODY:
- if (content->section_body.parsed)
- return &content->section_body;
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
-
-dx_message_t *dx_message()
-{
- dx_message_pvt_t *msg = (dx_message_pvt_t*) new_dx_message_t();
- if (!msg)
- return 0;
-
- DEQ_ITEM_INIT(msg);
- msg->content = new_dx_message_content_t();
-
- if (msg->content == 0) {
- free_dx_message_t((dx_message_t*) msg);
- return 0;
- }
-
- memset(msg->content, 0, sizeof(dx_message_content_t));
- msg->content->lock = sys_mutex();
- msg->content->ref_count = 1;
- msg->content->parse_depth = DX_DEPTH_NONE;
- msg->content->parsed_delivery_annotations = 0;
-
- return (dx_message_t*) msg;
-}
-
-
-void dx_message_free(dx_message_t *in_msg)
-{
- uint32_t rc;
- dx_message_pvt_t *msg = (dx_message_pvt_t*) in_msg;
- dx_message_content_t *content = msg->content;
-
- sys_mutex_lock(content->lock);
- rc = --content->ref_count;
- sys_mutex_unlock(content->lock);
-
- if (rc == 0) {
- if (content->parsed_delivery_annotations)
- dx_parse_free(content->parsed_delivery_annotations);
-
- dx_buffer_t *buf = DEQ_HEAD(content->buffers);
- while (buf) {
- DEQ_REMOVE_HEAD(content->buffers);
- dx_buffer_free(buf);
- buf = DEQ_HEAD(content->buffers);
- }
-
- buf = DEQ_HEAD(content->new_delivery_annotations);
- while (buf) {
- DEQ_REMOVE_HEAD(content->new_delivery_annotations);
- dx_buffer_free(buf);
- buf = DEQ_HEAD(content->new_delivery_annotations);
- }
-
- sys_mutex_free(content->lock);
- free_dx_message_content_t(content);
- }
-
- free_dx_message_t((dx_message_t*) msg);
-}
-
-
-dx_message_t *dx_message_copy(dx_message_t *in_msg)
-{
- dx_message_pvt_t *msg = (dx_message_pvt_t*) in_msg;
- dx_message_content_t *content = msg->content;
- dx_message_pvt_t *copy = (dx_message_pvt_t*) new_dx_message_t();
-
- if (!copy)
- return 0;
-
- DEQ_ITEM_INIT(copy);
- copy->content = content;
-
- sys_mutex_lock(content->lock);
- content->ref_count++;
- sys_mutex_unlock(content->lock);
-
- return (dx_message_t*) copy;
-}
-
-
-dx_parsed_field_t *dx_message_delivery_annotations(dx_message_t *in_msg)
-{
- dx_message_pvt_t *msg = (dx_message_pvt_t*) in_msg;
- dx_message_content_t *content = msg->content;
-
- if (content->parsed_delivery_annotations)
- return content->parsed_delivery_annotations;
-
- dx_field_iterator_t *da = dx_message_field_iterator(in_msg, DX_FIELD_DELIVERY_ANNOTATION);
- if (da == 0)
- return 0;
-
- content->parsed_delivery_annotations = dx_parse(da);
- if (content->parsed_delivery_annotations == 0 ||
- !dx_parse_ok(content->parsed_delivery_annotations) ||
- !dx_parse_is_map(content->parsed_delivery_annotations)) {
- dx_field_iterator_free(da);
- dx_parse_free(content->parsed_delivery_annotations);
- content->parsed_delivery_annotations = 0;
- return 0;
- }
-
- dx_field_iterator_free(da);
- return content->parsed_delivery_annotations;
-}
-
-
-void dx_message_set_delivery_annotations(dx_message_t *msg, dx_composed_field_t *da)
-{
- dx_message_content_t *content = MSG_CONTENT(msg);
- dx_buffer_list_t *field_buffers = dx_compose_buffers(da);
-
- assert(DEQ_SIZE(content->new_delivery_annotations) == 0);
- content->new_delivery_annotations = *field_buffers;
- DEQ_INIT(*field_buffers); // Zero out the linkage to the now moved buffers.
-}
-
-
-dx_message_t *dx_message_receive(dx_delivery_t *delivery)
-{
- pn_delivery_t *pnd = dx_delivery_pn(delivery);
- dx_message_pvt_t *msg = (dx_message_pvt_t*) dx_delivery_context(delivery);
- pn_link_t *link = pn_delivery_link(pnd);
- ssize_t rc;
- dx_buffer_t *buf;
-
- //
- // If there is no message associated with the delivery, this is the first time
- // we've received anything on this delivery. Allocate a message descriptor and
- // link it and the delivery together.
- //
- if (!msg) {
- msg = (dx_message_pvt_t*) dx_message();
- dx_delivery_set_context(delivery, (void*) msg);
- }
-
- //
- // Get a reference to the tail buffer on the message. This is the buffer into which
- // we will store incoming message data. If there is no buffer in the message, allocate
- // an empty one and add it to the message.
- //
- buf = DEQ_TAIL(msg->content->buffers);
- if (!buf) {
- buf = dx_buffer();
- DEQ_INSERT_TAIL(msg->content->buffers, buf);
- }
-
- while (1) {
- //
- // Try to receive enough data to fill the remaining space in the tail buffer.
- //
- rc = pn_link_recv(link, (char*) dx_buffer_cursor(buf), dx_buffer_capacity(buf));
-
- //
- // If we receive PN_EOS, we have come to the end of the message.
- //
- if (rc == PN_EOS) {
- //
- // If the last buffer in the list is empty, remove it and free it. This
- // will only happen if the size of the message content is an exact multiple
- // of the buffer size.
- //
- if (dx_buffer_size(buf) == 0) {
- DEQ_REMOVE_TAIL(msg->content->buffers);
- dx_buffer_free(buf);
- }
- dx_delivery_set_context(delivery, 0);
- return (dx_message_t*) msg;
- }
-
- if (rc > 0) {
- //
- // We have received a positive number of bytes for the message. Advance
- // the cursor in the buffer.
- //
- dx_buffer_insert(buf, rc);
-
- //
- // If the buffer is full, allocate a new empty buffer and append it to the
- // tail of the message's list.
- //
- if (dx_buffer_capacity(buf) == 0) {
- buf = dx_buffer();
- DEQ_INSERT_TAIL(msg->content->buffers, buf);
- }
- } else
- //
- // We received zero bytes, and no PN_EOS. This means that we've received
- // all of the data available up to this point, but it does not constitute
- // the entire message. We'll be back later to finish it up.
- //
- break;
- }
-
- return 0;
-}
-
-
-static void send_handler(void *context, const unsigned char *start, int length)
-{
- pn_link_t *pnl = (pn_link_t*) context;
- pn_link_send(pnl, (const char*) start, length);
-}
-
-
-void dx_message_send(dx_message_t *in_msg, dx_link_t *link)
-{
- dx_message_pvt_t *msg = (dx_message_pvt_t*) in_msg;
- dx_message_content_t *content = msg->content;
- dx_buffer_t *buf = DEQ_HEAD(content->buffers);
- unsigned char *cursor;
- pn_link_t *pnl = dx_link_pn(link);
-
- if (DEQ_SIZE(content->new_delivery_annotations) > 0) {
- //
- // This is the case where the delivery annotations have been modified.
- // The message send must be divided into sections: The existing header;
- // the new delivery annotations; the rest of the existing message.
- // Note that the original delivery annotations that are still in the
- // buffer chain must not be sent.
- //
- // Start by making sure that we've parsed the message sections through
- // the delivery annotations
- //
- if (!dx_message_check(in_msg, DX_DEPTH_DELIVERY_ANNOTATIONS))
- return;
-
- //
- // Send header if present
- //
- cursor = dx_buffer_base(buf);
- if (content->section_message_header.length > 0) {
- pn_link_send(pnl, (const char*) MSG_HDR_SHORT, 3);
- buf = content->section_message_header.buffer;
- cursor = content->section_message_header.offset + dx_buffer_base(buf);
- advance(&cursor, &buf, content->section_message_header.length, send_handler, (void*) pnl);
- }
-
- //
- // Send new delivery annotations
- //
- dx_buffer_t *da_buf = DEQ_HEAD(content->new_delivery_annotations);
- while (da_buf) {
- pn_link_send(pnl, (char*) dx_buffer_base(da_buf), dx_buffer_size(da_buf));
- da_buf = DEQ_NEXT(da_buf);
- }
-
- //
- // Skip over replaced delivery annotations
- //
- if (content->section_delivery_annotation.length > 0)
- advance(&cursor, &buf,
- content->section_delivery_annotation.hdr_length + content->section_delivery_annotation.length,
- 0, 0);
-
- //
- // Send remaining partial buffer
- //
- if (buf) {
- size_t len = dx_buffer_size(buf) - (cursor - dx_buffer_base(buf));
- advance(&cursor, &buf, len, send_handler, (void*) pnl);
- }
-
- // Fall through to process the remaining buffers normally
- }
-
- while (buf) {
- pn_link_send(pnl, (char*) dx_buffer_base(buf), dx_buffer_size(buf));
- buf = DEQ_NEXT(buf);
- }
-}
-
-
-static int dx_check_field_LH(dx_message_content_t *content,
- dx_message_depth_t depth,
- const unsigned char *long_pattern,
- const unsigned char *short_pattern,
- const unsigned char *expected_tags,
- dx_field_location_t *location,
- int more)
-{
-#define LONG 10
-#define SHORT 3
- if (depth > content->parse_depth) {
- if (0 == dx_check_and_advance(&content->parse_buffer, &content->parse_cursor, long_pattern, LONG, expected_tags, location))
- return 0;
- if (0 == dx_check_and_advance(&content->parse_buffer, &content->parse_cursor, short_pattern, SHORT, expected_tags, location))
- return 0;
- if (!more)
- content->parse_depth = depth;
- }
- return 1;
-}
-
-
-static int dx_message_check_LH(dx_message_content_t *content, dx_message_depth_t depth)
-{
- dx_buffer_t *buffer = DEQ_HEAD(content->buffers);
-
- if (!buffer)
- return 0; // Invalid - No data in the message
-
- if (depth <= content->parse_depth)
- return 1; // We've already parsed at least this deep
-
- if (content->parse_buffer == 0) {
- content->parse_buffer = buffer;
- content->parse_cursor = dx_buffer_base(content->parse_buffer);
- }
-
- if (depth == DX_DEPTH_NONE)
- return 1;
-
- //
- // MESSAGE HEADER
- //
- if (0 == dx_check_field_LH(content, DX_DEPTH_HEADER,
- MSG_HDR_LONG, MSG_HDR_SHORT, TAGS_LIST, &content->section_message_header, 0))
- return 0;
- if (depth == DX_DEPTH_HEADER)
- return 1;
-
- //
- // DELIVERY ANNOTATION
- //
- if (0 == dx_check_field_LH(content, DX_DEPTH_DELIVERY_ANNOTATIONS,
- DELIVERY_ANNOTATION_LONG, DELIVERY_ANNOTATION_SHORT, TAGS_MAP, &content->section_delivery_annotation, 0))
- return 0;
- if (depth == DX_DEPTH_DELIVERY_ANNOTATIONS)
- return 1;
-
- //
- // MESSAGE ANNOTATION
- //
- if (0 == dx_check_field_LH(content, DX_DEPTH_MESSAGE_ANNOTATIONS,
- MESSAGE_ANNOTATION_LONG, MESSAGE_ANNOTATION_SHORT, TAGS_MAP, &content->section_message_annotation, 0))
- return 0;
- if (depth == DX_DEPTH_MESSAGE_ANNOTATIONS)
- return 1;
-
- //
- // PROPERTIES
- //
- if (0 == dx_check_field_LH(content, DX_DEPTH_PROPERTIES,
- PROPERTIES_LONG, PROPERTIES_SHORT, TAGS_LIST, &content->section_message_properties, 0))
- return 0;
- if (depth == DX_DEPTH_PROPERTIES)
- return 1;
-
- //
- // APPLICATION PROPERTIES
- //
- if (0 == dx_check_field_LH(content, DX_DEPTH_APPLICATION_PROPERTIES,
- APPLICATION_PROPERTIES_LONG, APPLICATION_PROPERTIES_SHORT, TAGS_MAP, &content->section_application_properties, 0))
- return 0;
- if (depth == DX_DEPTH_APPLICATION_PROPERTIES)
- return 1;
-
- //
- // BODY
- // Note that this function expects a limited set of types in a VALUE section. This is
- // not a problem for messages passing through Dispatch because through-only messages won't
- // be parsed to BODY-depth.
- //
- if (0 == dx_check_field_LH(content, DX_DEPTH_BODY,
- BODY_DATA_LONG, BODY_DATA_SHORT, TAGS_BINARY, &content->section_body, 1))
- return 0;
- if (0 == dx_check_field_LH(content, DX_DEPTH_BODY,
- BODY_SEQUENCE_LONG, BODY_SEQUENCE_SHORT, TAGS_LIST, &content->section_body, 1))
- return 0;
- if (0 == dx_check_field_LH(content, DX_DEPTH_BODY,
- BODY_VALUE_LONG, BODY_VALUE_SHORT, TAGS_ANY, &content->section_body, 0))
- return 0;
- if (depth == DX_DEPTH_BODY)
- return 1;
-
- //
- // FOOTER
- //
- if (0 == dx_check_field_LH(content, DX_DEPTH_ALL,
- FOOTER_LONG, FOOTER_SHORT, TAGS_MAP, &content->section_footer, 0))
- return 0;
-
- return 1;
-}
-
-
-int dx_message_check(dx_message_t *in_msg, dx_message_depth_t depth)
-{
- dx_message_pvt_t *msg = (dx_message_pvt_t*) in_msg;
- dx_message_content_t *content = msg->content;
- int result;
-
- sys_mutex_lock(content->lock);
- result = dx_message_check_LH(content, depth);
- sys_mutex_unlock(content->lock);
-
- return result;
-}
-
-
-dx_field_iterator_t *dx_message_field_iterator(dx_message_t *msg, dx_message_field_t field)
-{
- dx_field_location_t *loc = dx_message_field_location(msg, field);
- if (!loc)
- return 0;
-
- return dx_field_iterator_buffer(loc->buffer, loc->offset, loc->length, ITER_VIEW_ALL);
-}
-
-
-ssize_t dx_message_field_length(dx_message_t *msg, dx_message_field_t field)
-{
- dx_field_location_t *loc = dx_message_field_location(msg, field);
- if (!loc)
- return -1;
-
- return loc->length;
-}
-
-
-ssize_t dx_message_field_copy(dx_message_t *msg, dx_message_field_t field, void *buffer)
-{
- dx_field_location_t *loc = dx_message_field_location(msg, field);
- if (!loc)
- return -1;
-
- dx_buffer_t *buf = loc->buffer;
- size_t bufsize = dx_buffer_size(buf) - loc->offset;
- void *base = dx_buffer_base(buf) + loc->offset;
- size_t remaining = loc->length;
-
- while (remaining > 0) {
- if (bufsize > remaining)
- bufsize = remaining;
- memcpy(buffer, base, bufsize);
- buffer += bufsize;
- remaining -= bufsize;
- if (remaining > 0) {
- buf = buf->next;
- base = dx_buffer_base(buf);
- bufsize = dx_buffer_size(buf);
- }
- }
-
- return loc->length;
-}
-
-
-void dx_message_compose_1(dx_message_t *msg, const char *to, dx_buffer_list_t *buffers)
-{
- dx_composed_field_t *field = dx_compose(DX_PERFORMATIVE_HEADER, 0);
- dx_message_content_t *content = MSG_CONTENT(msg);
-
- dx_compose_start_list(field);
- dx_compose_insert_bool(field, 0); // durable
- //dx_compose_insert_null(field); // priority
- //dx_compose_insert_null(field); // ttl
- //dx_compose_insert_boolean(field, 0); // first-acquirer
- //dx_compose_insert_uint(field, 0); // delivery-count
- dx_compose_end_list(field);
-
- field = dx_compose(DX_PERFORMATIVE_PROPERTIES, field);
- dx_compose_start_list(field);
- dx_compose_insert_null(field); // message-id
- dx_compose_insert_null(field); // user-id
- dx_compose_insert_string(field, to); // to
- //dx_compose_insert_null(field); // subject
- //dx_compose_insert_null(field); // reply-to
- //dx_compose_insert_null(field); // correlation-id
- //dx_compose_insert_null(field); // content-type
- //dx_compose_insert_null(field); // content-encoding
- //dx_compose_insert_timestamp(field, 0); // absolute-expiry-time
- //dx_compose_insert_timestamp(field, 0); // creation-time
- //dx_compose_insert_null(field); // group-id
- //dx_compose_insert_uint(field, 0); // group-sequence
- //dx_compose_insert_null(field); // reply-to-group-id
- dx_compose_end_list(field);
-
- if (buffers) {
- field = dx_compose(DX_PERFORMATIVE_BODY_DATA, field);
- dx_compose_insert_binary_buffers(field, buffers);
- }
-
- dx_buffer_list_t *field_buffers = dx_compose_buffers(field);
- content->buffers = *field_buffers;
- DEQ_INIT(*field_buffers); // Zero out the linkage to the now moved buffers.
-
- dx_compose_free(field);
-}
-
-
-void dx_message_compose_2(dx_message_t *msg, dx_composed_field_t *field)
-{
- dx_message_content_t *content = MSG_CONTENT(msg);
- dx_buffer_list_t *field_buffers = dx_compose_buffers(field);
-
- content->buffers = *field_buffers;
- DEQ_INIT(*field_buffers); // Zero out the linkage to the now moved buffers.
-}
-
diff --git a/extras/dispatch/src/message_private.h b/extras/dispatch/src/message_private.h
deleted file mode 100644
index c57cea5f0d..0000000000
--- a/extras/dispatch/src/message_private.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef __message_private_h__
-#define __message_private_h__ 1
-/*
- * 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/dispatch/message.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/threading.h>
-
-/**
- * Architecture of the message module:
- *
- * +--------------+ +----------------------+
- * | | | |
- * | dx_message_t |----------->| dx_message_content_t |
- * | | +----->| |
- * +--------------+ | +----------------------+
- * | |
- * +--------------+ | | +-------------+ +-------------+ +-------------+
- * | | | +--->| dx_buffer_t |-->| dx_buffer_t |-->| dx_buffer_t |--/
- * | dx_message_t |-----+ +-------------+ +-------------+ +-------------+
- * | |
- * +--------------+
- *
- * The message module provides chained-fixed-sized-buffer storage of message content with multiple
- * references. If a message is received and is to be queued for multiple destinations, there is only
- * one copy of the message content in memory but multiple lightweight references to the content.
- *
- */
-
-typedef struct {
- dx_buffer_t *buffer; // Buffer that contains the first octet of the field, null if the field is not present
- size_t offset; // Offset in the buffer to the first octet
- size_t length; // Length of the field or zero if unneeded
- size_t hdr_length; // Length of the field's header (not included in the length of the field)
- int parsed; // non-zero iff the buffer chain has been parsed to find this field
-} dx_field_location_t;
-
-
-// TODO - consider using pointers to dx_field_location_t below to save memory
-// TODO - we need a second buffer list for modified annotations and header
-// There are three message scenarios:
-// 1) Received message is held and forwarded unmodified - single buffer list
-// 2) Received message is held and modified before forwarding - two buffer lists
-// 3) Message is composed internally - single buffer list
-// TODO - provide a way to allocate a message without a lock for the link-routing case.
-// It's likely that link-routing will cause no contention for the message content.
-//
-
-typedef struct {
- sys_mutex_t *lock;
- uint32_t ref_count; // The number of messages referencing this
- dx_buffer_list_t buffers; // The buffer chain containing the message
- dx_buffer_list_t new_delivery_annotations; // The buffer chain containing the new delivery annotations (MOVE TO MSG_PVT)
- dx_field_location_t section_message_header; // The message header list
- dx_field_location_t section_delivery_annotation; // The delivery annotation map
- dx_field_location_t section_message_annotation; // The message annotation map
- dx_field_location_t section_message_properties; // The message properties list
- dx_field_location_t section_application_properties; // The application properties list
- dx_field_location_t section_body; // The message body: Data
- dx_field_location_t section_footer; // The footer
- dx_field_location_t field_user_id; // The string value of the user-id
- dx_field_location_t field_to; // The string value of the to field
- dx_field_location_t field_reply_to; // The string value of the reply_to field
- dx_field_location_t body; // The body of the message
- dx_buffer_t *parse_buffer;
- unsigned char *parse_cursor;
- dx_message_depth_t parse_depth;
- dx_parsed_field_t *parsed_delivery_annotations;
-} dx_message_content_t;
-
-typedef struct {
- DEQ_LINKS(dx_message_t); // Deque linkage that overlays the dx_message_t
- dx_message_content_t *content;
-} dx_message_pvt_t;
-
-ALLOC_DECLARE(dx_message_t);
-ALLOC_DECLARE(dx_message_content_t);
-
-#define MSG_CONTENT(m) (((dx_message_pvt_t*) m)->content)
-
-#endif
diff --git a/extras/dispatch/src/parse.c b/extras/dispatch/src/parse.c
deleted file mode 100644
index c5ecc4e498..0000000000
--- a/extras/dispatch/src/parse.c
+++ /dev/null
@@ -1,385 +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/dispatch/alloc.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/parse.h>
-#include <qpid/dispatch/amqp.h>
-
-DEQ_DECLARE(dx_parsed_field_t, dx_parsed_field_list_t);
-
-struct dx_parsed_field_t {
- DEQ_LINKS(dx_parsed_field_t);
- dx_parsed_field_t *parent;
- dx_parsed_field_list_t children;
- uint8_t tag;
- dx_field_iterator_t *raw_iter;
- const char *parse_error;
-};
-
-ALLOC_DECLARE(dx_parsed_field_t);
-ALLOC_DEFINE(dx_parsed_field_t);
-
-
-static char *get_type_info(dx_field_iterator_t *iter, uint8_t *tag, uint32_t *length, uint32_t *count, uint32_t *clen)
-{
- if (dx_field_iterator_end(iter))
- return "Insufficient Data to Determine Tag";
- *tag = dx_field_iterator_octet(iter);
- *count = 0;
- *length = 0;
- *clen = 0;
-
- switch (*tag & 0xF0) {
- case 0x40: *length = 0; break;
- case 0x50: *length = 1; break;
- case 0x60: *length = 2; break;
- case 0x70: *length = 4; break;
- case 0x80: *length = 8; break;
- case 0x90: *length = 16; break;
- case 0xB0:
- case 0xD0:
- case 0xF0:
- *length += ((unsigned int) dx_field_iterator_octet(iter)) << 24;
- *length += ((unsigned int) dx_field_iterator_octet(iter)) << 16;
- *length += ((unsigned int) dx_field_iterator_octet(iter)) << 8;
- // fall through to the next case
-
- case 0xA0:
- case 0xC0:
- case 0xE0:
- if (dx_field_iterator_end(iter))
- return "Insufficient Data to Determine Length";
- *length += (unsigned int) dx_field_iterator_octet(iter);
- break;
-
- default:
- return "Invalid Tag - No Length Information";
- }
-
- switch (*tag & 0xF0) {
- case 0xD0:
- case 0xF0:
- *count += ((unsigned int) dx_field_iterator_octet(iter)) << 24;
- *count += ((unsigned int) dx_field_iterator_octet(iter)) << 16;
- *count += ((unsigned int) dx_field_iterator_octet(iter)) << 8;
- *clen = 3;
- // fall through to the next case
-
- case 0xC0:
- case 0xE0:
- if (dx_field_iterator_end(iter))
- return "Insufficient Data to Determine Count";
- *count += (unsigned int) dx_field_iterator_octet(iter);
- *clen += 1;
- break;
- }
-
- if ((*tag == DX_AMQP_MAP8 || *tag == DX_AMQP_MAP32) && (*count & 1))
- return "Odd Number of Elements in a Map";
-
- if (*clen > *length)
- return "Insufficient Length to Determine Count";
-
- return 0;
-}
-
-
-static dx_parsed_field_t *dx_parse_internal(dx_field_iterator_t *iter, dx_parsed_field_t *p)
-{
- dx_parsed_field_t *field = new_dx_parsed_field_t();
- if (!field)
- return 0;
-
- DEQ_ITEM_INIT(field);
- DEQ_INIT(field->children);
- field->parent = p;
- field->raw_iter = 0;
-
- uint32_t length;
- uint32_t count;
- uint32_t length_of_count;
-
- field->parse_error = get_type_info(iter, &field->tag, &length, &count, &length_of_count);
-
- if (!field->parse_error) {
- field->raw_iter = dx_field_iterator_sub(iter, length);
- dx_field_iterator_advance(iter, length - length_of_count);
- for (uint32_t idx = 0; idx < count; idx++) {
- dx_parsed_field_t *child = dx_parse_internal(field->raw_iter, field);
- DEQ_INSERT_TAIL(field->children, child);
- if (!dx_parse_ok(child)) {
- field->parse_error = child->parse_error;
- break;
- }
- }
- }
-
- return field;
-}
-
-
-dx_parsed_field_t *dx_parse(dx_field_iterator_t *iter)
-{
- return dx_parse_internal(iter, 0);
-}
-
-
-void dx_parse_free(dx_parsed_field_t *field)
-{
- if (!field)
- return;
-
- assert(field->parent == 0);
- if (field->raw_iter)
- dx_field_iterator_free(field->raw_iter);
-
- dx_parsed_field_t *sub_field = DEQ_HEAD(field->children);
- while (sub_field) {
- dx_parsed_field_t *next = DEQ_NEXT(sub_field);
- DEQ_REMOVE_HEAD(field->children);
- sub_field->parent = 0;
- dx_parse_free(sub_field);
- sub_field = next;
- }
-
- free_dx_parsed_field_t(field);
-}
-
-
-int dx_parse_ok(dx_parsed_field_t *field)
-{
- return field->parse_error == 0;
-}
-
-
-const char *dx_parse_error(dx_parsed_field_t *field)
-{
- return field->parse_error;
-}
-
-
-uint8_t dx_parse_tag(dx_parsed_field_t *field)
-{
- return field->tag;
-}
-
-
-dx_field_iterator_t *dx_parse_raw(dx_parsed_field_t *field)
-{
- return field->raw_iter;
-}
-
-
-uint32_t dx_parse_as_uint(dx_parsed_field_t *field)
-{
- uint32_t result = 0;
-
- dx_field_iterator_reset(field->raw_iter);
-
- switch (field->tag) {
- case DX_AMQP_UINT:
- result |= ((uint32_t) dx_field_iterator_octet(field->raw_iter)) << 24;
- result |= ((uint32_t) dx_field_iterator_octet(field->raw_iter)) << 16;
-
- case DX_AMQP_USHORT:
- result |= ((uint32_t) dx_field_iterator_octet(field->raw_iter)) << 8;
- // Fall Through...
-
- case DX_AMQP_UBYTE:
- case DX_AMQP_SMALLUINT:
- case DX_AMQP_BOOLEAN:
- result |= (uint32_t) dx_field_iterator_octet(field->raw_iter);
- break;
-
- case DX_AMQP_TRUE:
- result = 1;
- break;
- }
-
- return result;
-}
-
-
-uint64_t dx_parse_as_ulong(dx_parsed_field_t *field)
-{
- uint64_t result = 0;
-
- dx_field_iterator_reset(field->raw_iter);
-
- switch (field->tag) {
- case DX_AMQP_ULONG:
- case DX_AMQP_TIMESTAMP:
- result |= ((uint64_t) dx_field_iterator_octet(field->raw_iter)) << 56;
- result |= ((uint64_t) dx_field_iterator_octet(field->raw_iter)) << 48;
- result |= ((uint64_t) dx_field_iterator_octet(field->raw_iter)) << 40;
- result |= ((uint64_t) dx_field_iterator_octet(field->raw_iter)) << 32;
- result |= ((uint64_t) dx_field_iterator_octet(field->raw_iter)) << 24;
- result |= ((uint64_t) dx_field_iterator_octet(field->raw_iter)) << 16;
- result |= ((uint64_t) dx_field_iterator_octet(field->raw_iter)) << 8;
- // Fall Through...
-
- case DX_AMQP_SMALLULONG:
- result |= (uint64_t) dx_field_iterator_octet(field->raw_iter);
- // Fall Through...
-
- case DX_AMQP_ULONG0:
- break;
- }
-
- return result;
-}
-
-
-int32_t dx_parse_as_int(dx_parsed_field_t *field)
-{
- int32_t result = 0;
-
- dx_field_iterator_reset(field->raw_iter);
-
- switch (field->tag) {
- case DX_AMQP_INT:
- result |= ((int32_t) dx_field_iterator_octet(field->raw_iter)) << 24;
- result |= ((int32_t) dx_field_iterator_octet(field->raw_iter)) << 16;
-
- case DX_AMQP_SHORT:
- result |= ((int32_t) dx_field_iterator_octet(field->raw_iter)) << 8;
- // Fall Through...
-
- case DX_AMQP_BYTE:
- case DX_AMQP_SMALLINT:
- case DX_AMQP_BOOLEAN:
- result |= (int32_t) dx_field_iterator_octet(field->raw_iter);
- break;
-
- case DX_AMQP_TRUE:
- result = 1;
- break;
- }
-
- return result;
-}
-
-
-int64_t dx_parse_as_long(dx_parsed_field_t *field)
-{
- int64_t result = 0;
-
- dx_field_iterator_reset(field->raw_iter);
-
- switch (field->tag) {
- case DX_AMQP_LONG:
- result |= ((int64_t) dx_field_iterator_octet(field->raw_iter)) << 56;
- result |= ((int64_t) dx_field_iterator_octet(field->raw_iter)) << 48;
- result |= ((int64_t) dx_field_iterator_octet(field->raw_iter)) << 40;
- result |= ((int64_t) dx_field_iterator_octet(field->raw_iter)) << 32;
- result |= ((int64_t) dx_field_iterator_octet(field->raw_iter)) << 24;
- result |= ((int64_t) dx_field_iterator_octet(field->raw_iter)) << 16;
- result |= ((int64_t) dx_field_iterator_octet(field->raw_iter)) << 8;
- // Fall Through...
-
- case DX_AMQP_SMALLLONG:
- result |= (uint64_t) dx_field_iterator_octet(field->raw_iter);
- break;
- }
-
- return result;
-}
-
-
-uint32_t dx_parse_sub_count(dx_parsed_field_t *field)
-{
- uint32_t count = DEQ_SIZE(field->children);
-
- if (field->tag == DX_AMQP_MAP8 || field->tag == DX_AMQP_MAP32)
- count = count >> 1;
-
- return count;
-}
-
-
-dx_parsed_field_t *dx_parse_sub_key(dx_parsed_field_t *field, uint32_t idx)
-{
- if (field->tag != DX_AMQP_MAP8 && field->tag != DX_AMQP_MAP32)
- return 0;
-
- idx = idx << 1;
- dx_parsed_field_t *key = DEQ_HEAD(field->children);
- while (idx && key) {
- idx--;
- key = DEQ_NEXT(key);
- }
-
- return key;
-}
-
-
-dx_parsed_field_t *dx_parse_sub_value(dx_parsed_field_t *field, uint32_t idx)
-{
- if (field->tag == DX_AMQP_MAP8 || field->tag == DX_AMQP_MAP32)
- idx = (idx << 1) + 1;
-
- dx_parsed_field_t *key = DEQ_HEAD(field->children);
- while (idx && key) {
- idx--;
- key = DEQ_NEXT(key);
- }
-
- return key;
-}
-
-
-int dx_parse_is_map(dx_parsed_field_t *field)
-{
- return field->tag == DX_AMQP_MAP8 || field->tag == DX_AMQP_MAP32;
-}
-
-
-int dx_parse_is_list(dx_parsed_field_t *field)
-{
- return field->tag == DX_AMQP_LIST8 || field->tag == DX_AMQP_LIST32;
-}
-
-
-int dx_parse_is_scalar(dx_parsed_field_t *field)
-{
- return DEQ_SIZE(field->children) == 0;
-}
-
-
-dx_parsed_field_t *dx_parse_value_by_key(dx_parsed_field_t *field, const char *key)
-{
- uint32_t count = dx_parse_sub_count(field);
-
- for (uint32_t idx = 0; idx < count; idx++) {
- dx_parsed_field_t *sub = dx_parse_sub_key(field, idx);
- if (!sub)
- return 0;
-
- dx_field_iterator_t *iter = dx_parse_raw(sub);
- if (!iter)
- return 0;
-
- if (dx_field_iterator_equal(iter, (const unsigned char*) key)) {
- return dx_parse_sub_value(field, idx);
- }
- }
-
- return 0;
-}
diff --git a/extras/dispatch/src/posix/threading.c b/extras/dispatch/src/posix/threading.c
deleted file mode 100644
index 1d7760ca88..0000000000
--- a/extras/dispatch/src/posix/threading.c
+++ /dev/null
@@ -1,125 +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/dispatch/threading.h>
-#include <qpid/dispatch/ctools.h>
-#include <stdio.h>
-#include <pthread.h>
-
-struct sys_mutex_t {
- pthread_mutex_t mutex;
- int acquired;
-};
-
-sys_mutex_t *sys_mutex(void)
-{
- sys_mutex_t *mutex = NEW(sys_mutex_t);
- pthread_mutex_init(&(mutex->mutex), 0);
- mutex->acquired = 0;
- return mutex;
-}
-
-
-void sys_mutex_free(sys_mutex_t *mutex)
-{
- assert(!mutex->acquired);
- pthread_mutex_destroy(&(mutex->mutex));
- free(mutex);
-}
-
-
-void sys_mutex_lock(sys_mutex_t *mutex)
-{
- pthread_mutex_lock(&(mutex->mutex));
- assert(!mutex->acquired);
- mutex->acquired++;
-}
-
-
-void sys_mutex_unlock(sys_mutex_t *mutex)
-{
- mutex->acquired--;
- assert(!mutex->acquired);
- pthread_mutex_unlock(&(mutex->mutex));
-}
-
-
-struct sys_cond_t {
- pthread_cond_t cond;
-};
-
-
-sys_cond_t *sys_cond(void)
-{
- sys_cond_t *cond = NEW(sys_cond_t);
- pthread_cond_init(&(cond->cond), 0);
- return cond;
-}
-
-
-void sys_cond_free(sys_cond_t *cond)
-{
- pthread_cond_destroy(&(cond->cond));
- free(cond);
-}
-
-
-void sys_cond_wait(sys_cond_t *cond, sys_mutex_t *held_mutex)
-{
- assert(held_mutex->acquired);
- held_mutex->acquired--;
- pthread_cond_wait(&(cond->cond), &(held_mutex->mutex));
- held_mutex->acquired++;
-}
-
-
-void sys_cond_signal(sys_cond_t *cond)
-{
- pthread_cond_signal(&(cond->cond));
-}
-
-
-void sys_cond_signal_all(sys_cond_t *cond)
-{
- pthread_cond_broadcast(&(cond->cond));
-}
-
-
-struct sys_thread_t {
- pthread_t thread;
-};
-
-sys_thread_t *sys_thread(void *(*run_function) (void *), void *arg)
-{
- sys_thread_t *thread = NEW(sys_thread_t);
- pthread_create(&(thread->thread), 0, run_function, arg);
- return thread;
-}
-
-
-void sys_thread_free(sys_thread_t *thread)
-{
- free(thread);
-}
-
-
-void sys_thread_join(sys_thread_t *thread)
-{
- pthread_join(thread->thread, 0);
-}
diff --git a/extras/dispatch/src/python_embedded.c b/extras/dispatch/src/python_embedded.c
deleted file mode 100644
index a6e35018c6..0000000000
--- a/extras/dispatch/src/python_embedded.c
+++ /dev/null
@@ -1,678 +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/dispatch/python_embedded.h>
-#include <qpid/dispatch/threading.h>
-#include <qpid/dispatch/log.h>
-#include <qpid/dispatch/amqp.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/router.h>
-
-
-//===============================================================================
-// Control Functions
-//===============================================================================
-
-static dx_dispatch_t *dispatch = 0;
-static uint32_t ref_count = 0;
-static sys_mutex_t *lock = 0;
-static char *log_module = "PYTHON";
-static PyObject *dispatch_module = 0;
-
-static void dx_python_setup();
-
-
-void dx_python_initialize(dx_dispatch_t *dx)
-{
- dispatch = dx;
- lock = sys_mutex();
-}
-
-
-void dx_python_finalize()
-{
- assert(ref_count == 0);
- sys_mutex_free(lock);
-}
-
-
-void dx_python_start()
-{
- sys_mutex_lock(lock);
- if (ref_count == 0) {
- Py_Initialize();
- dx_python_setup();
- dx_log(log_module, LOG_TRACE, "Embedded Python Interpreter Initialized");
- }
- ref_count++;
- sys_mutex_unlock(lock);
-}
-
-
-void dx_python_stop()
-{
- sys_mutex_lock(lock);
- ref_count--;
- if (ref_count == 0) {
- Py_DECREF(dispatch_module);
- dispatch_module = 0;
- Py_Finalize();
- dx_log(log_module, LOG_TRACE, "Embedded Python Interpreter Shut Down");
- }
- sys_mutex_unlock(lock);
-}
-
-
-PyObject *dx_python_module()
-{
- assert(dispatch_module);
- return dispatch_module;
-}
-
-
-//===============================================================================
-// Data Conversion Functions
-//===============================================================================
-
-static PyObject *parsed_to_py_string(dx_parsed_field_t *field)
-{
- switch (dx_parse_tag(field)) {
- case DX_AMQP_VBIN8:
- case DX_AMQP_VBIN32:
- case DX_AMQP_STR8_UTF8:
- case DX_AMQP_STR32_UTF8:
- case DX_AMQP_SYM8:
- case DX_AMQP_SYM32:
- break;
- default:
- return Py_None;
- }
-
-#define SHORT_BUF 1024
- uint8_t short_buf[SHORT_BUF];
- PyObject *result;
- dx_field_iterator_t *raw = dx_parse_raw(field);
- dx_field_iterator_reset(raw);
- uint32_t length = dx_field_iterator_remaining(raw);
- uint8_t *buffer = short_buf;
- uint8_t *ptr;
- int alloc = 0;
-
- if (length > SHORT_BUF) {
- alloc = 1;
- buffer = (uint8_t*) malloc(length);
- }
-
- ptr = buffer;
- while (!dx_field_iterator_end(raw))
- *(ptr++) = dx_field_iterator_octet(raw);
- result = PyString_FromStringAndSize((char*) buffer, ptr - buffer);
- if (alloc)
- free(buffer);
-
- return result;
-}
-
-
-void dx_py_to_composed(PyObject *value, dx_composed_field_t *field)
-{
- if (PyBool_Check(value))
- dx_compose_insert_bool(field, PyInt_AS_LONG(value) ? 1 : 0);
-
- //else if (PyFloat_Check(value))
- // dx_compose_insert_double(field, PyFloat_AS_DOUBLE(value));
-
- else if (PyInt_Check(value))
- dx_compose_insert_long(field, (int64_t) PyInt_AS_LONG(value));
-
- else if (PyLong_Check(value))
- dx_compose_insert_long(field, (int64_t) PyLong_AsLongLong(value));
-
- else if (PyString_Check(value))
- dx_compose_insert_string(field, PyString_AS_STRING(value));
-
- else if (PyDict_Check(value)) {
- Py_ssize_t iter = 0;
- PyObject *key;
- PyObject *val;
- dx_compose_start_map(field);
- while (PyDict_Next(value, &iter, &key, &val)) {
- dx_py_to_composed(key, field);
- dx_py_to_composed(val, field);
- }
- dx_compose_end_map(field);
- }
-
- else if (PyList_Check(value)) {
- Py_ssize_t count = PyList_Size(value);
- dx_compose_start_list(field);
- for (Py_ssize_t idx = 0; idx < count; idx++) {
- PyObject *item = PyList_GetItem(value, idx);
- dx_py_to_composed(item, field);
- }
- dx_compose_end_list(field);
- }
-
- else if (PyTuple_Check(value)) {
- Py_ssize_t count = PyTuple_Size(value);
- dx_compose_start_list(field);
- for (Py_ssize_t idx = 0; idx < count; idx++) {
- PyObject *item = PyTuple_GetItem(value, idx);
- dx_py_to_composed(item, field);
- }
- dx_compose_end_list(field);
- }
-}
-
-
-PyObject *dx_field_to_py(dx_parsed_field_t *field)
-{
- PyObject *result = Py_None;
- uint8_t tag = dx_parse_tag(field);
-
- switch (tag) {
- case DX_AMQP_NULL:
- result = Py_None;
- break;
-
- case DX_AMQP_BOOLEAN:
- case DX_AMQP_TRUE:
- case DX_AMQP_FALSE:
- result = dx_parse_as_uint(field) ? Py_True : Py_False;
- break;
-
- case DX_AMQP_UBYTE:
- case DX_AMQP_USHORT:
- case DX_AMQP_UINT:
- case DX_AMQP_SMALLUINT:
- case DX_AMQP_UINT0:
- result = PyInt_FromLong((long) dx_parse_as_uint(field));
- break;
-
- case DX_AMQP_ULONG:
- case DX_AMQP_SMALLULONG:
- case DX_AMQP_ULONG0:
- case DX_AMQP_TIMESTAMP:
- result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) dx_parse_as_ulong(field));
- break;
-
- case DX_AMQP_BYTE:
- case DX_AMQP_SHORT:
- case DX_AMQP_INT:
- case DX_AMQP_SMALLINT:
- result = PyInt_FromLong((long) dx_parse_as_int(field));
- break;
-
- case DX_AMQP_LONG:
- case DX_AMQP_SMALLLONG:
- result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) dx_parse_as_long(field));
- break;
-
- case DX_AMQP_FLOAT:
- case DX_AMQP_DOUBLE:
- case DX_AMQP_DECIMAL32:
- case DX_AMQP_DECIMAL64:
- case DX_AMQP_DECIMAL128:
- case DX_AMQP_UTF32:
- case DX_AMQP_UUID:
- break;
-
- case DX_AMQP_VBIN8:
- case DX_AMQP_VBIN32:
- case DX_AMQP_STR8_UTF8:
- case DX_AMQP_STR32_UTF8:
- case DX_AMQP_SYM8:
- case DX_AMQP_SYM32:
- result = parsed_to_py_string(field);
- break;
-
- case DX_AMQP_LIST0:
- case DX_AMQP_LIST8:
- case DX_AMQP_LIST32: {
- uint32_t count = dx_parse_sub_count(field);
- result = PyList_New(count);
- for (uint32_t idx = 0; idx < count; idx++) {
- dx_parsed_field_t *sub = dx_parse_sub_value(field, idx);
- PyObject *pysub = dx_field_to_py(sub);
- if (pysub == 0)
- return 0;
- PyList_SetItem(result, idx, pysub);
- }
- break;
- }
- case DX_AMQP_MAP8:
- case DX_AMQP_MAP32: {
- uint32_t count = dx_parse_sub_count(field);
- result = PyDict_New();
- for (uint32_t idx = 0; idx < count; idx++) {
- dx_parsed_field_t *key = dx_parse_sub_key(field, idx);
- dx_parsed_field_t *val = dx_parse_sub_value(field, idx);
- PyObject *pykey = parsed_to_py_string(key);
- PyObject *pyval = dx_field_to_py(val);
- if (pyval == 0)
- return 0;
- PyDict_SetItem(result, pykey, pyval);
- Py_DECREF(pykey);
- Py_DECREF(pyval);
- }
- break;
- }
- case DX_AMQP_ARRAY8:
- case DX_AMQP_ARRAY32:
- break;
- }
-
- return result;
-}
-
-
-//===============================================================================
-// Logging Object
-//===============================================================================
-
-typedef struct {
- PyObject_HEAD
- PyObject *module_name;
-} LogAdapter;
-
-
-static int LogAdapter_init(LogAdapter *self, PyObject *args, PyObject *kwds)
-{
- const char *text;
- if (!PyArg_ParseTuple(args, "s", &text))
- return -1;
-
- self->module_name = PyString_FromString(text);
- return 0;
-}
-
-
-static void LogAdapter_dealloc(LogAdapter* self)
-{
- Py_XDECREF(self->module_name);
- self->ob_type->tp_free((PyObject*)self);
-}
-
-
-static PyObject* dx_python_log(PyObject *self, PyObject *args)
-{
- int level;
- const char* text;
-
- if (!PyArg_ParseTuple(args, "is", &level, &text))
- return 0;
-
- LogAdapter *self_ptr = (LogAdapter*) self;
- char *logmod = PyString_AS_STRING(self_ptr->module_name);
-
- dx_log(logmod, level, text);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyMethodDef LogAdapter_methods[] = {
- {"log", dx_python_log, METH_VARARGS, "Emit a Log Line"},
- {0, 0, 0, 0}
-};
-
-static PyMethodDef empty_methods[] = {
- {0, 0, 0, 0}
-};
-
-static PyTypeObject LogAdapterType = {
- PyObject_HEAD_INIT(0)
- 0, /* ob_size*/
- "dispatch.LogAdapter", /* tp_name*/
- sizeof(LogAdapter), /* tp_basicsize*/
- 0, /* tp_itemsize*/
- (destructor)LogAdapter_dealloc, /* tp_dealloc*/
- 0, /* tp_print*/
- 0, /* tp_getattr*/
- 0, /* tp_setattr*/
- 0, /* tp_compare*/
- 0, /* tp_repr*/
- 0, /* tp_as_number*/
- 0, /* tp_as_sequence*/
- 0, /* tp_as_mapping*/
- 0, /* tp_hash */
- 0, /* tp_call*/
- 0, /* tp_str*/
- 0, /* tp_getattro*/
- 0, /* tp_setattro*/
- 0, /* tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /* tp_flags*/
- "Dispatch Log Adapter", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- LogAdapter_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)LogAdapter_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0 /* tp_version_tag */
-};
-
-
-//===============================================================================
-// Message IO Object
-//===============================================================================
-
-typedef struct {
- PyObject_HEAD
- PyObject *handler;
- PyObject *handler_rx_call;
- dx_dispatch_t *dx;
- Py_ssize_t addr_count;
- dx_address_t **addrs;
-} IoAdapter;
-
-
-static void dx_io_rx_handler(void *context, dx_message_t *msg, int link_id)
-{
- IoAdapter *self = (IoAdapter*) context;
-
- //
- // Parse the message through the body and exit if the message is not well formed.
- //
- if (!dx_message_check(msg, DX_DEPTH_BODY))
- return;
-
- //
- // Get an iterator for the application-properties. Exit if the message has none.
- //
- dx_field_iterator_t *ap = dx_message_field_iterator(msg, DX_FIELD_APPLICATION_PROPERTIES);
- if (ap == 0)
- return;
-
- //
- // Try to get a map-view of the application-properties.
- //
- dx_parsed_field_t *ap_map = dx_parse(ap);
- if (ap_map == 0 || !dx_parse_ok(ap_map) || !dx_parse_is_map(ap_map)) {
- dx_field_iterator_free(ap);
- dx_parse_free(ap_map);
- return;
- }
-
- //
- // Get an iterator for the body. Exit if the message has none.
- //
- dx_field_iterator_t *body = dx_message_field_iterator(msg, DX_FIELD_BODY);
- if (body == 0) {
- dx_field_iterator_free(ap);
- dx_parse_free(ap_map);
- return;
- }
-
- //
- // Try to get a map-view of the body.
- //
- dx_parsed_field_t *body_map = dx_parse(body);
- if (body_map == 0 || !dx_parse_ok(body_map) || !dx_parse_is_map(body_map)) {
- dx_field_iterator_free(ap);
- dx_field_iterator_free(body);
- dx_parse_free(ap_map);
- dx_parse_free(body_map);
- return;
- }
-
- sys_mutex_lock(lock);
- PyObject *pAP = dx_field_to_py(ap_map);
- PyObject *pBody = dx_field_to_py(body_map);
-
- PyObject *pArgs = PyTuple_New(3);
- PyTuple_SetItem(pArgs, 0, pAP);
- PyTuple_SetItem(pArgs, 1, pBody);
- PyTuple_SetItem(pArgs, 2, PyInt_FromLong((long) link_id));
-
- PyObject *pValue = PyObject_CallObject(self->handler_rx_call, pArgs);
- Py_DECREF(pArgs);
- if (pValue) {
- Py_DECREF(pValue);
- }
- sys_mutex_unlock(lock);
-
- dx_field_iterator_free(ap);
- dx_field_iterator_free(body);
- dx_parse_free(ap_map);
- dx_parse_free(body_map);
-}
-
-
-static int IoAdapter_init(IoAdapter *self, PyObject *args, PyObject *kwds)
-{
- PyObject *addrs;
- if (!PyArg_ParseTuple(args, "OO", &self->handler, &addrs))
- return -1;
-
- self->handler_rx_call = PyObject_GetAttrString(self->handler, "receive");
- if (!self->handler_rx_call || !PyCallable_Check(self->handler_rx_call))
- return -1;
-
- if (!PyTuple_Check(addrs))
- return -1;
-
- Py_INCREF(self->handler);
- Py_INCREF(self->handler_rx_call);
- self->dx = dispatch;
- self->addr_count = PyTuple_Size(addrs);
- self->addrs = NEW_PTR_ARRAY(dx_address_t, self->addr_count);
- for (Py_ssize_t idx = 0; idx < self->addr_count; idx++)
- self->addrs[idx] = dx_router_register_address(self->dx,
- PyString_AS_STRING(PyTuple_GetItem(addrs, idx)),
- dx_io_rx_handler, self);
- return 0;
-}
-
-
-static void IoAdapter_dealloc(IoAdapter* self)
-{
- for (Py_ssize_t idx = 0; idx < self->addr_count; idx++)
- dx_router_unregister_address(self->addrs[idx]);
- free(self->addrs);
- Py_DECREF(self->handler);
- Py_DECREF(self->handler_rx_call);
- self->ob_type->tp_free((PyObject*)self);
-}
-
-
-static PyObject* dx_python_send(PyObject *self, PyObject *args)
-{
- IoAdapter *ioa = (IoAdapter*) self;
- dx_composed_field_t *field = 0;
- const char *address;
- PyObject *app_properties;
- PyObject *body;
-
- if (!PyArg_ParseTuple(args, "sOO", &address, &app_properties, &body))
- return 0;
-
- field = dx_compose(DX_PERFORMATIVE_DELIVERY_ANNOTATIONS, field);
- dx_compose_start_map(field);
-
- dx_compose_insert_string(field, DX_DA_INGRESS);
- dx_compose_insert_string(field, dx_router_id(ioa->dx));
-
- dx_compose_insert_string(field, DX_DA_TRACE);
- dx_compose_start_list(field);
- dx_compose_insert_string(field, dx_router_id(ioa->dx));
- dx_compose_end_list(field);
-
- dx_compose_end_map(field);
-
- field = dx_compose(DX_PERFORMATIVE_PROPERTIES, field);
- dx_compose_start_list(field);
- dx_compose_insert_null(field); // message-id
- dx_compose_insert_null(field); // user-id
- dx_compose_insert_string(field, address); // to
- dx_compose_end_list(field);
-
- field = dx_compose(DX_PERFORMATIVE_APPLICATION_PROPERTIES, field);
- dx_py_to_composed(app_properties, field);
-
- field = dx_compose(DX_PERFORMATIVE_BODY_AMQP_VALUE, field);
- dx_py_to_composed(body, field);
-
- dx_message_t *msg = dx_message();
- dx_message_compose_2(msg, field);
- dx_router_send2(ioa->dx, address, msg);
- dx_message_free(msg);
- dx_compose_free(field);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyMethodDef IoAdapter_methods[] = {
- {"send", dx_python_send, METH_VARARGS, "Send a Message"},
- {0, 0, 0, 0}
-};
-
-
-static PyTypeObject IoAdapterType = {
- PyObject_HEAD_INIT(0)
- 0, /* ob_size*/
- "dispatch.IoAdapter", /* tp_name*/
- sizeof(IoAdapter), /* tp_basicsize*/
- 0, /* tp_itemsize*/
- (destructor)IoAdapter_dealloc, /* tp_dealloc*/
- 0, /* tp_print*/
- 0, /* tp_getattr*/
- 0, /* tp_setattr*/
- 0, /* tp_compare*/
- 0, /* tp_repr*/
- 0, /* tp_as_number*/
- 0, /* tp_as_sequence*/
- 0, /* tp_as_mapping*/
- 0, /* tp_hash */
- 0, /* tp_call*/
- 0, /* tp_str*/
- 0, /* tp_getattro*/
- 0, /* tp_setattro*/
- 0, /* tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /* tp_flags*/
- "Dispatch IO Adapter", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- IoAdapter_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)IoAdapter_init, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0 /* tp_version_tag */
-};
-
-
-//===============================================================================
-// Initialization of Modules and Types
-//===============================================================================
-
-static void dx_register_log_constant(PyObject *module, const char *name, uint32_t value)
-{
- PyObject *const_object = PyInt_FromLong((long) value);
- Py_INCREF(const_object);
- PyModule_AddObject(module, name, const_object);
-}
-
-
-static void dx_python_setup()
-{
- LogAdapterType.tp_new = PyType_GenericNew;
- IoAdapterType.tp_new = PyType_GenericNew;
- if ((PyType_Ready(&LogAdapterType) < 0) || (PyType_Ready(&IoAdapterType) < 0)) {
- PyErr_Print();
- dx_log(log_module, LOG_ERROR, "Unable to initialize Adapters");
- assert(0);
- } else {
- PyObject *m = Py_InitModule3("dispatch", empty_methods, "Dispatch Adapter Module");
-
- //
- // Add LogAdapter
- //
- PyTypeObject *laType = &LogAdapterType;
- Py_INCREF(laType);
- PyModule_AddObject(m, "LogAdapter", (PyObject*) &LogAdapterType);
-
- dx_register_log_constant(m, "LOG_TRACE", LOG_TRACE);
- dx_register_log_constant(m, "LOG_DEBUG", LOG_DEBUG);
- dx_register_log_constant(m, "LOG_INFO", LOG_INFO);
- dx_register_log_constant(m, "LOG_NOTICE", LOG_NOTICE);
- dx_register_log_constant(m, "LOG_WARNING", LOG_WARNING);
- dx_register_log_constant(m, "LOG_ERROR", LOG_ERROR);
- dx_register_log_constant(m, "LOG_CRITICAL", LOG_CRITICAL);
-
- //
- PyTypeObject *ioaType = &IoAdapterType;
- Py_INCREF(ioaType);
- PyModule_AddObject(m, "IoAdapter", (PyObject*) &IoAdapterType);
-
- Py_INCREF(m);
- dispatch_module = m;
- }
-}
-
-void dx_python_lock()
-{
- sys_mutex_lock(lock);
-}
-
-void dx_python_unlock()
-{
- sys_mutex_unlock(lock);
-}
-
diff --git a/extras/dispatch/src/router_agent.c b/extras/dispatch/src/router_agent.c
deleted file mode 100644
index 4a70dc4ede..0000000000
--- a/extras/dispatch/src/router_agent.c
+++ /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/dispatch/python_embedded.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <qpid/dispatch.h>
-#include <qpid/dispatch/agent.h>
-#include "dispatch_private.h"
-#include "router_private.h"
-
-//static char *module = "router.agent";
-
-#define DX_ROUTER_CLASS_ROUTER 1
-#define DX_ROUTER_CLASS_LINK 2
-#define DX_ROUTER_CLASS_NODE 3
-#define DX_ROUTER_CLASS_ADDRESS 4
-
-typedef struct dx_router_class_t {
- dx_router_t *router;
- int class_id;
-} dx_router_class_t;
-
-
-static void dx_router_schema_handler(void *context, void *correlator)
-{
-}
-
-
-static const char *dx_router_addr_text(dx_address_t *addr)
-{
- if (addr) {
- const unsigned char *text = dx_hash_key_by_handle(addr->hash_handle);
- if (text)
- return (const char*) text;
- }
- return 0;
-}
-
-
-static void dx_router_query_router(dx_router_t *router, void *cor)
-{
- dx_agent_value_string(cor, "area", router->router_area);
- dx_agent_value_string(cor, "router_id", router->router_id);
-
- sys_mutex_lock(router->lock);
- dx_agent_value_uint(cor, "addr_count", DEQ_SIZE(router->addrs));
- dx_agent_value_uint(cor, "link_count", DEQ_SIZE(router->links));
- dx_agent_value_uint(cor, "node_count", DEQ_SIZE(router->routers));
- sys_mutex_unlock(router->lock);
-
- dx_agent_value_complete(cor, 0);
-}
-
-
-static void dx_router_query_link(dx_router_t *router, void *cor)
-{
- sys_mutex_lock(router->lock);
- dx_router_link_t *link = DEQ_HEAD(router->links);
- const char *link_type = "?";
- const char *link_dir;
-
- while (link) {
- dx_agent_value_uint(cor, "index", link->mask_bit);
- switch (link->link_type) {
- case DX_LINK_ENDPOINT: link_type = "endpoint"; break;
- case DX_LINK_ROUTER: link_type = "inter-router"; break;
- case DX_LINK_AREA: link_type = "inter-area"; break;
- }
- dx_agent_value_string(cor, "link-type", link_type);
-
- if (link->link_direction == DX_INCOMING)
- link_dir = "in";
- else
- link_dir = "out";
- dx_agent_value_string(cor, "link-dir", link_dir);
-
- const char *text = dx_router_addr_text(link->owning_addr);
- if (text)
- dx_agent_value_string(cor, "owning-addr", text);
- else
- dx_agent_value_null(cor, "owning-addr");
-
- link = DEQ_NEXT(link);
- dx_agent_value_complete(cor, link != 0);
- }
- sys_mutex_unlock(router->lock);
-}
-
-
-static void dx_router_query_node(dx_router_t *router, void *cor)
-{
- sys_mutex_lock(router->lock);
- dx_router_node_t *node = DEQ_HEAD(router->routers);
- while (node) {
- dx_agent_value_uint(cor, "index", node->mask_bit);
- dx_agent_value_string(cor, "addr", dx_router_addr_text(node->owning_addr));
- if (node->next_hop)
- dx_agent_value_uint(cor, "next-hop", node->next_hop->mask_bit);
- else
- dx_agent_value_null(cor, "next-hop");
- if (node->peer_link)
- dx_agent_value_uint(cor, "router-link", node->peer_link->mask_bit);
- else
- dx_agent_value_null(cor, "router-link");
- node = DEQ_NEXT(node);
- dx_agent_value_complete(cor, node != 0);
- }
- sys_mutex_unlock(router->lock);
-}
-
-
-static void dx_router_query_address(dx_router_t *router, void *cor)
-{
- sys_mutex_lock(router->lock);
- dx_address_t *addr = DEQ_HEAD(router->addrs);
- while (addr) {
- dx_agent_value_string(cor, "addr", dx_router_addr_text(addr));
- dx_agent_value_boolean(cor, "in-process", addr->handler != 0);
- dx_agent_value_uint(cor, "subscriber-count", DEQ_SIZE(addr->rlinks));
- dx_agent_value_uint(cor, "remote-count", DEQ_SIZE(addr->rnodes));
- dx_agent_value_uint(cor, "deliveries-ingress", addr->deliveries_ingress);
- dx_agent_value_uint(cor, "deliveries-egress", addr->deliveries_egress);
- dx_agent_value_uint(cor, "deliveries-transit", addr->deliveries_transit);
- dx_agent_value_uint(cor, "deliveries-to-container", addr->deliveries_to_container);
- dx_agent_value_uint(cor, "deliveries-from-container", addr->deliveries_from_container);
- addr = DEQ_NEXT(addr);
- dx_agent_value_complete(cor, addr != 0);
- }
- sys_mutex_unlock(router->lock);
-}
-
-
-static void dx_router_query_handler(void* context, const char *id, void *correlator)
-{
- dx_router_class_t *cls = (dx_router_class_t*) context;
- switch (cls->class_id) {
- case DX_ROUTER_CLASS_ROUTER: dx_router_query_router(cls->router, correlator); break;
- case DX_ROUTER_CLASS_LINK: dx_router_query_link(cls->router, correlator); break;
- case DX_ROUTER_CLASS_NODE: dx_router_query_node(cls->router, correlator); break;
- case DX_ROUTER_CLASS_ADDRESS: dx_router_query_address(cls->router, correlator); break;
- }
-}
-
-
-static dx_agent_class_t *dx_router_setup_class(dx_router_t *router, const char *fqname, int id)
-{
- dx_router_class_t *cls = NEW(dx_router_class_t);
- cls->router = router;
- cls->class_id = id;
-
- return dx_agent_register_class(router->dx, fqname, cls,
- dx_router_schema_handler,
- dx_router_query_handler);
-}
-
-
-void dx_router_agent_setup(dx_router_t *router)
-{
- router->class_router =
- dx_router_setup_class(router, "org.apache.qpid.dispatch.router", DX_ROUTER_CLASS_ROUTER);
- router->class_link =
- dx_router_setup_class(router, "org.apache.qpid.dispatch.router.link", DX_ROUTER_CLASS_LINK);
- router->class_node =
- dx_router_setup_class(router, "org.apache.qpid.dispatch.router.node", DX_ROUTER_CLASS_NODE);
- router->class_address =
- dx_router_setup_class(router, "org.apache.qpid.dispatch.router.address", DX_ROUTER_CLASS_ADDRESS);
-}
-
-
-void dx_router_build_node_list(dx_dispatch_t *dx, dx_composed_field_t *field)
-{
- dx_router_t *router = dx->router;
- char temp[1000]; // FIXME
-
- sys_mutex_lock(router->lock);
- dx_router_node_t *rnode = DEQ_HEAD(router->routers);
- while (rnode) {
- strcpy(temp, "amqp:/_topo/");
- strcat(temp, router->router_area);
- strcat(temp, "/");
- const unsigned char* addr = dx_hash_key_by_handle(rnode->owning_addr->hash_handle);
- strcat(temp, &((char*) addr)[1]);
- strcat(temp, "/$management");
- dx_compose_insert_string(field, temp);
- rnode = DEQ_NEXT(rnode);
- }
- sys_mutex_unlock(router->lock);
-}
-
diff --git a/extras/dispatch/src/router_node.c b/extras/dispatch/src/router_node.c
deleted file mode 100644
index a810462f1b..0000000000
--- a/extras/dispatch/src/router_node.c
+++ /dev/null
@@ -1,1323 +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/dispatch/python_embedded.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <qpid/dispatch.h>
-#include "dispatch_private.h"
-#include "router_private.h"
-
-static char *module = "ROUTER";
-
-static char *router_role = "inter-router";
-static char *local_prefix = "_local/";
-static char *topo_prefix = "_topo/";
-static char *direct_prefix;
-static char *node_id;
-
-/**
- * Address Types and Processing:
- *
- * Address Hash Key onReceive
- * ===================================================================
- * _local/<local> L<local> handler
- * _topo/<area>/<router>/<local> A<area> forward
- * _topo/<my-area>/<router>/<local> R<router> forward
- * _topo/<my-area>/<my-router>/<local> L<local> handler
- * _topo/<area>/all/<local> A<area> forward
- * _topo/<my-area>/all/<local> L<local> forward handler
- * _topo/all/all/<local> L<local> forward handler
- * <mobile> M<mobile> forward handler
- */
-
-ALLOC_DEFINE(dx_routed_event_t);
-ALLOC_DEFINE(dx_router_link_t);
-ALLOC_DEFINE(dx_router_node_t);
-ALLOC_DEFINE(dx_router_ref_t);
-ALLOC_DEFINE(dx_router_link_ref_t);
-ALLOC_DEFINE(dx_address_t);
-ALLOC_DEFINE(dx_router_conn_t);
-
-
-void dx_router_add_link_ref_LH(dx_router_link_ref_list_t *ref_list, dx_router_link_t *link)
-{
- dx_router_link_ref_t *ref = new_dx_router_link_ref_t();
- DEQ_ITEM_INIT(ref);
- ref->link = link;
- link->ref = ref;
- DEQ_INSERT_TAIL(*ref_list, ref);
-}
-
-
-void dx_router_del_link_ref_LH(dx_router_link_ref_list_t *ref_list, dx_router_link_t *link)
-{
- if (link->ref) {
- DEQ_REMOVE(*ref_list, link->ref);
- free_dx_router_link_ref_t(link->ref);
- link->ref = 0;
- }
-}
-
-
-void dx_router_add_node_ref_LH(dx_router_ref_list_t *ref_list, dx_router_node_t *rnode)
-{
- dx_router_ref_t *ref = new_dx_router_ref_t();
- DEQ_ITEM_INIT(ref);
- ref->router = rnode;
- rnode->ref_count++;
- DEQ_INSERT_TAIL(*ref_list, ref);
-}
-
-
-void dx_router_del_node_ref_LH(dx_router_ref_list_t *ref_list, dx_router_node_t *rnode)
-{
- dx_router_ref_t *ref = DEQ_HEAD(*ref_list);
- while (ref) {
- if (ref->router == rnode) {
- DEQ_REMOVE(*ref_list, ref);
- free_dx_router_ref_t(ref);
- rnode->ref_count--;
- break;
- }
- ref = DEQ_NEXT(ref);
- }
-}
-
-
-/**
- * Check an address to see if it no longer has any associated destinations.
- * Depending on its policy, the address may be eligible for being closed out
- * (i.e. Logging its terminal statistics and freeing its resources).
- */
-void dx_router_check_addr(dx_router_t *router, dx_address_t *addr, int was_local)
-{
- if (addr == 0)
- return;
-
- unsigned char *key = 0;
- int to_delete = 0;
- int no_more_locals = 0;
-
- sys_mutex_lock(router->lock);
-
- //
- // If the address has no handlers or destinations, it should be deleted.
- //
- if (addr->handler == 0 && DEQ_SIZE(addr->rlinks) == 0 && DEQ_SIZE(addr->rnodes) == 0)
- to_delete = 1;
-
- //
- // If we have just removed a local linkage and it was the last local linkage,
- // we need to notify the router module that there is no longer a local
- // presence of this address.
- //
- if (was_local && DEQ_SIZE(addr->rlinks) == 0)
- no_more_locals = 1;
-
- if (to_delete) {
- //
- // Delete the address but grab the hash key so we can use it outside the
- // critical section.
- //
- dx_hash_remove_by_handle2(router->addr_hash, addr->hash_handle, &key);
- DEQ_REMOVE(router->addrs, addr);
- dx_hash_handle_free(addr->hash_handle);
- free_dx_address_t(addr);
- }
-
- //
- // If we're not deleting but there are no more locals, get a copy of the hash key.
- //
- if (!to_delete && no_more_locals) {
- const unsigned char *key_const = dx_hash_key_by_handle(addr->hash_handle);
- key = (unsigned char*) malloc(strlen((const char*) key_const) + 1);
- strcpy((char*) key, (const char*) key_const);
- }
-
- sys_mutex_unlock(router->lock);
-
- //
- // If the address is mobile-class and it was just removed from a local link,
- // tell the router module that it is no longer attached locally.
- //
- if (no_more_locals && key && key[0] == 'M')
- dx_router_mobile_removed(router, (const char*) key);
-
- //
- // Free the key that was not freed by the hash table.
- //
- if (key)
- free(key);
-}
-
-
-/**
- * Determine whether a connection is configured in the inter-router role.
- */
-static int dx_router_connection_is_inter_router(const dx_connection_t *conn)
-{
- if (!conn)
- return 0;
-
- const dx_server_config_t *cf = dx_connection_config(conn);
- if (cf && strcmp(cf->role, router_role) == 0)
- return 1;
-
- return 0;
-}
-
-
-/**
- * Determine whether a terminus has router capability
- */
-static int dx_router_terminus_is_router(pn_terminus_t *term)
-{
- pn_data_t *cap = pn_terminus_capabilities(term);
-
- pn_data_rewind(cap);
- pn_data_next(cap);
- if (cap && pn_data_type(cap) == PN_SYMBOL) {
- pn_bytes_t sym = pn_data_get_symbol(cap);
- if (sym.size == strlen(DX_CAPABILITY_ROUTER) &&
- strcmp(sym.start, DX_CAPABILITY_ROUTER) == 0)
- return 1;
- }
-
- return 0;
-}
-
-
-static void dx_router_generate_temp_addr(dx_router_t *router, char *buffer, size_t length)
-{
- static const char *table = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+_";
- char discriminator[11];
- long int rnd = random();
- int idx;
-
- for (idx = 0; idx < 6; idx++)
- discriminator[idx] = table[(rnd >> (idx * 6)) & 63];
- discriminator[idx] = '\0';
-
- snprintf(buffer, length, "amqp:/%s%s/%s/temp.%s", topo_prefix, router->router_area, router->router_id, discriminator);
-}
-
-
-static int dx_router_find_mask_bit_LH(dx_router_t *router, dx_link_t *link)
-{
- dx_router_conn_t *shared = (dx_router_conn_t*) dx_link_get_conn_context(link);
- if (shared)
- return shared->mask_bit;
-
- int mask_bit;
- if (dx_bitmask_first_set(router->neighbor_free_mask, &mask_bit)) {
- dx_bitmask_clear_bit(router->neighbor_free_mask, mask_bit);
- } else {
- dx_log(module, LOG_CRITICAL, "Exceeded maximum inter-router link count");
- return -1;
- }
-
- shared = new_dx_router_conn_t();
- shared->mask_bit = mask_bit;
- dx_link_set_conn_context(link, shared);
- return mask_bit;
-}
-
-
-/**
- * Outgoing Link Writable Handler
- */
-static int router_writable_link_handler(void* context, dx_link_t *link)
-{
- dx_router_t *router = (dx_router_t*) context;
- dx_delivery_t *delivery;
- dx_router_link_t *rlink = (dx_router_link_t*) dx_link_get_context(link);
- pn_link_t *pn_link = dx_link_pn(link);
- uint64_t tag;
- int link_credit = pn_link_credit(pn_link);
- dx_routed_event_list_t to_send;
- dx_routed_event_list_t events;
- dx_routed_event_t *re;
- size_t offer;
- int event_count = 0;
-
- DEQ_INIT(to_send);
- DEQ_INIT(events);
-
- sys_mutex_lock(router->lock);
-
- //
- // Pull the non-delivery events into a local list so they can be processed without
- // the lock being held.
- //
- re = DEQ_HEAD(rlink->event_fifo);
- while (re) {
- DEQ_REMOVE_HEAD(rlink->event_fifo);
- DEQ_INSERT_TAIL(events, re);
- re = DEQ_HEAD(rlink->event_fifo);
- }
-
- //
- // Under lock, move available deliveries from the msg_fifo to the local to_send
- // list. Don't move more than we have credit to send.
- //
- if (link_credit > 0) {
- tag = router->dtag;
- re = DEQ_HEAD(rlink->msg_fifo);
- while (re) {
- DEQ_REMOVE_HEAD(rlink->msg_fifo);
- DEQ_INSERT_TAIL(to_send, re);
- if (DEQ_SIZE(to_send) == link_credit)
- break;
- re = DEQ_HEAD(rlink->msg_fifo);
- }
- router->dtag += DEQ_SIZE(to_send);
- }
-
- offer = DEQ_SIZE(rlink->msg_fifo);
- sys_mutex_unlock(router->lock);
-
- //
- // Deliver all the to_send messages downrange
- //
- re = DEQ_HEAD(to_send);
- while (re) {
- DEQ_REMOVE_HEAD(to_send);
-
- //
- // Get a delivery for the send. This will be the current delivery on the link.
- //
- tag++;
- delivery = dx_delivery(link, pn_dtag((char*) &tag, 8));
-
- //
- // Send the message
- //
- dx_message_send(re->message, link);
-
- //
- // If there is an incoming delivery associated with this message, link it
- // with the outgoing delivery. Otherwise, the message arrived pre-settled
- // and should be sent presettled.
- //
- if (re->delivery) {
- dx_delivery_set_peer(re->delivery, delivery);
- dx_delivery_set_peer(delivery, re->delivery);
- } else
- dx_delivery_free(delivery, 0); // settle and free
-
- pn_link_advance(pn_link);
- event_count++;
-
- dx_message_free(re->message);
- free_dx_routed_event_t(re);
- re = DEQ_HEAD(to_send);
- }
-
- //
- // Process the non-delivery events.
- //
- re = DEQ_HEAD(events);
- while (re) {
- DEQ_REMOVE_HEAD(events);
-
- if (re->delivery) {
- if (re->disposition) {
- pn_delivery_update(dx_delivery_pn(re->delivery), re->disposition);
- event_count++;
- }
- if (re->settle) {
- dx_delivery_free(re->delivery, 0);
- event_count++;
- }
- }
-
- free_dx_routed_event_t(re);
- re = DEQ_HEAD(events);
- }
-
- //
- // Set the offer to the number of messages remaining to be sent.
- //
- pn_link_offered(pn_link, offer);
- return event_count;
-}
-
-
-static dx_field_iterator_t *router_annotate_message(dx_router_t *router, dx_message_t *msg, int *drop)
-{
- dx_parsed_field_t *in_da = dx_message_delivery_annotations(msg);
- dx_composed_field_t *out_da = dx_compose(DX_PERFORMATIVE_DELIVERY_ANNOTATIONS, 0);
- dx_field_iterator_t *ingress_iter = 0;
-
- dx_parsed_field_t *trace = 0;
- dx_parsed_field_t *ingress = 0;
-
- if (in_da) {
- trace = dx_parse_value_by_key(in_da, DX_DA_TRACE);
- ingress = dx_parse_value_by_key(in_da, DX_DA_INGRESS);
- }
-
- dx_compose_start_map(out_da);
-
- //
- // If there is a trace field, append this router's ID to the trace.
- //
- dx_compose_insert_string(out_da, DX_DA_TRACE);
- dx_compose_start_list(out_da);
- if (trace) {
- if (dx_parse_is_list(trace)) {
- uint32_t idx = 0;
- dx_parsed_field_t *trace_item = dx_parse_sub_value(trace, idx);
- while (trace_item) {
- dx_field_iterator_t *iter = dx_parse_raw(trace_item);
- if (dx_field_iterator_equal(iter, (unsigned char*) node_id))
- *drop = 1;
- dx_field_iterator_reset(iter);
- dx_compose_insert_string_iterator(out_da, iter);
- idx++;
- trace_item = dx_parse_sub_value(trace, idx);
- }
- }
- }
-
- dx_compose_insert_string(out_da, node_id);
- dx_compose_end_list(out_da);
-
- //
- // If there is no ingress field, annotate the ingress as this router else
- // keep the original field.
- //
- dx_compose_insert_string(out_da, DX_DA_INGRESS);
- if (ingress && dx_parse_is_scalar(ingress)) {
- ingress_iter = dx_parse_raw(ingress);
- dx_compose_insert_string_iterator(out_da, ingress_iter);
- } else
- dx_compose_insert_string(out_da, node_id);
-
- dx_compose_end_map(out_da);
-
- dx_message_set_delivery_annotations(msg, out_da);
- dx_compose_free(out_da);
-
- //
- // Return the iterator to the ingress field _if_ it was present.
- // If we added the ingress, return NULL.
- //
- return ingress_iter;
-}
-
-
-/**
- * Inbound Delivery Handler
- */
-static void router_rx_handler(void* context, dx_link_t *link, dx_delivery_t *delivery)
-{
- dx_router_t *router = (dx_router_t*) context;
- pn_link_t *pn_link = dx_link_pn(link);
- dx_router_link_t *rlink = (dx_router_link_t*) dx_link_get_context(link);
- dx_message_t *msg;
- int valid_message = 0;
-
- //
- // Receive the message into a local representation. If the returned message
- // pointer is NULL, we have not yet received a complete message.
- //
- msg = dx_message_receive(delivery);
- if (!msg)
- return;
-
- //
- // Consume the delivery and issue a replacement credit
- //
- pn_link_advance(pn_link);
- pn_link_flow(pn_link, 1);
-
- sys_mutex_lock(router->lock);
-
- //
- // Handle the Link-Routing case. If this incoming link is associated with a connected
- // link, simply deliver the message to the outgoing link. There is no need to validate
- // the message in this case.
- //
- if (rlink->connected_link) {
- dx_router_link_t *clink = rlink->connected_link;
- dx_routed_event_t *re = new_dx_routed_event_t();
-
- DEQ_ITEM_INIT(re);
- re->delivery = 0;
- re->message = msg;
- re->settle = false;
- re->disposition = 0;
- DEQ_INSERT_TAIL(clink->msg_fifo, re);
-
- //
- // If the incoming delivery is settled (pre-settled), don't link it into the routed
- // event. If it's not settled, link it into the event for later handling.
- //
- if (dx_delivery_settled(delivery))
- dx_delivery_free(delivery, 0);
- else
- re->delivery = delivery;
-
- sys_mutex_unlock(router->lock);
- dx_link_activate(clink->link);
- return;
- }
-
- //
- // We are performing Message-Routing, therefore we will need to validate the message
- // through the Properties section so we can access the TO field.
- //
- dx_message_t *in_process_copy = 0;
- dx_router_message_cb handler = 0;
- void *handler_context = 0;
-
- valid_message = dx_message_check(msg, DX_DEPTH_PROPERTIES);
-
- if (valid_message) {
- dx_field_iterator_t *iter = dx_message_field_iterator(msg, DX_FIELD_TO);
- dx_address_t *addr;
- int fanout = 0;
-
- if (iter) {
- dx_field_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
-
- //
- // Note: This function is going to need to be refactored so we can put an
- // asynchronous address lookup here. In the event there is a translation
- // of the address (via namespace), it will have to be done here after
- // obtaining the iterator and before doing the hash lookup.
- //
- // Note that this lookup is only done for global/mobile class addresses.
- //
-
- dx_hash_retrieve(router->addr_hash, iter, (void*) &addr);
- dx_field_iterator_reset_view(iter, ITER_VIEW_NO_HOST);
- int is_local = dx_field_iterator_prefix(iter, local_prefix);
- int is_direct = dx_field_iterator_prefix(iter, direct_prefix);
- dx_field_iterator_free(iter);
-
- if (addr) {
- //
- // If the incoming link is an endpoint link, count this as an ingress delivery.
- //
- if (rlink->link_type == DX_LINK_ENDPOINT)
- addr->deliveries_ingress++;
-
- //
- // To field is valid and contains a known destination. Handle the various
- // cases for forwarding.
- //
-
- //
- // Interpret and update the delivery annotations of the message. As a convenience,
- // this function returns the iterator to the ingress field (if it exists).
- //
- int drop = 0;
- dx_field_iterator_t *ingress_iter = router_annotate_message(router, msg, &drop);
-
- //
- // Forward to the in-process handler for this message if there is one. The
- // actual invocation of the handler will occur later after we've released
- // the lock.
- //
- if (!drop && addr->handler) {
- in_process_copy = dx_message_copy(msg);
- handler = addr->handler;
- handler_context = addr->handler_context;
- addr->deliveries_to_container++;
- }
-
- //
- // If the address form is local (i.e. is prefixed by _local), don't forward
- // outside of the router process.
- //
- if (!drop && !is_local) {
- //
- // Forward to all of the local links receiving this address.
- //
- dx_router_link_ref_t *dest_link_ref = DEQ_HEAD(addr->rlinks);
- while (dest_link_ref) {
- dx_routed_event_t *re = new_dx_routed_event_t();
- DEQ_ITEM_INIT(re);
- re->delivery = 0;
- re->message = dx_message_copy(msg);
- re->settle = 0;
- re->disposition = 0;
- DEQ_INSERT_TAIL(dest_link_ref->link->msg_fifo, re);
-
- fanout++;
- if (fanout == 1 && !dx_delivery_settled(delivery))
- re->delivery = delivery;
-
- addr->deliveries_egress++;
- dx_link_activate(dest_link_ref->link->link);
- dest_link_ref = DEQ_NEXT(dest_link_ref);
- }
-
- //
- // If the address form is direct to this router node, don't relay it on
- // to any other part of the network.
- //
- if (!is_direct) {
- //
- // Get the mask bit associated with the ingress router for the message.
- // This will be compared against the "valid_origin" masks for each
- // candidate destination router.
- //
- int origin = -1;
- if (ingress_iter) {
- dx_field_iterator_reset_view(ingress_iter, ITER_VIEW_NODE_HASH);
- dx_address_t *origin_addr;
- dx_hash_retrieve(router->addr_hash, ingress_iter, (void*) &origin_addr);
- if (origin_addr && DEQ_SIZE(origin_addr->rnodes) == 1) {
- dx_router_ref_t *rref = DEQ_HEAD(origin_addr->rnodes);
- origin = rref->router->mask_bit;
- }
- } else
- origin = 0;
-
- //
- // Forward to the next-hops for remote destinations.
- //
- if (origin >= 0) {
- dx_router_ref_t *dest_node_ref = DEQ_HEAD(addr->rnodes);
- dx_router_link_t *dest_link;
- dx_bitmask_t *link_set = dx_bitmask(0);
-
- //
- // Loop over the target nodes for this address. Build a set of outgoing links
- // for which there are valid targets. We do this to avoid sending more than one
- // message down a given link. It's possible that there are multiple destinations
- // for this address that are all reachable over the same link. In this case, we
- // will send only one copy of the message over the link and allow a downstream
- // router to fan the message out.
- //
- while (dest_node_ref) {
- if (dest_node_ref->router->next_hop)
- dest_link = dest_node_ref->router->next_hop->peer_link;
- else
- dest_link = dest_node_ref->router->peer_link;
- if (dest_link && dx_bitmask_value(dest_node_ref->router->valid_origins, origin))
- dx_bitmask_set_bit(link_set, dest_link->mask_bit);
- dest_node_ref = DEQ_NEXT(dest_node_ref);
- }
-
- //
- // Send a copy of the message outbound on each identified link.
- //
- int link_bit;
- while (dx_bitmask_first_set(link_set, &link_bit)) {
- dx_bitmask_clear_bit(link_set, link_bit);
- dest_link = router->out_links_by_mask_bit[link_bit];
- if (dest_link) {
- dx_routed_event_t *re = new_dx_routed_event_t();
- DEQ_ITEM_INIT(re);
- re->delivery = 0;
- re->message = dx_message_copy(msg);
- re->settle = 0;
- re->disposition = 0;
- DEQ_INSERT_TAIL(dest_link->msg_fifo, re);
-
- fanout++;
- if (fanout == 1 && !dx_delivery_settled(delivery))
- re->delivery = delivery;
-
- addr->deliveries_transit++;
- dx_link_activate(dest_link->link);
- }
- }
-
- dx_bitmask_free(link_set);
- }
- }
- }
- }
-
- //
- // In message-routing mode, the handling of the incoming delivery depends on the
- // number of copies of the received message that were forwarded.
- //
- if (handler) {
- dx_delivery_free(delivery, PN_ACCEPTED);
- } else if (fanout == 0) {
- dx_delivery_free(delivery, PN_RELEASED);
- }
- }
- } else {
- //
- // Message is invalid. Reject the message.
- //
- dx_delivery_free(delivery, PN_REJECTED);
- }
-
- sys_mutex_unlock(router->lock);
- dx_message_free(msg);
-
- //
- // Invoke the in-process handler now that the lock is released.
- //
- if (handler) {
- handler(handler_context, in_process_copy, rlink->mask_bit);
- dx_message_free(in_process_copy);
- }
-}
-
-
-/**
- * Delivery Disposition Handler
- */
-static void router_disp_handler(void* context, dx_link_t *link, dx_delivery_t *delivery)
-{
- dx_router_t *router = (dx_router_t*) context;
- bool changed = dx_delivery_disp_changed(delivery);
- uint64_t disp = dx_delivery_disp(delivery);
- bool settled = dx_delivery_settled(delivery);
- dx_delivery_t *peer = dx_delivery_peer(delivery);
-
- if (peer) {
- //
- // The case where this delivery has a peer.
- //
- if (changed || settled) {
- dx_link_t *peer_link = dx_delivery_link(peer);
- dx_router_link_t *prl = (dx_router_link_t*) dx_link_get_context(peer_link);
- dx_routed_event_t *re = new_dx_routed_event_t();
- DEQ_ITEM_INIT(re);
- re->delivery = peer;
- re->message = 0;
- re->settle = settled;
- re->disposition = changed ? disp : 0;
-
- sys_mutex_lock(router->lock);
- DEQ_INSERT_TAIL(prl->event_fifo, re);
- sys_mutex_unlock(router->lock);
-
- dx_link_activate(peer_link);
- }
-
- } else {
- //
- // The no-peer case. Ignore status changes and echo settlement.
- //
- if (settled)
- dx_delivery_free(delivery, 0);
- }
-}
-
-
-/**
- * New Incoming Link Handler
- */
-static int router_incoming_link_handler(void* context, dx_link_t *link)
-{
- dx_router_t *router = (dx_router_t*) context;
- pn_link_t *pn_link = dx_link_pn(link);
- int is_router = dx_router_terminus_is_router(dx_link_remote_source(link));
-
- if (is_router && !dx_router_connection_is_inter_router(dx_link_connection(link))) {
- dx_log(module, LOG_WARNING, "Incoming link claims router capability but is not on an inter-router connection");
- pn_link_close(pn_link);
- return 0;
- }
-
- dx_router_link_t *rlink = new_dx_router_link_t();
- DEQ_ITEM_INIT(rlink);
- rlink->link_type = is_router ? DX_LINK_ROUTER : DX_LINK_ENDPOINT;
- rlink->link_direction = DX_INCOMING;
- rlink->owning_addr = 0;
- rlink->link = link;
- rlink->connected_link = 0;
- rlink->peer_link = 0;
- rlink->ref = 0;
- DEQ_INIT(rlink->event_fifo);
- DEQ_INIT(rlink->msg_fifo);
-
- dx_link_set_context(link, rlink);
-
- sys_mutex_lock(router->lock);
- rlink->mask_bit = is_router ? dx_router_find_mask_bit_LH(router, link) : 0;
- DEQ_INSERT_TAIL(router->links, rlink);
- sys_mutex_unlock(router->lock);
-
- pn_terminus_copy(dx_link_source(link), dx_link_remote_source(link));
- pn_terminus_copy(dx_link_target(link), dx_link_remote_target(link));
- pn_link_flow(pn_link, 1000);
- pn_link_open(pn_link);
-
- //
- // TODO - If the address has link-route semantics, create all associated
- // links needed to go with this one.
- //
-
- return 0;
-}
-
-
-/**
- * New Outgoing Link Handler
- */
-static int router_outgoing_link_handler(void* context, dx_link_t *link)
-{
- dx_router_t *router = (dx_router_t*) context;
- pn_link_t *pn_link = dx_link_pn(link);
- const char *r_src = pn_terminus_get_address(dx_link_remote_source(link));
- int is_dynamic = pn_terminus_is_dynamic(dx_link_remote_source(link));
- int is_router = dx_router_terminus_is_router(dx_link_remote_target(link));
- int propagate = 0;
- dx_field_iterator_t *iter = 0;
-
- if (is_router && !dx_router_connection_is_inter_router(dx_link_connection(link))) {
- dx_log(module, LOG_WARNING, "Outgoing link claims router capability but is not on an inter-router connection");
- pn_link_close(pn_link);
- return 0;
- }
-
- //
- // If this link is not a router link and it has no source address, we can't
- // accept it.
- //
- if (r_src == 0 && !is_router && !is_dynamic) {
- pn_link_close(pn_link);
- return 0;
- }
-
-
- //
- // If this is an endpoint link with a source address, make sure the address is
- // appropriate for endpoint links. If it is not mobile address, it cannot be
- // bound to an endpoint link.
- //
- if(r_src && !is_router && !is_dynamic) {
- iter = dx_field_iterator_string(r_src, ITER_VIEW_ADDRESS_HASH);
- unsigned char prefix = dx_field_iterator_octet(iter);
- dx_field_iterator_reset(iter);
-
- if (prefix != 'M') {
- dx_field_iterator_free(iter);
- pn_link_close(pn_link);
- dx_log(module, LOG_WARNING, "Rejected an outgoing endpoint link with a router address: %s", r_src);
- return 0;
- }
- }
-
- //
- // Create a router_link record for this link. Some of the fields will be
- // modified in the different cases below.
- //
- dx_router_link_t *rlink = new_dx_router_link_t();
- DEQ_ITEM_INIT(rlink);
- rlink->link_type = is_router ? DX_LINK_ROUTER : DX_LINK_ENDPOINT;
- rlink->link_direction = DX_OUTGOING;
- rlink->owning_addr = 0;
- rlink->link = link;
- rlink->connected_link = 0;
- rlink->peer_link = 0;
- rlink->ref = 0;
- DEQ_INIT(rlink->event_fifo);
- DEQ_INIT(rlink->msg_fifo);
-
- dx_link_set_context(link, rlink);
- pn_terminus_copy(dx_link_source(link), dx_link_remote_source(link));
- pn_terminus_copy(dx_link_target(link), dx_link_remote_target(link));
-
- sys_mutex_lock(router->lock);
- rlink->mask_bit = is_router ? dx_router_find_mask_bit_LH(router, link) : 0;
-
- if (is_router) {
- //
- // If this is a router link, put it in the hello_address link-list.
- //
- dx_router_add_link_ref_LH(&router->hello_addr->rlinks, rlink);
- rlink->owning_addr = router->hello_addr;
- router->out_links_by_mask_bit[rlink->mask_bit] = rlink;
-
- } else {
- //
- // If this is an endpoint link, check the source. If it is dynamic, we will
- // assign it an ephemeral and routable address. If it has a non-dymanic
- // address, that address needs to be set up in the address list.
- //
- char temp_addr[1000]; // FIXME
- dx_address_t *addr;
-
- if (is_dynamic) {
- dx_router_generate_temp_addr(router, temp_addr, 1000);
- iter = dx_field_iterator_string(temp_addr, ITER_VIEW_ADDRESS_HASH);
- pn_terminus_set_address(dx_link_source(link), temp_addr);
- dx_log(module, LOG_INFO, "Assigned temporary routable address: %s", temp_addr);
- } else
- dx_log(module, LOG_INFO, "Registered local address: %s", r_src);
-
- dx_hash_retrieve(router->addr_hash, iter, (void**) &addr);
- if (!addr) {
- addr = new_dx_address_t();
- memset(addr, 0, sizeof(dx_address_t));
- DEQ_ITEM_INIT(addr);
- DEQ_INIT(addr->rlinks);
- DEQ_INIT(addr->rnodes);
- dx_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
- DEQ_INSERT_TAIL(router->addrs, addr);
- }
-
- rlink->owning_addr = addr;
- dx_router_add_link_ref_LH(&addr->rlinks, rlink);
-
- //
- // If this is not a dynamic address and it is the first local subscription
- // to the address, supply the address to the router module for propagation
- // to other nodes.
- //
- propagate = (!is_dynamic) && (DEQ_SIZE(addr->rlinks) == 1);
- }
-
- DEQ_INSERT_TAIL(router->links, rlink);
- sys_mutex_unlock(router->lock);
-
- if (propagate)
- dx_router_mobile_added(router, iter);
-
- if (iter)
- dx_field_iterator_free(iter);
- pn_link_open(pn_link);
- return 0;
-}
-
-
-/**
- * Link Detached Handler
- */
-static int router_link_detach_handler(void* context, dx_link_t *link, int closed)
-{
- dx_router_t *router = (dx_router_t*) context;
- dx_router_link_t *rlink = (dx_router_link_t*) dx_link_get_context(link);
- dx_router_conn_t *shared = (dx_router_conn_t*) dx_link_get_conn_context(link);
- dx_address_t *oaddr = 0;
-
- if (shared) {
- dx_link_set_conn_context(link, 0);
- free_dx_router_conn_t(shared);
- }
-
- if (!rlink)
- return 0;
-
- sys_mutex_lock(router->lock);
-
- //
- // If the link is outgoing, we must disassociate it from its address.
- //
- if (rlink->link_direction == DX_OUTGOING && rlink->owning_addr) {
- dx_router_del_link_ref_LH(&rlink->owning_addr->rlinks, rlink);
- oaddr = rlink->owning_addr;
- }
-
- //
- // If this is an outgoing inter-router link, we must remove the by-mask-bit
- // index reference to this link.
- //
- if (rlink->link_type == DX_LINK_ROUTER && rlink->link_direction == DX_OUTGOING) {
- if (router->out_links_by_mask_bit[rlink->mask_bit] == rlink)
- router->out_links_by_mask_bit[rlink->mask_bit] = 0;
- else
- dx_log(module, LOG_CRITICAL, "Outgoing router link closing but not in index: bit=%d", rlink->mask_bit);
- }
-
- //
- // If this is an incoming inter-router link, we must free the mask_bit.
- //
- if (rlink->link_type == DX_LINK_ROUTER && rlink->link_direction == DX_INCOMING)
- dx_bitmask_set_bit(router->neighbor_free_mask, rlink->mask_bit);
-
- //
- // Remove the link from the master list-of-links.
- //
- DEQ_REMOVE(router->links, rlink);
- sys_mutex_unlock(router->lock);
-
- //
- // Check to see if the owning address should be deleted
- //
- dx_router_check_addr(router, oaddr, 1);
-
- // TODO - wrap the free to handle the recursive items
- free_dx_router_link_t(rlink);
-
- return 0;
-}
-
-
-static void router_inbound_open_handler(void *type_context, dx_connection_t *conn)
-{
-}
-
-
-static void router_outbound_open_handler(void *type_context, dx_connection_t *conn)
-{
- //
- // Check the configured role of this connection. If it is not the inter-router
- // role, ignore it.
- //
- if (!dx_router_connection_is_inter_router(conn)) {
- dx_log(module, LOG_WARNING, "Outbound connection set up without inter-router role");
- return;
- }
-
- dx_router_t *router = (dx_router_t*) type_context;
- dx_link_t *sender;
- dx_link_t *receiver;
- dx_router_link_t *rlink;
- int mask_bit = 0;
- size_t clen = strlen(DX_CAPABILITY_ROUTER);
-
- //
- // Allocate a mask bit to designate the pair of links connected to the neighbor router
- //
- sys_mutex_lock(router->lock);
- if (dx_bitmask_first_set(router->neighbor_free_mask, &mask_bit)) {
- dx_bitmask_clear_bit(router->neighbor_free_mask, mask_bit);
- } else {
- sys_mutex_unlock(router->lock);
- dx_log(module, LOG_CRITICAL, "Exceeded maximum inter-router link count");
- return;
- }
-
- //
- // Create an incoming link with router source capability
- //
- receiver = dx_link(router->node, conn, DX_INCOMING, DX_INTERNODE_LINK_NAME_1);
- // TODO - We don't want to have to cast away the constness of the literal string here!
- // See PROTON-429
- pn_data_put_symbol(pn_terminus_capabilities(dx_link_target(receiver)), pn_bytes(clen, (char*) DX_CAPABILITY_ROUTER));
-
- rlink = new_dx_router_link_t();
- DEQ_ITEM_INIT(rlink);
- rlink->mask_bit = mask_bit;
- rlink->link_type = DX_LINK_ROUTER;
- rlink->link_direction = DX_INCOMING;
- rlink->owning_addr = 0;
- rlink->link = receiver;
- rlink->connected_link = 0;
- rlink->peer_link = 0;
- DEQ_INIT(rlink->event_fifo);
- DEQ_INIT(rlink->msg_fifo);
-
- dx_link_set_context(receiver, rlink);
- DEQ_INSERT_TAIL(router->links, rlink);
-
- //
- // Create an outgoing link with router target capability
- //
- sender = dx_link(router->node, conn, DX_OUTGOING, DX_INTERNODE_LINK_NAME_2);
- // TODO - We don't want to have to cast away the constness of the literal string here!
- // See PROTON-429
- pn_data_put_symbol(pn_terminus_capabilities(dx_link_source(sender)), pn_bytes(clen, (char *) DX_CAPABILITY_ROUTER));
-
- rlink = new_dx_router_link_t();
- DEQ_ITEM_INIT(rlink);
- rlink->mask_bit = mask_bit;
- rlink->link_type = DX_LINK_ROUTER;
- rlink->link_direction = DX_OUTGOING;
- rlink->owning_addr = router->hello_addr;
- rlink->link = sender;
- rlink->connected_link = 0;
- rlink->peer_link = 0;
- DEQ_INIT(rlink->event_fifo);
- DEQ_INIT(rlink->msg_fifo);
-
- //
- // Add the new outgoing link to the hello_address's list of links.
- //
- dx_router_add_link_ref_LH(&router->hello_addr->rlinks, rlink);
-
- //
- // Index this link from the by-maskbit index so we can later find it quickly
- // when provided with the mask bit.
- //
- router->out_links_by_mask_bit[mask_bit] = rlink;
-
- dx_link_set_context(sender, rlink);
- DEQ_INSERT_TAIL(router->links, rlink);
- sys_mutex_unlock(router->lock);
-
- pn_link_open(dx_link_pn(receiver));
- pn_link_open(dx_link_pn(sender));
- pn_link_flow(dx_link_pn(receiver), 1000);
-}
-
-
-static void dx_router_timer_handler(void *context)
-{
- dx_router_t *router = (dx_router_t*) context;
-
- //
- // Periodic processing.
- //
- dx_pyrouter_tick(router);
- dx_timer_schedule(router->timer, 1000);
-}
-
-
-static dx_node_type_t router_node = {"router", 0, 0,
- router_rx_handler,
- router_disp_handler,
- router_incoming_link_handler,
- router_outgoing_link_handler,
- router_writable_link_handler,
- router_link_detach_handler,
- 0, // node_created_handler
- 0, // node_destroyed_handler
- router_inbound_open_handler,
- router_outbound_open_handler };
-static int type_registered = 0;
-
-
-dx_router_t *dx_router(dx_dispatch_t *dx, dx_router_mode_t mode, const char *area, const char *id)
-{
- if (!type_registered) {
- type_registered = 1;
- dx_container_register_node_type(dx, &router_node);
- }
-
- size_t dplen = 9 + strlen(area) + strlen(id);
- direct_prefix = (char*) malloc(dplen);
- strcpy(direct_prefix, "_topo/");
- strcat(direct_prefix, area);
- strcat(direct_prefix, "/");
- strcat(direct_prefix, id);
- strcat(direct_prefix, "/");
-
- node_id = (char*) malloc(dplen);
- strcpy(node_id, area);
- strcat(node_id, "/");
- strcat(node_id, id);
-
- dx_router_t *router = NEW(dx_router_t);
-
- router_node.type_context = router;
-
- dx->router = router;
- router->dx = dx;
- router->router_mode = mode;
- router->router_area = area;
- router->router_id = id;
- router->node = dx_container_set_default_node_type(dx, &router_node, (void*) router, DX_DIST_BOTH);
- DEQ_INIT(router->addrs);
- router->addr_hash = dx_hash(10, 32, 0);
-
- DEQ_INIT(router->links);
- DEQ_INIT(router->routers);
-
- router->out_links_by_mask_bit = NEW_PTR_ARRAY(dx_router_link_t, dx_bitmask_width());
- router->routers_by_mask_bit = NEW_PTR_ARRAY(dx_router_node_t, dx_bitmask_width());
- for (int idx = 0; idx < dx_bitmask_width(); idx++) {
- router->out_links_by_mask_bit[idx] = 0;
- router->routers_by_mask_bit[idx] = 0;
- }
-
- router->neighbor_free_mask = dx_bitmask(1);
- router->lock = sys_mutex();
- router->timer = dx_timer(dx, dx_router_timer_handler, (void*) router);
- router->dtag = 1;
- router->pyRouter = 0;
- router->pyTick = 0;
- router->pyAdded = 0;
- router->pyRemoved = 0;
-
- //
- // Create addresses for all of the routers in the topology. It will be registered
- // locally later in the initialization sequence.
- //
- if (router->router_mode == DX_ROUTER_MODE_INTERIOR) {
- router->router_addr = dx_router_register_address(dx, "qdxrouter", 0, 0);
- router->hello_addr = dx_router_register_address(dx, "qdxhello", 0, 0);
- }
-
- //
- // Inform the field iterator module of this router's id and area. The field iterator
- // uses this to offload some of the address-processing load from the router.
- //
- dx_field_iterator_set_address(area, id);
-
- //
- // Set up the usage of the embedded python router module.
- //
- dx_python_start();
-
- switch (router->router_mode) {
- case DX_ROUTER_MODE_STANDALONE: dx_log(module, LOG_INFO, "Router started in Standalone mode"); break;
- case DX_ROUTER_MODE_INTERIOR: dx_log(module, LOG_INFO, "Router started in Interior mode, area=%s id=%s", area, id); break;
- case DX_ROUTER_MODE_EDGE: dx_log(module, LOG_INFO, "Router started in Edge mode"); break;
- }
-
- return router;
-}
-
-
-void dx_router_setup_late(dx_dispatch_t *dx)
-{
- dx_router_agent_setup(dx->router);
- dx_router_python_setup(dx->router);
- dx_timer_schedule(dx->router->timer, 1000);
-}
-
-
-void dx_router_free(dx_router_t *router)
-{
- dx_container_set_default_node_type(router->dx, 0, 0, DX_DIST_BOTH);
- sys_mutex_free(router->lock);
- free(router);
- dx_python_stop();
-}
-
-
-const char *dx_router_id(const dx_dispatch_t *dx)
-{
- return node_id;
-}
-
-
-dx_address_t *dx_router_register_address(dx_dispatch_t *dx,
- const char *address,
- dx_router_message_cb handler,
- void *context)
-{
- char addr_string[1000];
- dx_router_t *router = dx->router;
- dx_address_t *addr;
- dx_field_iterator_t *iter;
-
- strcpy(addr_string, "L"); // Local Hash-Key Space
- strcat(addr_string, address);
- iter = dx_field_iterator_string(addr_string, ITER_VIEW_NO_HOST);
-
- sys_mutex_lock(router->lock);
- dx_hash_retrieve(router->addr_hash, iter, (void**) &addr);
- if (!addr) {
- addr = new_dx_address_t();
- memset(addr, 0, sizeof(dx_address_t));
- DEQ_ITEM_INIT(addr);
- DEQ_INIT(addr->rlinks);
- DEQ_INIT(addr->rnodes);
- dx_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
- DEQ_ITEM_INIT(addr);
- DEQ_INSERT_TAIL(router->addrs, addr);
- }
- dx_field_iterator_free(iter);
-
- addr->handler = handler;
- addr->handler_context = context;
-
- sys_mutex_unlock(router->lock);
-
- if (handler)
- dx_log(module, LOG_INFO, "In-Process Address Registered: %s", address);
- return addr;
-}
-
-
-void dx_router_unregister_address(dx_address_t *ad)
-{
- //free_dx_address_t(ad);
-}
-
-
-void dx_router_send(dx_dispatch_t *dx,
- dx_field_iterator_t *address,
- dx_message_t *msg)
-{
- dx_router_t *router = dx->router;
- dx_address_t *addr;
-
- dx_field_iterator_reset_view(address, ITER_VIEW_ADDRESS_HASH);
- sys_mutex_lock(router->lock);
- dx_hash_retrieve(router->addr_hash, address, (void*) &addr);
- if (addr) {
- //
- // Forward to all of the local links receiving this address.
- //
- addr->deliveries_from_container++;
- dx_router_link_ref_t *dest_link_ref = DEQ_HEAD(addr->rlinks);
- while (dest_link_ref) {
- dx_routed_event_t *re = new_dx_routed_event_t();
- DEQ_ITEM_INIT(re);
- re->delivery = 0;
- re->message = dx_message_copy(msg);
- re->settle = 0;
- re->disposition = 0;
- DEQ_INSERT_TAIL(dest_link_ref->link->msg_fifo, re);
-
- dx_link_activate(dest_link_ref->link->link);
- addr->deliveries_egress++;
-
- dest_link_ref = DEQ_NEXT(dest_link_ref);
- }
-
- //
- // Forward to the next-hops for remote destinations.
- //
- dx_router_ref_t *dest_node_ref = DEQ_HEAD(addr->rnodes);
- dx_router_link_t *dest_link;
- dx_bitmask_t *link_set = dx_bitmask(0);
-
- while (dest_node_ref) {
- if (dest_node_ref->router->next_hop)
- dest_link = dest_node_ref->router->next_hop->peer_link;
- else
- dest_link = dest_node_ref->router->peer_link;
- if (dest_link)
- dx_bitmask_set_bit(link_set, dest_link->mask_bit);
- dest_node_ref = DEQ_NEXT(dest_node_ref);
- }
-
- int link_bit;
- while (dx_bitmask_first_set(link_set, &link_bit)) {
- dx_bitmask_clear_bit(link_set, link_bit);
- dest_link = router->out_links_by_mask_bit[link_bit];
- if (dest_link) {
- dx_routed_event_t *re = new_dx_routed_event_t();
- DEQ_ITEM_INIT(re);
- re->delivery = 0;
- re->message = dx_message_copy(msg);
- re->settle = 0;
- re->disposition = 0;
- DEQ_INSERT_TAIL(dest_link->msg_fifo, re);
- dx_link_activate(dest_link->link);
- addr->deliveries_transit++;
- }
- }
-
- dx_bitmask_free(link_set);
- }
- sys_mutex_unlock(router->lock); // TOINVESTIGATE Move this higher?
-}
-
-
-void dx_router_send2(dx_dispatch_t *dx,
- const char *address,
- dx_message_t *msg)
-{
- dx_field_iterator_t *iter = dx_field_iterator_string(address, ITER_VIEW_ADDRESS_HASH);
- dx_router_send(dx, iter, msg);
- dx_field_iterator_free(iter);
-}
-
diff --git a/extras/dispatch/src/router_private.h b/extras/dispatch/src/router_private.h
deleted file mode 100644
index 066188b3f7..0000000000
--- a/extras/dispatch/src/router_private.h
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef __router_private_h__
-#define __router_private_h__ 1
-/*
- * 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.
- */
-
-typedef struct dx_router_link_t dx_router_link_t;
-typedef struct dx_router_node_t dx_router_node_t;
-typedef struct dx_router_ref_t dx_router_ref_t;
-typedef struct dx_router_link_ref_t dx_router_link_ref_t;
-typedef struct dx_router_conn_t dx_router_conn_t;
-
-void dx_router_python_setup(dx_router_t *router);
-void dx_pyrouter_tick(dx_router_t *router);
-void dx_router_agent_setup(dx_router_t *router);
-
-typedef enum {
- DX_ROUTER_MODE_STANDALONE, // Standalone router. No routing protocol participation
- DX_ROUTER_MODE_INTERIOR, // Interior router. Full participation in routing protocol.
- DX_ROUTER_MODE_EDGE // Edge router. No routing protocol participation, access via other protocols.
-} dx_router_mode_t;
-
-typedef enum {
- DX_LINK_ENDPOINT, // A link to a connected endpoint
- DX_LINK_ROUTER, // A link to a peer router in the same area
- DX_LINK_AREA // A link to a peer router in a different area (area boundary)
-} dx_link_type_t;
-
-
-typedef struct dx_routed_event_t {
- DEQ_LINKS(struct dx_routed_event_t);
- dx_delivery_t *delivery;
- dx_message_t *message;
- bool settle;
- uint64_t disposition;
-} dx_routed_event_t;
-
-ALLOC_DECLARE(dx_routed_event_t);
-DEQ_DECLARE(dx_routed_event_t, dx_routed_event_list_t);
-
-
-struct dx_router_link_t {
- DEQ_LINKS(dx_router_link_t);
- int mask_bit; // Unique mask bit if this is an inter-router link
- dx_link_type_t link_type;
- dx_direction_t link_direction;
- dx_address_t *owning_addr; // [ref] Address record that owns this link
- dx_link_t *link; // [own] Link pointer
- dx_router_link_t *connected_link; // [ref] If this is a link-route, reference the connected link
- dx_router_link_t *peer_link; // [ref] If this is a bidirectional link-route, reference the peer link
- dx_router_link_ref_t *ref; // Pointer to a containing reference object
- dx_routed_event_list_t event_fifo; // FIFO of outgoing delivery/link events (no messages)
- dx_routed_event_list_t msg_fifo; // FIFO of outgoing message deliveries
-};
-
-ALLOC_DECLARE(dx_router_link_t);
-DEQ_DECLARE(dx_router_link_t, dx_router_link_list_t);
-
-struct dx_router_node_t {
- DEQ_LINKS(dx_router_node_t);
- dx_address_t *owning_addr;
- int mask_bit;
- dx_router_node_t *next_hop; // Next hop node _if_ this is not a neighbor node
- dx_router_link_t *peer_link; // Outgoing link _if_ this is a neighbor node
- uint32_t ref_count;
- dx_bitmask_t *valid_origins;
-};
-
-ALLOC_DECLARE(dx_router_node_t);
-DEQ_DECLARE(dx_router_node_t, dx_router_node_list_t);
-
-struct dx_router_ref_t {
- DEQ_LINKS(dx_router_ref_t);
- dx_router_node_t *router;
-};
-
-ALLOC_DECLARE(dx_router_ref_t);
-DEQ_DECLARE(dx_router_ref_t, dx_router_ref_list_t);
-
-
-struct dx_router_link_ref_t {
- DEQ_LINKS(dx_router_link_ref_t);
- dx_router_link_t *link;
-};
-
-ALLOC_DECLARE(dx_router_link_ref_t);
-DEQ_DECLARE(dx_router_link_ref_t, dx_router_link_ref_list_t);
-
-
-struct dx_router_conn_t {
- int mask_bit;
-};
-
-ALLOC_DECLARE(dx_router_conn_t);
-
-
-struct dx_address_t {
- DEQ_LINKS(dx_address_t);
- dx_router_message_cb handler; // In-Process Consumer
- void *handler_context; // In-Process Consumer context
- dx_router_link_ref_list_t rlinks; // Locally-Connected Consumers
- dx_router_ref_list_t rnodes; // Remotely-Connected Consumers
- dx_hash_handle_t *hash_handle; // Linkage back to the hash table entry
-
- uint64_t deliveries_ingress;
- uint64_t deliveries_egress;
- uint64_t deliveries_transit;
- uint64_t deliveries_to_container;
- uint64_t deliveries_from_container;
-};
-
-ALLOC_DECLARE(dx_address_t);
-DEQ_DECLARE(dx_address_t, dx_address_list_t);
-
-
-struct dx_router_t {
- dx_dispatch_t *dx;
- dx_router_mode_t router_mode;
- const char *router_area;
- const char *router_id;
- dx_node_t *node;
-
- dx_address_list_t addrs;
- dx_hash_t *addr_hash;
- dx_address_t *router_addr;
- dx_address_t *hello_addr;
-
- dx_router_link_list_t links;
- dx_router_node_list_t routers;
- dx_router_link_t **out_links_by_mask_bit;
- dx_router_node_t **routers_by_mask_bit;
-
- dx_bitmask_t *neighbor_free_mask;
- sys_mutex_t *lock;
- dx_timer_t *timer;
- uint64_t dtag;
-
- PyObject *pyRouter;
- PyObject *pyTick;
- PyObject *pyAdded;
- PyObject *pyRemoved;
-
- dx_agent_class_t *class_router;
- dx_agent_class_t *class_link;
- dx_agent_class_t *class_node;
- dx_agent_class_t *class_address;
-};
-
-
-
-void dx_router_check_addr(dx_router_t *router, dx_address_t *addr, int was_local);
-void dx_router_add_link_ref_LH(dx_router_link_ref_list_t *ref_list, dx_router_link_t *link);
-void dx_router_del_link_ref_LH(dx_router_link_ref_list_t *ref_list, dx_router_link_t *link);
-
-void dx_router_add_node_ref_LH(dx_router_ref_list_t *ref_list, dx_router_node_t *rnode);
-void dx_router_del_node_ref_LH(dx_router_ref_list_t *ref_list, dx_router_node_t *rnode);
-
-void dx_router_mobile_added(dx_router_t *router, dx_field_iterator_t *iter);
-void dx_router_mobile_removed(dx_router_t *router, const char *addr);
-
-
-#endif
diff --git a/extras/dispatch/src/router_pynode.c b/extras/dispatch/src/router_pynode.c
deleted file mode 100644
index 82b08c0785..0000000000
--- a/extras/dispatch/src/router_pynode.c
+++ /dev/null
@@ -1,682 +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/dispatch/python_embedded.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <qpid/dispatch.h>
-#include "dispatch_private.h"
-#include "router_private.h"
-
-static char *module = "router.pynode";
-
-typedef struct {
- PyObject_HEAD
- dx_router_t *router;
-} RouterAdapter;
-
-
-static char *dx_add_router(dx_router_t *router, const char *address, int router_maskbit, int link_maskbit)
-{
- if (router_maskbit >= dx_bitmask_width() || router_maskbit < 0)
- return "Router bit mask out of range";
-
- if (link_maskbit >= dx_bitmask_width() || link_maskbit < -1)
- return "Link bit mask out of range";
-
- sys_mutex_lock(router->lock);
- if (router->routers_by_mask_bit[router_maskbit] != 0) {
- sys_mutex_unlock(router->lock);
- return "Adding router over already existing router";
- }
-
- if (link_maskbit >= 0 && router->out_links_by_mask_bit[link_maskbit] == 0) {
- sys_mutex_unlock(router->lock);
- return "Adding neighbor router with invalid link reference";
- }
-
- //
- // Hash lookup the address to ensure there isn't an existing router address.
- //
- dx_field_iterator_t *iter = dx_field_iterator_string(address, ITER_VIEW_ADDRESS_HASH);
- dx_address_t *addr;
-
- dx_hash_retrieve(router->addr_hash, iter, (void**) &addr);
- assert(addr == 0);
-
- //
- // Create an address record for this router and insert it in the hash table.
- // This record will be found whenever a "foreign" topological address to this
- // remote router is looked up.
- //
- addr = new_dx_address_t();
- memset(addr, 0, sizeof(dx_address_t));
- DEQ_ITEM_INIT(addr);
- DEQ_INIT(addr->rlinks);
- DEQ_INIT(addr->rnodes);
- dx_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
- DEQ_INSERT_TAIL(router->addrs, addr);
- dx_field_iterator_free(iter);
-
- //
- // Create a router-node record to represent the remote router.
- //
- dx_router_node_t *rnode = new_dx_router_node_t();
- DEQ_ITEM_INIT(rnode);
- rnode->owning_addr = addr;
- rnode->mask_bit = router_maskbit;
- rnode->next_hop = 0;
- rnode->peer_link = 0;
- rnode->ref_count = 0;
- rnode->valid_origins = dx_bitmask(0);
-
- DEQ_INSERT_TAIL(router->routers, rnode);
-
- //
- // Link the router record to the address record.
- //
- dx_router_add_node_ref_LH(&addr->rnodes, rnode);
-
- //
- // Link the router record to the router address record.
- //
- dx_router_add_node_ref_LH(&router->router_addr->rnodes, rnode);
-
- //
- // Add the router record to the mask-bit index.
- //
- router->routers_by_mask_bit[router_maskbit] = rnode;
-
- //
- // If this is a neighbor router, add the peer_link reference to the
- // router record.
- //
- if (link_maskbit >= 0)
- rnode->peer_link = router->out_links_by_mask_bit[link_maskbit];
-
- sys_mutex_unlock(router->lock);
- return 0;
-}
-
-
-static char *dx_del_router(dx_router_t *router, int router_maskbit)
-{
- if (router_maskbit >= dx_bitmask_width() || router_maskbit < 0)
- return "Router bit mask out of range";
-
- sys_mutex_lock(router->lock);
- if (router->routers_by_mask_bit[router_maskbit] == 0) {
- sys_mutex_unlock(router->lock);
- return "Deleting nonexistent router";
- }
-
- dx_router_node_t *rnode = router->routers_by_mask_bit[router_maskbit];
- dx_address_t *oaddr = rnode->owning_addr;
- assert(oaddr);
-
- //
- // Unlink the router node from the address record
- //
- dx_router_del_node_ref_LH(&oaddr->rnodes, rnode);
-
- //
- // While the router node has a non-zero reference count, look for addresses
- // to unlink the node from.
- //
- dx_address_t *addr = DEQ_HEAD(router->addrs);
- while (addr && rnode->ref_count > 0) {
- dx_router_del_node_ref_LH(&addr->rnodes, rnode);
- addr = DEQ_NEXT(addr);
- }
- assert(rnode->ref_count == 0);
-
- //
- // Free the router node and the owning address records.
- //
- dx_bitmask_free(rnode->valid_origins);
- DEQ_REMOVE(router->routers, rnode);
- free_dx_router_node_t(rnode);
-
- dx_hash_remove_by_handle(router->addr_hash, oaddr->hash_handle);
- DEQ_REMOVE(router->addrs, oaddr);
- dx_hash_handle_free(oaddr->hash_handle);
- router->routers_by_mask_bit[router_maskbit] = 0;
- free_dx_address_t(oaddr);
-
- sys_mutex_unlock(router->lock);
- return 0;
-}
-
-
-static PyObject* dx_add_remote_router(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- const char *address;
- int router_maskbit;
-
- if (!PyArg_ParseTuple(args, "si", &address, &router_maskbit))
- return 0;
-
- char *error = dx_add_router(router, address, router_maskbit, -1);
- if (error) {
- PyErr_SetString(PyExc_Exception, error);
- return 0;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyObject* dx_del_remote_router(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- int router_maskbit;
-
- if (!PyArg_ParseTuple(args, "i", &router_maskbit))
- return 0;
-
- char *error = dx_del_router(router, router_maskbit);
- if (error) {
- PyErr_SetString(PyExc_Exception, error);
- return 0;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyObject* dx_set_next_hop(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- int router_maskbit;
- int next_hop_maskbit;
-
- if (!PyArg_ParseTuple(args, "ii", &router_maskbit, &next_hop_maskbit))
- return 0;
-
- if (router_maskbit >= dx_bitmask_width() || router_maskbit < 0) {
- PyErr_SetString(PyExc_Exception, "Router bit mask out of range");
- return 0;
- }
-
- if (next_hop_maskbit >= dx_bitmask_width() || next_hop_maskbit < 0) {
- PyErr_SetString(PyExc_Exception, "Next Hop bit mask out of range");
- return 0;
- }
-
- if (router->routers_by_mask_bit[router_maskbit] == 0) {
- PyErr_SetString(PyExc_Exception, "Router Not Found");
- return 0;
- }
-
- if (router->routers_by_mask_bit[next_hop_maskbit] == 0) {
- PyErr_SetString(PyExc_Exception, "Next Hop Not Found");
- return 0;
- }
-
- if (router_maskbit != next_hop_maskbit) {
- dx_router_node_t *rnode = router->routers_by_mask_bit[router_maskbit];
- rnode->next_hop = router->routers_by_mask_bit[next_hop_maskbit];
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyObject* dx_set_valid_origins(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- int router_maskbit;
- PyObject *origin_list;
- Py_ssize_t idx;
-
- if (!PyArg_ParseTuple(args, "iO", &router_maskbit, &origin_list))
- return 0;
-
- if (router_maskbit >= dx_bitmask_width() || router_maskbit < 0) {
- PyErr_SetString(PyExc_Exception, "Router bit mask out of range");
- return 0;
- }
-
- if (router->routers_by_mask_bit[router_maskbit] == 0) {
- PyErr_SetString(PyExc_Exception, "Router Not Found");
- return 0;
- }
-
- if (!PyList_Check(origin_list)) {
- PyErr_SetString(PyExc_Exception, "Expected List as argument 2");
- return 0;
- }
-
- Py_ssize_t origin_count = PyList_Size(origin_list);
- dx_router_node_t *rnode = router->routers_by_mask_bit[router_maskbit];
- int maskbit;
-
- for (idx = 0; idx < origin_count; idx++) {
- maskbit = PyInt_AS_LONG(PyList_GetItem(origin_list, idx));
-
- if (maskbit >= dx_bitmask_width() || maskbit < 0) {
- PyErr_SetString(PyExc_Exception, "Origin bit mask out of range");
- return 0;
- }
-
- if (router->routers_by_mask_bit[maskbit] == 0) {
- PyErr_SetString(PyExc_Exception, "Origin router Not Found");
- return 0;
- }
- }
-
- dx_bitmask_clear_all(rnode->valid_origins);
- dx_bitmask_set_bit(rnode->valid_origins, 0); // This router is a valid origin for all destinations
- for (idx = 0; idx < origin_count; idx++) {
- maskbit = PyInt_AS_LONG(PyList_GetItem(origin_list, idx));
- dx_bitmask_set_bit(rnode->valid_origins, maskbit);
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyObject* dx_add_neighbor_router(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- const char *address;
- int router_maskbit;
- int link_maskbit;
-
- if (!PyArg_ParseTuple(args, "sii", &address, &router_maskbit, &link_maskbit))
- return 0;
-
- char *error = dx_add_router(router, address, router_maskbit, link_maskbit);
- if (error) {
- PyErr_SetString(PyExc_Exception, error);
- return 0;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyObject* dx_del_neighbor_router(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- int router_maskbit;
-
- if (!PyArg_ParseTuple(args, "i", &router_maskbit))
- return 0;
-
- char *error = dx_del_router(router, router_maskbit);
- if (error) {
- PyErr_SetString(PyExc_Exception, error);
- return 0;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyObject* dx_map_destination(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- const char *addr_string;
- int maskbit;
- dx_address_t *addr;
- dx_field_iterator_t *iter;
-
- if (!PyArg_ParseTuple(args, "si", &addr_string, &maskbit))
- return 0;
-
- if (maskbit >= dx_bitmask_width() || maskbit < 0) {
- PyErr_SetString(PyExc_Exception, "Router bit mask out of range");
- return 0;
- }
-
- if (router->routers_by_mask_bit[maskbit] == 0) {
- PyErr_SetString(PyExc_Exception, "Router Not Found");
- return 0;
- }
-
- iter = dx_field_iterator_string(addr_string, ITER_VIEW_ADDRESS_HASH);
-
- sys_mutex_lock(router->lock);
- dx_hash_retrieve(router->addr_hash, iter, (void**) &addr);
- if (!addr) {
- addr = new_dx_address_t();
- memset(addr, 0, sizeof(dx_address_t));
- DEQ_ITEM_INIT(addr);
- DEQ_INIT(addr->rlinks);
- DEQ_INIT(addr->rnodes);
- dx_hash_insert(router->addr_hash, iter, addr, &addr->hash_handle);
- DEQ_ITEM_INIT(addr);
- DEQ_INSERT_TAIL(router->addrs, addr);
- }
- dx_field_iterator_free(iter);
-
- dx_router_node_t *rnode = router->routers_by_mask_bit[maskbit];
- dx_router_add_node_ref_LH(&addr->rnodes, rnode);
-
- sys_mutex_unlock(router->lock);
-
- dx_log(module, LOG_DEBUG, "Remote Destination '%s' Mapped to router %d", addr_string, maskbit);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyObject* dx_unmap_destination(PyObject *self, PyObject *args)
-{
- RouterAdapter *adapter = (RouterAdapter*) self;
- dx_router_t *router = adapter->router;
- const char *addr_string;
- int maskbit;
- dx_address_t *addr;
-
- if (!PyArg_ParseTuple(args, "si", &addr_string, &maskbit))
- return 0;
-
- if (maskbit >= dx_bitmask_width() || maskbit < 0) {
- PyErr_SetString(PyExc_Exception, "Router bit mask out of range");
- return 0;
- }
-
- if (router->routers_by_mask_bit[maskbit] == 0) {
- PyErr_SetString(PyExc_Exception, "Router Not Found");
- return 0;
- }
-
- dx_router_node_t *rnode = router->routers_by_mask_bit[maskbit];
- dx_field_iterator_t *iter = dx_field_iterator_string(addr_string, ITER_VIEW_ADDRESS_HASH);
-
- sys_mutex_lock(router->lock);
- dx_hash_retrieve(router->addr_hash, iter, (void**) &addr);
- dx_field_iterator_free(iter);
-
- if (!addr) {
- PyErr_SetString(PyExc_Exception, "Address Not Found");
- sys_mutex_unlock(router->lock);
- return 0;
- }
-
- dx_router_del_node_ref_LH(&addr->rnodes, rnode);
- sys_mutex_unlock(router->lock);
-
- dx_router_check_addr(router, addr, 0);
-
- dx_log(module, LOG_DEBUG, "Remote Destination '%s' Unmapped from router %d", addr_string, maskbit);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-
-static PyMethodDef RouterAdapter_methods[] = {
- {"add_remote_router", dx_add_remote_router, METH_VARARGS, "A new remote/reachable router has been discovered"},
- {"del_remote_router", dx_del_remote_router, METH_VARARGS, "We've lost reachability to a remote router"},
- {"set_next_hop", dx_set_next_hop, METH_VARARGS, "Set the next hop for a remote router"},
- {"set_valid_origins", dx_set_valid_origins, METH_VARARGS, "Set the valid origins for a remote router"},
- {"add_neighbor_router", dx_add_neighbor_router, METH_VARARGS, "A new neighbor router has been discovered"},
- {"del_neighbor_router", dx_del_neighbor_router, METH_VARARGS, "We've lost reachability to a neighbor router"},
- {"map_destination", dx_map_destination, METH_VARARGS, "Add a newly discovered destination mapping"},
- {"unmap_destination", dx_unmap_destination, METH_VARARGS, "Delete a destination mapping"},
- {0, 0, 0, 0}
-};
-
-static PyTypeObject RouterAdapterType = {
- PyObject_HEAD_INIT(0)
- 0, /* ob_size*/
- "dispatch.RouterAdapter", /* tp_name*/
- sizeof(RouterAdapter), /* tp_basicsize*/
- 0, /* tp_itemsize*/
- 0, /* tp_dealloc*/
- 0, /* tp_print*/
- 0, /* tp_getattr*/
- 0, /* tp_setattr*/
- 0, /* tp_compare*/
- 0, /* tp_repr*/
- 0, /* tp_as_number*/
- 0, /* tp_as_sequence*/
- 0, /* tp_as_mapping*/
- 0, /* tp_hash */
- 0, /* tp_call*/
- 0, /* tp_str*/
- 0, /* tp_getattro*/
- 0, /* tp_setattro*/
- 0, /* tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /* tp_flags*/
- "Dispatch Router Adapter", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- RouterAdapter_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
- 0, /* tp_free */
- 0, /* tp_is_gc */
- 0, /* tp_bases */
- 0, /* tp_mro */
- 0, /* tp_cache */
- 0, /* tp_subclasses */
- 0, /* tp_weaklist */
- 0, /* tp_del */
- 0 /* tp_version_tag */
-};
-
-
-void dx_router_python_setup(dx_router_t *router)
-{
- //
- // If we are not operating as an interior router, don't start the
- // router module.
- //
- if (router->router_mode != DX_ROUTER_MODE_INTERIOR)
- return;
-
- PyObject *pDispatchModule = dx_python_module();
-
- RouterAdapterType.tp_new = PyType_GenericNew;
- if (PyType_Ready(&RouterAdapterType) < 0) {
- PyErr_Print();
- dx_log(module, LOG_CRITICAL, "Unable to initialize the Python Router Adapter");
- return;
- }
-
- PyTypeObject *raType = &RouterAdapterType;
- Py_INCREF(raType);
- PyModule_AddObject(pDispatchModule, "RouterAdapter", (PyObject*) &RouterAdapterType);
-
- //
- // Attempt to import the Python Router module
- //
- PyObject* pName;
- PyObject* pId;
- PyObject* pArea;
- PyObject* pMaxRouters;
- PyObject* pModule;
- PyObject* pClass;
- PyObject* pArgs;
-
- pName = PyString_FromString("qpid.dispatch.router");
- pModule = PyImport_Import(pName);
- Py_DECREF(pName);
- if (!pModule) {
- dx_log(module, LOG_CRITICAL, "Can't Locate 'router' Python module");
- return;
- }
-
- pClass = PyObject_GetAttrString(pModule, "RouterEngine");
- if (!pClass || !PyClass_Check(pClass)) {
- dx_log(module, LOG_CRITICAL, "Can't Locate 'RouterEngine' class in the 'router' module");
- return;
- }
-
- PyObject *adapterType = PyObject_GetAttrString(pDispatchModule, "RouterAdapter");
- PyObject *adapterInstance = PyObject_CallObject(adapterType, 0);
- assert(adapterInstance);
-
- ((RouterAdapter*) adapterInstance)->router = router;
-
- //
- // Constructor Arguments for RouterEngine
- //
- pArgs = PyTuple_New(4);
-
- // arg 0: adapter instance
- PyTuple_SetItem(pArgs, 0, adapterInstance);
-
- // arg 1: router_id
- pId = PyString_FromString(router->router_id);
- PyTuple_SetItem(pArgs, 1, pId);
-
- // arg 2: area_id
- pArea = PyString_FromString(router->router_area);
- PyTuple_SetItem(pArgs, 2, pArea);
-
- // arg 3: max_routers
- pMaxRouters = PyInt_FromLong((long) dx_bitmask_width());
- PyTuple_SetItem(pArgs, 3, pMaxRouters);
-
- //
- // Instantiate the router
- //
- router->pyRouter = PyInstance_New(pClass, pArgs, 0);
- Py_DECREF(pArgs);
- Py_DECREF(adapterType);
-
- if (!router->pyRouter) {
- PyErr_Print();
- dx_log(module, LOG_CRITICAL, "'RouterEngine' class cannot be instantiated");
- return;
- }
-
- router->pyTick = PyObject_GetAttrString(router->pyRouter, "handleTimerTick");
- if (!router->pyTick || !PyCallable_Check(router->pyTick)) {
- dx_log(module, LOG_CRITICAL, "'RouterEngine' class has no handleTimerTick method");
- return;
- }
-
- router->pyAdded = PyObject_GetAttrString(router->pyRouter, "addressAdded");
- if (!router->pyAdded || !PyCallable_Check(router->pyAdded)) {
- dx_log(module, LOG_CRITICAL, "'RouterEngine' class has no addressAdded method");
- return;
- }
-
- router->pyRemoved = PyObject_GetAttrString(router->pyRouter, "addressRemoved");
- if (!router->pyRemoved || !PyCallable_Check(router->pyRemoved)) {
- dx_log(module, LOG_CRITICAL, "'RouterEngine' class has no addressRemoved method");
- return;
- }
-}
-
-
-void dx_pyrouter_tick(dx_router_t *router)
-{
- PyObject *pArgs;
- PyObject *pValue;
-
- if (router->pyTick && router->router_mode == DX_ROUTER_MODE_INTERIOR) {
- dx_python_lock();
- pArgs = PyTuple_New(0);
- pValue = PyObject_CallObject(router->pyTick, pArgs);
- if (PyErr_Occurred()) {
- PyErr_Print();
- }
- Py_DECREF(pArgs);
- if (pValue) {
- Py_DECREF(pValue);
- }
- dx_python_unlock();
- }
-}
-
-
-void dx_router_mobile_added(dx_router_t *router, dx_field_iterator_t *iter)
-{
- PyObject *pArgs;
- PyObject *pValue;
-
- if (router->pyAdded && router->router_mode == DX_ROUTER_MODE_INTERIOR) {
- dx_field_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
- char *address = (char*) dx_field_iterator_copy(iter);
-
- dx_python_lock();
- pArgs = PyTuple_New(1);
- PyTuple_SetItem(pArgs, 0, PyString_FromString(address));
- pValue = PyObject_CallObject(router->pyAdded, pArgs);
- if (PyErr_Occurred()) {
- PyErr_Print();
- }
- Py_DECREF(pArgs);
- if (pValue) {
- Py_DECREF(pValue);
- }
- dx_python_unlock();
-
- free(address);
- }
-}
-
-
-void dx_router_mobile_removed(dx_router_t *router, const char *address)
-{
- PyObject *pArgs;
- PyObject *pValue;
-
- if (router->pyRemoved && router->router_mode == DX_ROUTER_MODE_INTERIOR) {
- dx_python_lock();
- pArgs = PyTuple_New(1);
- PyTuple_SetItem(pArgs, 0, PyString_FromString(address));
- pValue = PyObject_CallObject(router->pyRemoved, pArgs);
- if (PyErr_Occurred()) {
- PyErr_Print();
- }
- Py_DECREF(pArgs);
- if (pValue) {
- Py_DECREF(pValue);
- }
- dx_python_unlock();
- }
-}
-
diff --git a/extras/dispatch/src/server.c b/extras/dispatch/src/server.c
deleted file mode 100644
index 65e181bd2c..0000000000
--- a/extras/dispatch/src/server.c
+++ /dev/null
@@ -1,1039 +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/dispatch/ctools.h>
-#include <qpid/dispatch/threading.h>
-#include <qpid/dispatch/log.h>
-#include "server_private.h"
-#include "timer_private.h"
-#include "alloc_private.h"
-#include "dispatch_private.h"
-#include "work_queue.h"
-#include <stdio.h>
-#include <time.h>
-
-static char *module="SERVER";
-static __thread dx_server_t *thread_server = 0;
-
-typedef struct dx_thread_t {
- dx_server_t *dx_server;
- int thread_id;
- volatile int running;
- volatile int canceled;
- int using_thread;
- sys_thread_t *thread;
-} dx_thread_t;
-
-
-struct dx_server_t {
- int thread_count;
- const char *container_name;
- pn_driver_t *driver;
- dx_thread_start_cb_t start_handler;
- dx_conn_handler_cb_t conn_handler;
- dx_user_fd_handler_cb_t ufd_handler;
- void *start_context;
- void *conn_handler_context;
- sys_cond_t *cond;
- sys_mutex_t *lock;
- dx_thread_t **threads;
- work_queue_t *work_queue;
- dx_timer_list_t pending_timers;
- bool a_thread_is_waiting;
- int threads_active;
- int pause_requests;
- int threads_paused;
- int pause_next_sequence;
- int pause_now_serving;
- dx_signal_handler_cb_t signal_handler;
- void *signal_context;
- int pending_signal;
-};
-
-
-
-
-ALLOC_DEFINE(dx_listener_t);
-ALLOC_DEFINE(dx_connector_t);
-ALLOC_DEFINE(dx_connection_t);
-ALLOC_DEFINE(dx_user_fd_t);
-
-
-static dx_thread_t *thread(dx_server_t *dx_server, int id)
-{
- dx_thread_t *thread = NEW(dx_thread_t);
- if (!thread)
- return 0;
-
- thread->dx_server = dx_server;
- thread->thread_id = id;
- thread->running = 0;
- thread->canceled = 0;
- thread->using_thread = 0;
-
- return thread;
-}
-
-
-static void thread_process_listeners(dx_server_t *dx_server)
-{
- pn_driver_t *driver = dx_server->driver;
- pn_listener_t *listener = pn_driver_listener(driver);
- pn_connector_t *cxtr;
- dx_connection_t *ctx;
-
- while (listener) {
- cxtr = pn_listener_accept(listener);
- dx_log(module, LOG_TRACE, "Accepting Connection from %s", pn_connector_name(cxtr));
- ctx = new_dx_connection_t();
- ctx->state = CONN_STATE_OPENING;
- ctx->owner_thread = CONTEXT_NO_OWNER;
- ctx->enqueued = 0;
- ctx->pn_cxtr = cxtr;
- ctx->listener = (dx_listener_t*) pn_listener_context(listener);
- ctx->connector = 0;
- ctx->context = ctx->listener->context;
- ctx->user_context = 0;
- ctx->link_context = 0;
- ctx->ufd = 0;
-
- pn_connection_t *conn = pn_connection();
- pn_connection_set_container(conn, dx_server->container_name);
- pn_connector_set_connection(cxtr, conn);
- pn_connection_set_context(conn, ctx);
- ctx->pn_conn = conn;
-
- //
- // Get a pointer to the transport so we can insert security components into it
- //
- pn_transport_t *tport = pn_connector_transport(cxtr);
- const dx_server_config_t *config = ctx->listener->config;
-
- //
- // Set up SSL if appropriate
- //
- if (config->ssl_enabled) {
- pn_ssl_domain_t *domain = pn_ssl_domain(PN_SSL_MODE_SERVER);
- pn_ssl_domain_set_credentials(domain,
- config->ssl_certificate_file,
- config->ssl_private_key_file,
- config->ssl_password);
- if (config->ssl_allow_unsecured_client)
- pn_ssl_domain_allow_unsecured_client(domain);
-
- if (config->ssl_require_peer_authentication)
- pn_ssl_domain_set_peer_authentication(domain, PN_SSL_VERIFY_PEER_NAME, config->ssl_trusted_certificate_db);
-
- pn_ssl_t *ssl = pn_ssl(tport);
- pn_ssl_init(ssl, domain, 0);
- pn_ssl_domain_free(domain);
- }
-
- //
- // Set up SASL
- //
- pn_sasl_t *sasl = pn_sasl(tport);
- pn_sasl_mechanisms(sasl, config->sasl_mechanisms);
- pn_sasl_server(sasl);
- pn_sasl_done(sasl, PN_SASL_OK); // TODO - This needs to go away
-
- pn_connector_set_context(cxtr, ctx);
- listener = pn_driver_listener(driver);
- }
-}
-
-
-static void handle_signals_LH(dx_server_t *dx_server)
-{
- int signum = dx_server->pending_signal;
-
- if (signum) {
- dx_server->pending_signal = 0;
- if (dx_server->signal_handler) {
- sys_mutex_unlock(dx_server->lock);
- dx_server->signal_handler(dx_server->signal_context, signum);
- sys_mutex_lock(dx_server->lock);
- }
- }
-}
-
-
-static void block_if_paused_LH(dx_server_t *dx_server)
-{
- if (dx_server->pause_requests > 0) {
- dx_server->threads_paused++;
- sys_cond_signal_all(dx_server->cond);
- while (dx_server->pause_requests > 0)
- sys_cond_wait(dx_server->cond, dx_server->lock);
- dx_server->threads_paused--;
- }
-}
-
-
-static int process_connector(dx_server_t *dx_server, pn_connector_t *cxtr)
-{
- dx_connection_t *ctx = pn_connector_context(cxtr);
- int events = 0;
- int passes = 0;
-
- if (ctx->state == CONN_STATE_USER) {
- dx_server->ufd_handler(ctx->ufd->context, ctx->ufd);
- return 1;
- }
-
- do {
- passes++;
-
- //
- // Step the engine for pre-handler processing
- //
- pn_connector_process(cxtr);
-
- //
- // Call the handler that is appropriate for the connector's state.
- //
- switch (ctx->state) {
- case CONN_STATE_CONNECTING: {
- if (pn_connector_closed(cxtr)) {
- ctx->state = CONN_STATE_FAILED;
- events = 0;
- break;
- }
-
- pn_connection_t *conn = pn_connection();
- pn_connection_set_container(conn, dx_server->container_name);
- pn_connector_set_connection(cxtr, conn);
- pn_connection_set_context(conn, ctx);
- ctx->pn_conn = conn;
-
- pn_transport_t *tport = pn_connector_transport(cxtr);
- const dx_server_config_t *config = ctx->connector->config;
-
- //
- // Set up SSL if appropriate
- //
- if (config->ssl_enabled) {
- pn_ssl_domain_t *domain = pn_ssl_domain(PN_SSL_MODE_CLIENT);
- pn_ssl_domain_set_credentials(domain,
- config->ssl_certificate_file,
- config->ssl_private_key_file,
- config->ssl_password);
-
- if (config->ssl_require_peer_authentication)
- pn_ssl_domain_set_peer_authentication(domain, PN_SSL_VERIFY_PEER_NAME, config->ssl_trusted_certificate_db);
-
- pn_ssl_t *ssl = pn_ssl(tport);
- pn_ssl_init(ssl, domain, 0);
- pn_ssl_domain_free(domain);
- }
-
- //
- // Set up SASL
- //
- pn_sasl_t *sasl = pn_sasl(tport);
- pn_sasl_mechanisms(sasl, config->sasl_mechanisms);
- pn_sasl_client(sasl);
-
- ctx->state = CONN_STATE_OPENING;
- assert(ctx->connector);
- ctx->connector->state = CXTR_STATE_OPEN;
- events = 1;
- break;
- }
-
- case CONN_STATE_OPENING: {
- pn_transport_t *tport = pn_connector_transport(cxtr);
- pn_sasl_t *sasl = pn_sasl(tport);
-
- if (pn_sasl_outcome(sasl) == PN_SASL_OK) {
- ctx->state = CONN_STATE_OPERATIONAL;
-
- dx_conn_event_t ce = DX_CONN_EVENT_PROCESS; // Initialize to keep the compiler happy
-
- if (ctx->listener) {
- ce = DX_CONN_EVENT_LISTENER_OPEN;
- } else if (ctx->connector) {
- ce = DX_CONN_EVENT_CONNECTOR_OPEN;
- ctx->connector->delay = 0;
- } else
- assert(0);
-
- dx_server->conn_handler(dx_server->conn_handler_context,
- ctx->context, ce, (dx_connection_t*) pn_connector_context(cxtr));
- events = 1;
- break;
- }
- else if (pn_sasl_outcome(sasl) != PN_SASL_NONE) {
- ctx->state = CONN_STATE_FAILED;
- if (ctx->connector) {
- const dx_server_config_t *config = ctx->connector->config;
- dx_log(module, LOG_TRACE, "Connection to %s:%s failed", config->host, config->port);
- }
- }
- }
-
- case CONN_STATE_OPERATIONAL:
- if (pn_connector_closed(cxtr)) {
- dx_server->conn_handler(dx_server->conn_handler_context, ctx->context,
- DX_CONN_EVENT_CLOSE,
- (dx_connection_t*) pn_connector_context(cxtr));
- events = 0;
- }
- else
- events = dx_server->conn_handler(dx_server->conn_handler_context, ctx->context,
- DX_CONN_EVENT_PROCESS,
- (dx_connection_t*) pn_connector_context(cxtr));
- break;
-
- default:
- break;
- }
- } while (events > 0);
-
- return passes > 1;
-}
-
-
-//
-// TEMPORARY FUNCTION PROTOTYPES
-//
-void pn_driver_wait_1(pn_driver_t *d);
-int pn_driver_wait_2(pn_driver_t *d, int timeout);
-void pn_driver_wait_3(pn_driver_t *d);
-//
-// END TEMPORARY
-//
-
-static void *thread_run(void *arg)
-{
- dx_thread_t *thread = (dx_thread_t*) arg;
- dx_server_t *dx_server = thread->dx_server;
- pn_connector_t *work;
- pn_connection_t *conn;
- dx_connection_t *ctx;
- int error;
- int poll_result;
-
- if (!thread)
- return 0;
-
- thread_server = dx_server;
- thread->running = 1;
-
- if (thread->canceled)
- return 0;
-
- //
- // Invoke the start handler if the application supplied one.
- // This handler can be used to set NUMA or processor affinnity for the thread.
- //
- if (dx_server->start_handler)
- dx_server->start_handler(dx_server->start_context, thread->thread_id);
-
- //
- // Main Loop
- //
- while (thread->running) {
- sys_mutex_lock(dx_server->lock);
-
- //
- // Check for pending signals to process
- //
- handle_signals_LH(dx_server);
- if (!thread->running) {
- sys_mutex_unlock(dx_server->lock);
- break;
- }
-
- //
- // Check to see if the server is pausing. If so, block here.
- //
- block_if_paused_LH(dx_server);
- if (!thread->running) {
- sys_mutex_unlock(dx_server->lock);
- break;
- }
-
- //
- // Service pending timers.
- //
- dx_timer_t *timer = DEQ_HEAD(dx_server->pending_timers);
- if (timer) {
- DEQ_REMOVE_HEAD(dx_server->pending_timers);
-
- //
- // Mark the timer as idle in case it reschedules itself.
- //
- dx_timer_idle_LH(timer);
-
- //
- // Release the lock and invoke the connection handler.
- //
- sys_mutex_unlock(dx_server->lock);
- timer->handler(timer->context);
- pn_driver_wakeup(dx_server->driver);
- continue;
- }
-
- //
- // Check the work queue for connectors scheduled for processing.
- //
- work = work_queue_get(dx_server->work_queue);
- if (!work) {
- //
- // There is no pending work to do
- //
- if (dx_server->a_thread_is_waiting) {
- //
- // Another thread is waiting on the proton driver, this thread must
- // wait on the condition variable until signaled.
- //
- sys_cond_wait(dx_server->cond, dx_server->lock);
- } else {
- //
- // This thread elects itself to wait on the proton driver. Set the
- // thread-is-waiting flag so other idle threads will not interfere.
- //
- dx_server->a_thread_is_waiting = true;
-
- //
- // Ask the timer module when its next timer is scheduled to fire. We'll
- // use this value in driver_wait as the timeout. If there are no scheduled
- // timers, the returned value will be -1.
- //
- long duration = dx_timer_next_duration_LH();
-
- //
- // Invoke the proton driver's wait sequence. This is a bit of a hack for now
- // and will be improved in the future. The wait process is divided into three parts,
- // the first and third of which need to be non-reentrant, and the second of which
- // must be reentrant (and blocks).
- //
- pn_driver_wait_1(dx_server->driver);
- sys_mutex_unlock(dx_server->lock);
-
- do {
- error = 0;
- poll_result = pn_driver_wait_2(dx_server->driver, duration);
- if (poll_result == -1)
- error = pn_driver_errno(dx_server->driver);
- } while (error == PN_INTR);
- if (error) {
- dx_log(module, LOG_ERROR, "Driver Error: %s", pn_error_text(pn_error(dx_server->driver)));
- exit(-1);
- }
-
- sys_mutex_lock(dx_server->lock);
- pn_driver_wait_3(dx_server->driver);
-
- if (!thread->running) {
- sys_mutex_unlock(dx_server->lock);
- break;
- }
-
- //
- // Visit the timer module.
- //
- struct timespec tv;
- clock_gettime(CLOCK_REALTIME, &tv);
- long milliseconds = tv.tv_sec * 1000 + tv.tv_nsec / 1000000;
- dx_timer_visit_LH(milliseconds);
-
- //
- // Process listeners (incoming connections).
- //
- thread_process_listeners(dx_server);
-
- //
- // Traverse the list of connectors-needing-service from the proton driver.
- // If the connector is not already in the work queue and it is not currently
- // being processed by another thread, put it in the work queue and signal the
- // condition variable.
- //
- work = pn_driver_connector(dx_server->driver);
- while (work) {
- ctx = pn_connector_context(work);
- if (!ctx->enqueued && ctx->owner_thread == CONTEXT_NO_OWNER) {
- ctx->enqueued = 1;
- work_queue_put(dx_server->work_queue, work);
- sys_cond_signal(dx_server->cond);
- }
- work = pn_driver_connector(dx_server->driver);
- }
-
- //
- // Release our exclusive claim on pn_driver_wait.
- //
- dx_server->a_thread_is_waiting = false;
- }
- }
-
- //
- // If we were given a connector to work on from the work queue, mark it as
- // owned by this thread and as no longer enqueued.
- //
- if (work) {
- ctx = pn_connector_context(work);
- if (ctx->owner_thread == CONTEXT_NO_OWNER) {
- ctx->owner_thread = thread->thread_id;
- ctx->enqueued = 0;
- dx_server->threads_active++;
- } else {
- //
- // This connector is being processed by another thread, re-queue it.
- //
- work_queue_put(dx_server->work_queue, work);
- work = 0;
- }
- }
- sys_mutex_unlock(dx_server->lock);
-
- //
- // Process the connector that we now have exclusive access to.
- //
- if (work) {
- int work_done = process_connector(dx_server, work);
-
- //
- // Check to see if the connector was closed during processing
- //
- if (pn_connector_closed(work)) {
- //
- // Connector is closed. Free the context and the connector.
- //
- conn = pn_connector_connection(work);
-
- //
- // If this is a dispatch connector, schedule the re-connect timer
- //
- if (ctx->connector) {
- ctx->connector->ctx = 0;
- ctx->connector->state = CXTR_STATE_CONNECTING;
- dx_timer_schedule(ctx->connector->timer, ctx->connector->delay);
- }
-
- sys_mutex_lock(dx_server->lock);
- free_dx_connection_t(ctx);
- pn_connector_free(work);
- if (conn)
- pn_connection_free(conn);
- dx_server->threads_active--;
- sys_mutex_unlock(dx_server->lock);
- } else {
- //
- // The connector lives on. Mark it as no longer owned by this thread.
- //
- sys_mutex_lock(dx_server->lock);
- ctx->owner_thread = CONTEXT_NO_OWNER;
- dx_server->threads_active--;
- sys_mutex_unlock(dx_server->lock);
- }
-
- //
- // Wake up the proton driver to force it to reconsider its set of FDs
- // in light of the processing that just occurred.
- //
- if (work_done)
- pn_driver_wakeup(dx_server->driver);
- }
- }
-
- return 0;
-}
-
-
-static void thread_start(dx_thread_t *thread)
-{
- if (!thread)
- return;
-
- thread->using_thread = 1;
- thread->thread = sys_thread(thread_run, (void*) thread);
-}
-
-
-static void thread_cancel(dx_thread_t *thread)
-{
- if (!thread)
- return;
-
- thread->running = 0;
- thread->canceled = 1;
-}
-
-
-static void thread_join(dx_thread_t *thread)
-{
- if (!thread)
- return;
-
- if (thread->using_thread)
- sys_thread_join(thread->thread);
-}
-
-
-static void thread_free(dx_thread_t *thread)
-{
- if (!thread)
- return;
-
- free(thread);
-}
-
-
-static void cxtr_try_open(void *context)
-{
- dx_connector_t *ct = (dx_connector_t*) context;
- if (ct->state != CXTR_STATE_CONNECTING)
- return;
-
- dx_connection_t *ctx = new_dx_connection_t();
- ctx->server = ct->server;
- ctx->state = CONN_STATE_CONNECTING;
- ctx->owner_thread = CONTEXT_NO_OWNER;
- ctx->enqueued = 0;
- ctx->pn_conn = 0;
- ctx->listener = 0;
- ctx->connector = ct;
- ctx->context = ct->context;
- ctx->user_context = 0;
- ctx->link_context = 0;
- ctx->ufd = 0;
-
- //
- // pn_connector is not thread safe
- //
- sys_mutex_lock(ct->server->lock);
- ctx->pn_cxtr = pn_connector(ct->server->driver, ct->config->host, ct->config->port, (void*) ctx);
- sys_mutex_unlock(ct->server->lock);
-
- ct->ctx = ctx;
- ct->delay = 5000;
- dx_log(module, LOG_TRACE, "Connecting to %s:%s", ct->config->host, ct->config->port);
-}
-
-
-dx_server_t *dx_server(int thread_count, const char *container_name)
-{
- int i;
-
- dx_server_t *dx_server = NEW(dx_server_t);
- if (dx_server == 0)
- return 0;
-
- dx_server->thread_count = thread_count;
- dx_server->container_name = container_name;
- dx_server->driver = pn_driver();
- dx_server->start_handler = 0;
- dx_server->conn_handler = 0;
- dx_server->signal_handler = 0;
- dx_server->ufd_handler = 0;
- dx_server->start_context = 0;
- dx_server->signal_context = 0;
- dx_server->lock = sys_mutex();
- dx_server->cond = sys_cond();
-
- dx_timer_initialize(dx_server->lock);
-
- dx_server->threads = NEW_PTR_ARRAY(dx_thread_t, thread_count);
- for (i = 0; i < thread_count; i++)
- dx_server->threads[i] = thread(dx_server, i);
-
- dx_server->work_queue = work_queue();
- DEQ_INIT(dx_server->pending_timers);
- dx_server->a_thread_is_waiting = false;
- dx_server->threads_active = 0;
- dx_server->pause_requests = 0;
- dx_server->threads_paused = 0;
- dx_server->pause_next_sequence = 0;
- dx_server->pause_now_serving = 0;
- dx_server->pending_signal = 0;
-
- dx_log(module, LOG_INFO, "Container Name: %s", dx_server->container_name);
-
- return dx_server;
-}
-
-
-void dx_server_setup_agent(dx_dispatch_t *dx)
-{
- // TODO
-}
-
-
-void dx_server_free(dx_server_t *dx_server)
-{
- int i;
- if (!dx_server)
- return;
-
- for (i = 0; i < dx_server->thread_count; i++)
- thread_free(dx_server->threads[i]);
-
- work_queue_free(dx_server->work_queue);
-
- pn_driver_free(dx_server->driver);
- sys_mutex_free(dx_server->lock);
- sys_cond_free(dx_server->cond);
- free(dx_server);
-}
-
-
-void dx_server_set_conn_handler(dx_dispatch_t *dx, dx_conn_handler_cb_t handler, void *handler_context)
-{
- dx->server->conn_handler = handler;
- dx->server->conn_handler_context = handler_context;
-}
-
-
-void dx_server_set_signal_handler(dx_dispatch_t *dx, dx_signal_handler_cb_t handler, void *context)
-{
- dx->server->signal_handler = handler;
- dx->server->signal_context = context;
-}
-
-
-void dx_server_set_start_handler(dx_dispatch_t *dx, dx_thread_start_cb_t handler, void *context)
-{
- dx->server->start_handler = handler;
- dx->server->start_context = context;
-}
-
-
-void dx_server_set_user_fd_handler(dx_dispatch_t *dx, dx_user_fd_handler_cb_t ufd_handler)
-{
- dx->server->ufd_handler = ufd_handler;
-}
-
-
-void dx_server_run(dx_dispatch_t *dx)
-{
- dx_server_t *dx_server = dx->server;
-
- int i;
- if (!dx_server)
- return;
-
- assert(dx_server->conn_handler); // Server can't run without a connection handler.
-
- for (i = 1; i < dx_server->thread_count; i++)
- thread_start(dx_server->threads[i]);
-
- dx_log(module, LOG_INFO, "Operational, %d Threads Running", dx_server->thread_count);
-
- thread_run((void*) dx_server->threads[0]);
-
- for (i = 1; i < dx_server->thread_count; i++)
- thread_join(dx_server->threads[i]);
-
- dx_log(module, LOG_INFO, "Shut Down");
-}
-
-
-void dx_server_start(dx_dispatch_t *dx)
-{
- dx_server_t *dx_server = dx->server;
- int i;
-
- if (!dx_server)
- return;
-
- assert(dx_server->conn_handler); // Server can't run without a connection handler.
-
- for (i = 0; i < dx_server->thread_count; i++)
- thread_start(dx_server->threads[i]);
-
- dx_log(module, LOG_INFO, "Operational, %d Threads Running", dx_server->thread_count);
-}
-
-
-void dx_server_stop(dx_dispatch_t *dx)
-{
- dx_server_t *dx_server = dx->server;
- int idx;
-
- sys_mutex_lock(dx_server->lock);
- for (idx = 0; idx < dx_server->thread_count; idx++)
- thread_cancel(dx_server->threads[idx]);
- sys_cond_signal_all(dx_server->cond);
- pn_driver_wakeup(dx_server->driver);
- sys_mutex_unlock(dx_server->lock);
-
- if (thread_server != dx_server) {
- for (idx = 0; idx < dx_server->thread_count; idx++)
- thread_join(dx_server->threads[idx]);
- dx_log(module, LOG_INFO, "Shut Down");
- }
-}
-
-
-void dx_server_signal(dx_dispatch_t *dx, int signum)
-{
- dx_server_t *dx_server = dx->server;
-
- dx_server->pending_signal = signum;
- sys_cond_signal_all(dx_server->cond);
- pn_driver_wakeup(dx_server->driver);
-}
-
-
-void dx_server_pause(dx_dispatch_t *dx)
-{
- dx_server_t *dx_server = dx->server;
-
- sys_mutex_lock(dx_server->lock);
-
- //
- // Bump the request count to stop all the threads.
- //
- dx_server->pause_requests++;
- int my_sequence = dx_server->pause_next_sequence++;
-
- //
- // Awaken all threads that are currently blocking.
- //
- sys_cond_signal_all(dx_server->cond);
- pn_driver_wakeup(dx_server->driver);
-
- //
- // Wait for the paused thread count plus the number of threads requesting a pause to equal
- // the total thread count. Also, don't exit the blocking loop until now_serving equals our
- // sequence number. This ensures that concurrent pausers don't run at the same time.
- //
- while ((dx_server->threads_paused + dx_server->pause_requests < dx_server->thread_count) ||
- (my_sequence != dx_server->pause_now_serving))
- sys_cond_wait(dx_server->cond, dx_server->lock);
-
- sys_mutex_unlock(dx_server->lock);
-}
-
-
-void dx_server_resume(dx_dispatch_t *dx)
-{
- dx_server_t *dx_server = dx->server;
-
- sys_mutex_lock(dx_server->lock);
- dx_server->pause_requests--;
- dx_server->pause_now_serving++;
- sys_cond_signal_all(dx_server->cond);
- sys_mutex_unlock(dx_server->lock);
-}
-
-
-void dx_server_activate(dx_connection_t *ctx)
-{
- if (!ctx)
- return;
-
- pn_connector_t *ctor = ctx->pn_cxtr;
- if (!ctor)
- return;
-
- if (!pn_connector_closed(ctor))
- pn_connector_activate(ctor, PN_CONNECTOR_WRITABLE);
-}
-
-
-void dx_connection_set_context(dx_connection_t *conn, void *context)
-{
- conn->user_context = context;
-}
-
-
-void *dx_connection_get_context(dx_connection_t *conn)
-{
- return conn->user_context;
-}
-
-
-void dx_connection_set_link_context(dx_connection_t *conn, void *context)
-{
- conn->link_context = context;
-}
-
-
-void *dx_connection_get_link_context(dx_connection_t *conn)
-{
- return conn->link_context;
-}
-
-
-pn_connection_t *dx_connection_pn(dx_connection_t *conn)
-{
- return conn->pn_conn;
-}
-
-
-const dx_server_config_t *dx_connection_config(const dx_connection_t *conn)
-{
- if (conn->listener)
- return conn->listener->config;
- return conn->connector->config;
-}
-
-
-dx_listener_t *dx_server_listen(dx_dispatch_t *dx, const dx_server_config_t *config, void *context)
-{
- dx_server_t *dx_server = dx->server;
- dx_listener_t *li = new_dx_listener_t();
-
- if (!li)
- return 0;
-
- li->server = dx_server;
- li->config = config;
- li->context = context;
- li->pn_listener = pn_listener(dx_server->driver, config->host, config->port, (void*) li);
-
- if (!li->pn_listener) {
- dx_log(module, LOG_ERROR, "Driver Error %d (%s)",
- pn_driver_errno(dx_server->driver), pn_driver_error(dx_server->driver));
- free_dx_listener_t(li);
- return 0;
- }
- dx_log(module, LOG_TRACE, "Listening on %s:%s", config->host, config->port);
-
- return li;
-}
-
-
-void dx_server_listener_free(dx_listener_t* li)
-{
- pn_listener_free(li->pn_listener);
- free_dx_listener_t(li);
-}
-
-
-void dx_server_listener_close(dx_listener_t* li)
-{
- pn_listener_close(li->pn_listener);
-}
-
-
-dx_connector_t *dx_server_connect(dx_dispatch_t *dx, const dx_server_config_t *config, void *context)
-{
- dx_server_t *dx_server = dx->server;
- dx_connector_t *ct = new_dx_connector_t();
-
- if (!ct)
- return 0;
-
- ct->server = dx_server;
- ct->state = CXTR_STATE_CONNECTING;
- ct->config = config;
- ct->context = context;
- ct->ctx = 0;
- ct->timer = dx_timer(dx, cxtr_try_open, (void*) ct);
- ct->delay = 0;
-
- dx_timer_schedule(ct->timer, ct->delay);
- return ct;
-}
-
-
-void dx_server_connector_free(dx_connector_t* ct)
-{
- // Don't free the proton connector. This will be done by the connector
- // processing/cleanup.
-
- if (ct->ctx) {
- pn_connector_close(ct->ctx->pn_cxtr);
- ct->ctx->connector = 0;
- }
-
- dx_timer_free(ct->timer);
- free_dx_connector_t(ct);
-}
-
-
-dx_user_fd_t *dx_user_fd(dx_dispatch_t *dx, int fd, void *context)
-{
- dx_server_t *dx_server = dx->server;
- dx_user_fd_t *ufd = new_dx_user_fd_t();
-
- if (!ufd)
- return 0;
-
- dx_connection_t *ctx = new_dx_connection_t();
- ctx->server = dx_server;
- ctx->state = CONN_STATE_USER;
- ctx->owner_thread = CONTEXT_NO_OWNER;
- ctx->enqueued = 0;
- ctx->pn_conn = 0;
- ctx->listener = 0;
- ctx->connector = 0;
- ctx->context = 0;
- ctx->user_context = 0;
- ctx->link_context = 0;
- ctx->ufd = ufd;
-
- ufd->context = context;
- ufd->server = dx_server;
- ufd->fd = fd;
- ufd->pn_conn = pn_connector_fd(dx_server->driver, fd, (void*) ctx);
- pn_driver_wakeup(dx_server->driver);
-
- return ufd;
-}
-
-
-void dx_user_fd_free(dx_user_fd_t *ufd)
-{
- pn_connector_close(ufd->pn_conn);
- free_dx_user_fd_t(ufd);
-}
-
-
-void dx_user_fd_activate_read(dx_user_fd_t *ufd)
-{
- pn_connector_activate(ufd->pn_conn, PN_CONNECTOR_READABLE);
- pn_driver_wakeup(ufd->server->driver);
-}
-
-
-void dx_user_fd_activate_write(dx_user_fd_t *ufd)
-{
- pn_connector_activate(ufd->pn_conn, PN_CONNECTOR_WRITABLE);
- pn_driver_wakeup(ufd->server->driver);
-}
-
-
-bool dx_user_fd_is_readable(dx_user_fd_t *ufd)
-{
- return pn_connector_activated(ufd->pn_conn, PN_CONNECTOR_READABLE);
-}
-
-
-bool dx_user_fd_is_writeable(dx_user_fd_t *ufd)
-{
- return pn_connector_activated(ufd->pn_conn, PN_CONNECTOR_WRITABLE);
-}
-
-
-void dx_server_timer_pending_LH(dx_timer_t *timer)
-{
- DEQ_INSERT_TAIL(timer->server->pending_timers, timer);
-}
-
-
-void dx_server_timer_cancel_LH(dx_timer_t *timer)
-{
- DEQ_REMOVE(timer->server->pending_timers, timer);
-}
-
diff --git a/extras/dispatch/src/server_private.h b/extras/dispatch/src/server_private.h
deleted file mode 100644
index 86a3ef98f1..0000000000
--- a/extras/dispatch/src/server_private.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef __server_private_h__
-#define __server_private_h__ 1
-/*
- * 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/dispatch/server.h>
-#include <qpid/dispatch/user_fd.h>
-#include <qpid/dispatch/timer.h>
-#include <qpid/dispatch/alloc.h>
-#include <proton/driver.h>
-#include <proton/driver_extras.h>
-
-void dx_server_timer_pending_LH(dx_timer_t *timer);
-void dx_server_timer_cancel_LH(dx_timer_t *timer);
-
-
-typedef enum {
- CONN_STATE_CONNECTING = 0,
- CONN_STATE_OPENING,
- CONN_STATE_OPERATIONAL,
- CONN_STATE_FAILED,
- CONN_STATE_USER
-} conn_state_t;
-
-#define CONTEXT_NO_OWNER -1
-
-typedef enum {
- CXTR_STATE_CONNECTING = 0,
- CXTR_STATE_OPEN,
- CXTR_STATE_FAILED
-} cxtr_state_t;
-
-typedef struct dx_server_t dx_server_t;
-
-struct dx_listener_t {
- dx_server_t *server;
- const dx_server_config_t *config;
- void *context;
- pn_listener_t *pn_listener;
-};
-
-
-struct dx_connector_t {
- dx_server_t *server;
- cxtr_state_t state;
- const dx_server_config_t *config;
- void *context;
- dx_connection_t *ctx;
- dx_timer_t *timer;
- long delay;
-};
-
-
-struct dx_connection_t {
- dx_server_t *server;
- conn_state_t state;
- int owner_thread;
- int enqueued;
- pn_connector_t *pn_cxtr;
- pn_connection_t *pn_conn;
- dx_listener_t *listener;
- dx_connector_t *connector;
- void *context; // Copy of context from listener or connector
- void *user_context;
- void *link_context; // Context shared by this connection's links
- dx_user_fd_t *ufd;
-};
-
-
-struct dx_user_fd_t {
- dx_server_t *server;
- void *context;
- int fd;
- pn_connector_t *pn_conn;
-};
-
-
-ALLOC_DECLARE(dx_listener_t);
-ALLOC_DECLARE(dx_connector_t);
-ALLOC_DECLARE(dx_connection_t);
-ALLOC_DECLARE(dx_user_fd_t);
-
-
-#endif
diff --git a/extras/dispatch/src/timer.c b/extras/dispatch/src/timer.c
deleted file mode 100644
index a7f36e149b..0000000000
--- a/extras/dispatch/src/timer.c
+++ /dev/null
@@ -1,239 +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 "timer_private.h"
-#include "server_private.h"
-#include "dispatch_private.h"
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/threading.h>
-#include <qpid/dispatch/alloc.h>
-#include <assert.h>
-#include <stdio.h>
-
-static sys_mutex_t *lock;
-static dx_timer_list_t idle_timers;
-static dx_timer_list_t scheduled_timers;
-static long time_base;
-
-ALLOC_DECLARE(dx_timer_t);
-ALLOC_DEFINE(dx_timer_t);
-
-//=========================================================================
-// Private static functions
-//=========================================================================
-
-static void dx_timer_cancel_LH(dx_timer_t *timer)
-{
- switch (timer->state) {
- case TIMER_FREE:
- assert(0);
- break;
-
- case TIMER_IDLE:
- break;
-
- case TIMER_SCHEDULED:
- if (timer->next)
- timer->next->delta_time += timer->delta_time;
- DEQ_REMOVE(scheduled_timers, timer);
- DEQ_INSERT_TAIL(idle_timers, timer);
- break;
-
- case TIMER_PENDING:
- dx_server_timer_cancel_LH(timer);
- DEQ_INSERT_TAIL(idle_timers, timer);
- break;
- }
-
- timer->state = TIMER_IDLE;
-}
-
-
-//=========================================================================
-// Public Functions from timer.h
-//=========================================================================
-
-dx_timer_t *dx_timer(dx_dispatch_t *dx, dx_timer_cb_t cb, void* context)
-{
- dx_timer_t *timer = new_dx_timer_t();
- if (!timer)
- return 0;
-
- DEQ_ITEM_INIT(timer);
-
- timer->server = dx ? dx->server : 0;
- timer->handler = cb;
- timer->context = context;
- timer->delta_time = 0;
- timer->state = TIMER_IDLE;
-
- sys_mutex_lock(lock);
- DEQ_INSERT_TAIL(idle_timers, timer);
- sys_mutex_unlock(lock);
-
- return timer;
-}
-
-
-void dx_timer_free(dx_timer_t *timer)
-{
- sys_mutex_lock(lock);
- dx_timer_cancel_LH(timer);
- DEQ_REMOVE(idle_timers, timer);
- sys_mutex_unlock(lock);
-
- timer->state = TIMER_FREE;
- free_dx_timer_t(timer);
-}
-
-
-void dx_timer_schedule(dx_timer_t *timer, long duration)
-{
- dx_timer_t *ptr;
- dx_timer_t *last;
- long total_time;
-
- sys_mutex_lock(lock);
- dx_timer_cancel_LH(timer); // Timer is now on the idle list
- assert(timer->state == TIMER_IDLE);
- DEQ_REMOVE(idle_timers, timer);
-
- //
- // Handle the special case of a zero-time scheduling. In this case,
- // the timer doesn't go on the scheduled list. It goes straight to the
- // pending list in the server.
- //
- if (duration == 0) {
- timer->state = TIMER_PENDING;
- dx_server_timer_pending_LH(timer);
- sys_mutex_unlock(lock);
- return;
- }
-
- //
- // Find the insert point in the schedule.
- //
- total_time = 0;
- ptr = DEQ_HEAD(scheduled_timers);
- assert(!ptr || ptr->prev == 0);
- while (ptr) {
- total_time += ptr->delta_time;
- if (total_time > duration)
- break;
- ptr = ptr->next;
- }
-
- //
- // Insert the timer into the schedule and adjust the delta time
- // of the following timer if present.
- //
- if (total_time <= duration) {
- assert(ptr == 0);
- timer->delta_time = duration - total_time;
- DEQ_INSERT_TAIL(scheduled_timers, timer);
- } else {
- total_time -= ptr->delta_time;
- timer->delta_time = duration - total_time;
- assert(ptr->delta_time > timer->delta_time);
- ptr->delta_time -= timer->delta_time;
- last = ptr->prev;
- if (last)
- DEQ_INSERT_AFTER(scheduled_timers, timer, last);
- else
- DEQ_INSERT_HEAD(scheduled_timers, timer);
- }
-
- timer->state = TIMER_SCHEDULED;
-
- sys_mutex_unlock(lock);
-}
-
-
-void dx_timer_cancel(dx_timer_t *timer)
-{
- sys_mutex_lock(lock);
- dx_timer_cancel_LH(timer);
- sys_mutex_unlock(lock);
-}
-
-
-//=========================================================================
-// Private Functions from timer_private.h
-//=========================================================================
-
-void dx_timer_initialize(sys_mutex_t *server_lock)
-{
- lock = server_lock;
- DEQ_INIT(idle_timers);
- DEQ_INIT(scheduled_timers);
- time_base = 0;
-}
-
-
-void dx_timer_finalize(void)
-{
- lock = 0;
-}
-
-
-long dx_timer_next_duration_LH(void)
-{
- dx_timer_t *timer = DEQ_HEAD(scheduled_timers);
- if (timer)
- return timer->delta_time;
- return -1;
-}
-
-
-void dx_timer_visit_LH(long current_time)
-{
- long delta;
- dx_timer_t *timer = DEQ_HEAD(scheduled_timers);
-
- if (time_base == 0) {
- time_base = current_time;
- return;
- }
-
- delta = current_time - time_base;
- time_base = current_time;
-
- while (timer) {
- assert(delta >= 0);
- if (timer->delta_time > delta) {
- timer->delta_time -= delta;
- break;
- } else {
- DEQ_REMOVE_HEAD(scheduled_timers);
- delta -= timer->delta_time;
- timer->state = TIMER_PENDING;
- dx_server_timer_pending_LH(timer);
-
- }
- timer = DEQ_HEAD(scheduled_timers);
- }
-}
-
-
-void dx_timer_idle_LH(dx_timer_t *timer)
-{
- timer->state = TIMER_IDLE;
- DEQ_INSERT_TAIL(idle_timers, timer);
-}
-
diff --git a/extras/dispatch/src/timer_private.h b/extras/dispatch/src/timer_private.h
deleted file mode 100644
index 4e173b7ad4..0000000000
--- a/extras/dispatch/src/timer_private.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __timer_private_h__
-#define __timer_private_h__ 1
-/*
- * 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/dispatch/ctools.h>
-#include <qpid/dispatch/timer.h>
-#include <qpid/dispatch/threading.h>
-#include "server_private.h"
-
-typedef enum {
- TIMER_FREE,
- TIMER_IDLE,
- TIMER_SCHEDULED,
- TIMER_PENDING
-} dx_timer_state_t;
-
-
-struct dx_timer_t {
- DEQ_LINKS(dx_timer_t);
- dx_server_t *server;
- dx_timer_cb_t handler;
- void *context;
- long delta_time;
- dx_timer_state_t state;
-};
-
-DEQ_DECLARE(dx_timer_t, dx_timer_list_t);
-
-void dx_timer_initialize(sys_mutex_t *server_lock);
-void dx_timer_finalize(void);
-long dx_timer_next_duration_LH(void);
-void dx_timer_visit_LH(long current_time);
-void dx_timer_idle_LH(dx_timer_t *timer);
-
-
-#endif
diff --git a/extras/dispatch/src/work_queue.c b/extras/dispatch/src/work_queue.c
deleted file mode 100644
index 93c1cda1a9..0000000000
--- a/extras/dispatch/src/work_queue.c
+++ /dev/null
@@ -1,132 +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/dispatch/ctools.h>
-#include "work_queue.h"
-#include <string.h>
-#include <stdio.h>
-
-#define BATCH_SIZE 100
-typedef struct work_item_t work_item_t;
-
-struct work_item_t {
- DEQ_LINKS(work_item_t);
- pn_connector_t *conn;
-};
-
-DEQ_DECLARE(work_item_t, work_list_t);
-
-struct work_queue_t {
- work_list_t items;
- work_list_t free_list;
-};
-
-static void allocate_batch(work_queue_t *w)
-{
- int i;
- work_item_t *batch = NEW_ARRAY(work_item_t, BATCH_SIZE);
- if (!batch)
- return;
-
- memset(batch, 0, sizeof(work_item_t) * BATCH_SIZE);
-
- for (i = 0; i < BATCH_SIZE; i++)
- DEQ_INSERT_TAIL(w->free_list, &batch[i]);
-}
-
-
-work_queue_t *work_queue(void)
-{
- work_queue_t *w = NEW(work_queue_t);
- if (!w)
- return 0;
-
- DEQ_INIT(w->items);
- DEQ_INIT(w->free_list);
-
- allocate_batch(w);
-
- return w;
-}
-
-
-void work_queue_free(work_queue_t *w)
-{
- if (!w)
- return;
-
- // KEEP TRACK OF BATCHES AND FREE
- free(w);
-}
-
-
-void work_queue_put(work_queue_t *w, pn_connector_t *conn)
-{
- work_item_t *item;
-
- if (!w)
- return;
- if (DEQ_SIZE(w->free_list) == 0)
- allocate_batch(w);
- if (DEQ_SIZE(w->free_list) == 0)
- return;
-
- item = DEQ_HEAD(w->free_list);
- DEQ_REMOVE_HEAD(w->free_list);
-
- item->conn = conn;
-
- DEQ_INSERT_TAIL(w->items, item);
-}
-
-
-pn_connector_t *work_queue_get(work_queue_t *w)
-{
- work_item_t *item;
- pn_connector_t *conn;
-
- if (!w)
- return 0;
- item = DEQ_HEAD(w->items);
- if (!item)
- return 0;
-
- DEQ_REMOVE_HEAD(w->items);
- conn = item->conn;
- item->conn = 0;
-
- DEQ_INSERT_TAIL(w->free_list, item);
-
- return conn;
-}
-
-
-int work_queue_empty(work_queue_t *w)
-{
- return !w || DEQ_SIZE(w->items) == 0;
-}
-
-
-int work_queue_depth(work_queue_t *w)
-{
- if (!w)
- return 0;
- return DEQ_SIZE(w->items);
-}
-
diff --git a/extras/dispatch/src/work_queue.h b/extras/dispatch/src/work_queue.h
deleted file mode 100644
index 3ad5c21c81..0000000000
--- a/extras/dispatch/src/work_queue.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef __work_queue_h__
-#define __work_queue_h__ 1
-/*
- * 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 <proton/driver.h>
-
-typedef struct work_queue_t work_queue_t;
-
-work_queue_t *work_queue(void);
-void work_queue_free(work_queue_t *w);
-void work_queue_put(work_queue_t *w, pn_connector_t *conn);
-pn_connector_t *work_queue_get(work_queue_t *w);
-int work_queue_empty(work_queue_t *w);
-int work_queue_depth(work_queue_t *w);
-
-#endif
diff --git a/extras/dispatch/tests/CMakeLists.txt b/extras/dispatch/tests/CMakeLists.txt
deleted file mode 100644
index fc85018991..0000000000
--- a/extras/dispatch/tests/CMakeLists.txt
+++ /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.
-##
-
-##
-## Build test applications
-##
-set(unit_test_SOURCES
- alloc_test.c
- compose_test.c
- parse_test.c
- run_unit_tests.c
- server_test.c
- timer_test.c
- tool_test.c
- )
-
-add_executable(unit_tests ${unit_test_SOURCES})
-target_link_libraries(unit_tests qpid-dispatch)
-
-set(unit_test_size_SOURCES
- field_test.c
- message_test.c
- run_unit_tests_size.c
- )
-
-add_executable(unit_tests_size ${unit_test_size_SOURCES})
-target_link_libraries(unit_tests_size qpid-dispatch)
-
-add_test(unit_tests_size_10000 unit_tests_size 10000)
-add_test(unit_tests_size_512 unit_tests_size 512)
-add_test(unit_tests_size_10 unit_tests_size 10)
-add_test(unit_tests_size_7 unit_tests_size 7)
-add_test(unit_tests_size_5 unit_tests_size 5)
-add_test(unit_tests_size_3 unit_tests_size 3)
-add_test(unit_tests_size_2 unit_tests_size 2)
-add_test(unit_tests_size_1 unit_tests_size 1)
-add_test(unit_tests unit_tests ${CMAKE_CURRENT_SOURCE_DIR}/threads4.conf)
-add_test(router_tests python ${CMAKE_CURRENT_SOURCE_DIR}/router_engine_test.py -v)
-add_test(system_tests_single python ${CMAKE_CURRENT_SOURCE_DIR}/system_tests_one_router.py -v)
-
-set_property(TEST system_tests_single PROPERTY
- ENVIRONMENT "CTEST_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
- )
diff --git a/extras/dispatch/tests/alloc_test.c b/extras/dispatch/tests/alloc_test.c
deleted file mode 100644
index 2406048209..0000000000
--- a/extras/dispatch/tests/alloc_test.c
+++ /dev/null
@@ -1,86 +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 "test_case.h"
-#include <stdio.h>
-#include <string.h>
-#include "alloc_private.h"
-
-typedef struct {
- int A;
- int B;
-} object_t;
-
-dx_alloc_config_t config = {3, 7, 10};
-
-ALLOC_DECLARE(object_t);
-ALLOC_DEFINE_CONFIG(object_t, sizeof(object_t), 0, &config);
-
-
-static char* check_stats(dx_alloc_stats_t *stats, uint64_t ah, uint64_t fh, uint64_t ht, uint64_t rt, uint64_t rg)
-{
- if (stats->total_alloc_from_heap != ah) return "Incorrect alloc-from-heap";
- if (stats->total_free_to_heap != fh) return "Incorrect free-to-heap";
- if (stats->held_by_threads != ht) return "Incorrect held-by-threads";
- if (stats->batches_rebalanced_to_threads != rt) return "Incorrect rebalance-to-threads";
- if (stats->batches_rebalanced_to_global != rg) return "Incorrect rebalance-to-global";
- return 0;
-}
-
-
-static char* test_alloc_basic(void *context)
-{
- object_t *obj[50];
- int idx;
- dx_alloc_stats_t *stats;
- char *error;
-
- for (idx = 0; idx < 20; idx++)
- obj[idx] = new_object_t();
-
- stats = alloc_stats_object_t();
- error = check_stats(stats, 21, 0, 21, 0, 0);
- if (error) return error;
-
- for (idx = 0; idx < 20; idx++)
- free_object_t(obj[idx]);
-
- error = check_stats(stats, 21, 5, 6, 0, 5);
- if (error) return error;
-
- for (idx = 0; idx < 20; idx++)
- obj[idx] = new_object_t();
-
- error = check_stats(stats, 27, 5, 21, 3, 5);
- if (error) return error;
-
- return 0;
-}
-
-
-int alloc_tests(void)
-{
- int result = 0;
- dx_alloc_initialize();
-
- TEST_CASE(test_alloc_basic, 0);
-
- return result;
-}
-
diff --git a/extras/dispatch/tests/compose_test.c b/extras/dispatch/tests/compose_test.c
deleted file mode 100644
index 06292c221f..0000000000
--- a/extras/dispatch/tests/compose_test.c
+++ /dev/null
@@ -1,292 +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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <inttypes.h>
-#include "test_case.h"
-#include <qpid/dispatch.h>
-#include "compose_private.h"
-
-
-static char *vector0 =
- "\x00\x53\x77" // amqp-value
- "\xd0\x00\x00\x01\x26\x00\x00\x00\x0a" // list32 with ten items
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x0a" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x0b" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- "\xd1\x00\x00\x00\x18\x00\x00\x00\x04" // map32 with two pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x14" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\x52\x15" // smalluint
- ;
-
-static int vector0_length = 302;
-
-static char *test_compose_list_of_maps(void *context)
-{
- dx_composed_field_t *field = dx_compose(DX_PERFORMATIVE_BODY_AMQP_VALUE, 0);
-
- dx_compose_start_list(field);
-
- dx_compose_start_map(field);
- dx_compose_insert_string(field, "key001");
- dx_compose_insert_uint(field, 10);
- dx_compose_insert_string(field, "key002");
- dx_compose_insert_uint(field, 11);
- dx_compose_end_map(field);
-
- for (int j = 0; j < 9; j++) {
- dx_compose_start_map(field);
- dx_compose_insert_string(field, "key001");
- dx_compose_insert_uint(field, 20);
- dx_compose_insert_string(field, "key002");
- dx_compose_insert_uint(field, 21);
- dx_compose_end_map(field);
- }
-
- dx_compose_end_list(field);
-
- dx_buffer_t *buf = DEQ_HEAD(field->buffers);
-
- if (dx_buffer_size(buf) != vector0_length) return "Incorrect Length of Buffer";
-
- char *left = vector0;
- char *right = (char*) dx_buffer_base(buf);
- int idx;
-
- for (idx = 0; idx < vector0_length; idx++) {
- if (*left != *right) return "Pattern Mismatch";
- left++;
- right++;
- }
-
- dx_compose_free(field);
- return 0;
-}
-
-static char *vector1 =
- "\x00\x53\x71" // delivery annotations
- "\xd1\x00\x00\x00\x3d\x00\x00\x00\x04" // map32 with two item pairs
- "\xa1\x06key001" // str8-utf8
- "\x52\x0a" // smalluint
- "\xa1\x06key002" // str8-utf8
- "\xd0\x00\x00\x00\x22\x00\x00\x00\x04" // list32 with four items
- "\xa1\x05item1" // str8-utf8
- "\xa1\x05item2" // str8-utf8
- "\xa1\x05item3" // str8-utf8
- "\xd0\x00\x00\x00\x04\x00\x00\x00\x00" // list32 empty
- ;
-
-static int vector1_length = 69;
-
-static char *test_compose_nested_composites(void *context)
-{
- dx_composed_field_t *field = dx_compose(DX_PERFORMATIVE_DELIVERY_ANNOTATIONS, 0);
-
- dx_compose_start_map(field);
-
- dx_compose_insert_string(field, "key001");
- dx_compose_insert_uint(field, 10);
-
- dx_compose_insert_string(field, "key002");
- dx_compose_start_list(field);
-
- dx_compose_insert_string(field, "item1");
- dx_compose_insert_string(field, "item2");
- dx_compose_insert_string(field, "item3");
-
- dx_compose_start_list(field);
- dx_compose_end_list(field);
-
- dx_compose_end_list(field);
- dx_compose_end_map(field);
-
- dx_buffer_t *buf = DEQ_HEAD(field->buffers);
-
- if (dx_buffer_size(buf) != vector1_length) return "Incorrect Length of Buffer";
-
- char *left = vector1;
- char *right = (char*) dx_buffer_base(buf);
- int idx;
-
- for (idx = 0; idx < vector1_length; idx++) {
- if (*left != *right) return "Pattern Mismatch";
- left++;
- right++;
- }
-
- dx_compose_free(field);
- return 0;
-}
-
-static char *vector2 =
- "\x00\x53\x73" // properties
- "\xd0\x00\x00\x00\x83\x00\x00\x00\x1c" // list32 with 28 items
- "\x40" // null
- "\x42" // false
- "\x41" // true
- "\x43" // uint0
- "\x52\x01" // smalluint
- "\x52\xff" // smalluint
- "\x70\x00\x00\x01\x00" // uint
- "\x70\x10\x00\x00\x00" // uint
- "\x44" // ulong0
- "\x53\x01" // smallulong
- "\x53\xff" // smallulong
- "\x80\x00\x00\x00\x00\x00\x00\x01\x00" // ulong
- "\x80\x00\x00\x00\x00\x20\x00\x00\x00" // ulong
- "\x54\x00" // smallint
- "\x54\x01" // smallint
- "\x54\xff" // smallint
- "\x71\x00\x00\x00\xff" // int
- "\x71\x00\x00\x01\x00" // int
- "\x55\x00" // smalllong
- "\x55\x01" // smalllong
- "\x55\xff" // smalllong
- "\x81\x00\x00\x00\x00\x00\x00\x00\xff" // long
- "\x81\x00\x00\x00\x00\x00\x00\x01\x00" // long
- "\x83\x00\x11\x22\x33\x44\x55\x66\x77" // timestamp
- "\x98\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x00" // uuid
- "\xa0\x02\x00\x11" // vbin8
- "\xa1\x06string" // str8-utf8
- "\xa3\x06symbol" // sym8
- ;
-
-static int vector2_length = 139;
-
-static char *test_compose_scalars(void *context)
-{
- dx_composed_field_t *field = dx_compose(DX_PERFORMATIVE_PROPERTIES, 0);
-
- dx_compose_start_list(field);
-
- dx_compose_insert_null(field);
-
- dx_compose_insert_bool(field, 0);
- dx_compose_insert_bool(field, 1);
-
- dx_compose_insert_uint(field, 0);
- dx_compose_insert_uint(field, 1);
- dx_compose_insert_uint(field, 255);
- dx_compose_insert_uint(field, 256);
- dx_compose_insert_uint(field, 0x10000000);
-
- dx_compose_insert_ulong(field, 0);
- dx_compose_insert_ulong(field, 1);
- dx_compose_insert_ulong(field, 255);
- dx_compose_insert_ulong(field, 256);
- dx_compose_insert_ulong(field, 0x20000000);
-
- dx_compose_insert_int(field, 0);
- dx_compose_insert_int(field, 1);
- dx_compose_insert_int(field, -1);
- dx_compose_insert_int(field, 255);
- dx_compose_insert_int(field, 256);
-
- dx_compose_insert_long(field, 0);
- dx_compose_insert_long(field, 1);
- dx_compose_insert_long(field, -1);
- dx_compose_insert_long(field, 255);
- dx_compose_insert_long(field, 256);
-
- dx_compose_insert_timestamp(field, 0x0011223344556677);
- dx_compose_insert_uuid(field, (uint8_t*) "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x00");
- dx_compose_insert_binary(field, (uint8_t*) "\x00\x11", 2);
- dx_compose_insert_string(field, "string");
- dx_compose_insert_symbol(field, "symbol");
-
- dx_compose_end_list(field);
-
- dx_buffer_t *buf = DEQ_HEAD(field->buffers);
-
- if (dx_buffer_size(buf) != vector2_length) return "Incorrect Length of Buffer";
-
- char *left = vector2;
- char *right = (char*) dx_buffer_base(buf);
- int idx;
-
- for (idx = 0; idx < vector2_length; idx++) {
- if (*left != *right) return "Pattern Mismatch";
- left++;
- right++;
- }
-
- dx_compose_free(field);
- return 0;
-}
-
-
-int compose_tests()
-{
- int result = 0;
- dx_log_set_mask(LOG_NONE);
-
- TEST_CASE(test_compose_list_of_maps, 0);
- TEST_CASE(test_compose_nested_composites, 0);
- TEST_CASE(test_compose_scalars, 0);
-
- return result;
-}
-
diff --git a/extras/dispatch/tests/config-1/A.conf b/extras/dispatch/tests/config-1/A.conf
deleted file mode 100644
index 308d86473c..0000000000
--- a/extras/dispatch/tests/config-1/A.conf
+++ /dev/null
@@ -1,54 +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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- ##
- ## worker-threads - The number of threads that will be created to
- ## process message traffic and other application work (timers, non-amqp
- ## file descriptors, etc.)
- ##
- ## The number of threads should be related to the number of available
- ## processor cores. To fully utilize a quad-core system, set the
- ## number of threads to 4.
- ##
- worker-threads: 4
-
- ##
- ## container-name - The name of the AMQP container. If not specified,
- ## the container name will be set to a value of the container's
- ## choosing. The automatically assigned container name is not
- ## guaranteed to be persistent across restarts of the container.
- ##
- container-name: Qpid.Dispatch.Router.A
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- addr: 0.0.0.0
- port: 20000
- sasl-mechanisms: ANONYMOUS
-}
-
diff --git a/extras/dispatch/tests/config-2/A.conf b/extras/dispatch/tests/config-2/A.conf
deleted file mode 100644
index a3fb411018..0000000000
--- a/extras/dispatch/tests/config-2/A.conf
+++ /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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- ##
- ## worker-threads - The number of threads that will be created to
- ## process message traffic and other application work (timers, non-amqp
- ## file descriptors, etc.)
- ##
- ## The number of threads should be related to the number of available
- ## processor cores. To fully utilize a quad-core system, set the
- ## number of threads to 4.
- ##
- worker-threads: 4
-
- ##
- ## container-name - The name of the AMQP container. If not specified,
- ## the container name will be set to a value of the container's
- ## choosing. The automatically assigned container name is not
- ## guaranteed to be persistent across restarts of the container.
- ##
- container-name: Qpid.Dispatch.Router.A
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- role: inter-router
- addr: 0.0.0.0
- port: 20001
- sasl-mechanisms: ANONYMOUS
-}
-
-router {
- mode: interior
- router-id: QDR.A
-}
diff --git a/extras/dispatch/tests/config-2/B.conf b/extras/dispatch/tests/config-2/B.conf
deleted file mode 100644
index 0950584c88..0000000000
--- a/extras/dispatch/tests/config-2/B.conf
+++ /dev/null
@@ -1,67 +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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- ##
- ## worker-threads - The number of threads that will be created to
- ## process message traffic and other application work (timers, non-amqp
- ## file descriptors, etc.)
- ##
- ## The number of threads should be related to the number of available
- ## processor cores. To fully utilize a quad-core system, set the
- ## number of threads to 4.
- ##
- worker-threads: 4
-
- ##
- ## container-name - The name of the AMQP container. If not specified,
- ## the container name will be set to a value of the container's
- ## choosing. The automatically assigned container name is not
- ## guaranteed to be persistent across restarts of the container.
- ##
- container-name: Qpid.Dispatch.Router.B
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- role: inter-router
- addr: 0.0.0.0
- port: 20002
- sasl-mechanisms: ANONYMOUS
-}
-
-connector {
- label: Router Uplink
- role: inter-router
- addr: 0.0.0.0
- port: 20001
- sasl-mechanisms: ANONYMOUS
-}
-
-router {
- mode: interior
- router-id: QDR.B
-}
diff --git a/extras/dispatch/tests/config-3-linear/A.conf b/extras/dispatch/tests/config-3-linear/A.conf
deleted file mode 100644
index 6f0f9abce8..0000000000
--- a/extras/dispatch/tests/config-3-linear/A.conf
+++ /dev/null
@@ -1,69 +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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- ##
- ## worker-threads - The number of threads that will be created to
- ## process message traffic and other application work (timers, non-amqp
- ## file descriptors, etc.)
- ##
- ## The number of threads should be related to the number of available
- ## processor cores. To fully utilize a quad-core system, set the
- ## number of threads to 4.
- ##
- worker-threads: 4
-
- ##
- ## container-name - The name of the AMQP container. If not specified,
- ## the container name will be set to a value of the container's
- ## choosing. The automatically assigned container name is not
- ## guaranteed to be persistent across restarts of the container.
- ##
- container-name: QDR.A
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- addr: 0.0.0.0
- port: 20001
- sasl-mechanisms: ANONYMOUS
-}
-
-connector {
- label: Router Uplink
- role: inter-router
- addr: 0.0.0.0
- port: 20002
- sasl-mechanisms: ANONYMOUS
-}
-
-router {
- mode: interior
- router-id: QDR.A
-}
-
-
-
diff --git a/extras/dispatch/tests/config-3-linear/B.conf b/extras/dispatch/tests/config-3-linear/B.conf
deleted file mode 100644
index 85c146bd58..0000000000
--- a/extras/dispatch/tests/config-3-linear/B.conf
+++ /dev/null
@@ -1,68 +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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- ##
- ## worker-threads - The number of threads that will be created to
- ## process message traffic and other application work (timers, non-amqp
- ## file descriptors, etc.)
- ##
- ## The number of threads should be related to the number of available
- ## processor cores. To fully utilize a quad-core system, set the
- ## number of threads to 4.
- ##
- worker-threads: 4
-
- ##
- ## container-name - The name of the AMQP container. If not specified,
- ## the container name will be set to a value of the container's
- ## choosing. The automatically assigned container name is not
- ## guaranteed to be persistent across restarts of the container.
- ##
- container-name: QDR.B
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- role: inter-router
- addr: 0.0.0.0
- port: 20002
- sasl-mechanisms: ANONYMOUS
-}
-
-connector {
- label: Router Uplink
- role: inter-router
- addr: 0.0.0.0
- port: 20003
- sasl-mechanisms: ANONYMOUS
-}
-
-
-router {
- mode: interior
- router-id: QDR.B
-}
diff --git a/extras/dispatch/tests/config-3-linear/C.conf b/extras/dispatch/tests/config-3-linear/C.conf
deleted file mode 100644
index 17971462bc..0000000000
--- a/extras/dispatch/tests/config-3-linear/C.conf
+++ /dev/null
@@ -1,60 +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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- ##
- ## worker-threads - The number of threads that will be created to
- ## process message traffic and other application work (timers, non-amqp
- ## file descriptors, etc.)
- ##
- ## The number of threads should be related to the number of available
- ## processor cores. To fully utilize a quad-core system, set the
- ## number of threads to 4.
- ##
- worker-threads: 4
-
- ##
- ## container-name - The name of the AMQP container. If not specified,
- ## the container name will be set to a value of the container's
- ## choosing. The automatically assigned container name is not
- ## guaranteed to be persistent across restarts of the container.
- ##
- container-name: QDR.C
-}
-
-
-##
-## Listeners and Connectors
-##
-listener {
- role: inter-router
- addr: 0.0.0.0
- port: 20003
- sasl-mechanisms: ANONYMOUS
-}
-
-
-router {
- mode: interior
- router-id: QDR.C
-}
diff --git a/extras/dispatch/tests/config-3-linear/topology.txt b/extras/dispatch/tests/config-3-linear/topology.txt
deleted file mode 100644
index 07d6d74008..0000000000
--- a/extras/dispatch/tests/config-3-linear/topology.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- +----------+ +----------+ +----------+
- |QDR.A | |QDR.B | |QDR.C |
- |port: | |port: | |port: |
- | 20001 |--------->| 20002 |--------->| 20003 |
- | | | | | |
- | | | | | |
- +----------+ +----------+ +----------+
-
- * The direction of the arrow shows the direction of the connection setup
- Connector --> Listener
diff --git a/extras/dispatch/tests/field_test.c b/extras/dispatch/tests/field_test.c
deleted file mode 100644
index 77cb6d969f..0000000000
--- a/extras/dispatch/tests/field_test.c
+++ /dev/null
@@ -1,178 +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 "test_case.h"
-#include <stdio.h>
-#include <string.h>
-#include <qpid/dispatch/iterator.h>
-
-#define FAIL_TEXT_SIZE 10000
-static char fail_text[FAIL_TEXT_SIZE];
-
-static char* test_view_global_dns(void *context)
-{
- dx_field_iterator_t *iter = dx_field_iterator_string("amqp://host/global/sub", ITER_VIEW_ALL);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "amqp://host/global/sub"))
- return "ITER_VIEW_ALL failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NO_HOST);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "global/sub"))
- return "ITER_VIEW_NO_HOST failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NODE_ID);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "global"))
- return "ITER_VIEW_NODE_ID failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NODE_SPECIFIC);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "sub"))
- return "ITER_VIEW_NODE_SPECIFIC failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "Mglobal/sub"))
- return "ITER_VIEW_ADDRESS_HASH failed";
-
- return 0;
-}
-
-
-static char* test_view_global_non_dns(void *context)
-{
- dx_field_iterator_t *iter = dx_field_iterator_string("amqp:/global/sub", ITER_VIEW_ALL);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "amqp:/global/sub"))
- return "ITER_VIEW_ALL failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NO_HOST);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "global/sub"))
- return "ITER_VIEW_NO_HOST failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NODE_ID);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "global"))
- return "ITER_VIEW_NODE_ID failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NODE_SPECIFIC);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "sub"))
- return "ITER_VIEW_NODE_SPECIFIC failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "Mglobal/sub"))
- return "ITER_VIEW_ADDRESS_HASH failed";
-
- return 0;
-}
-
-
-static char* test_view_global_no_host(void *context)
-{
- dx_field_iterator_t *iter = dx_field_iterator_string("global/sub", ITER_VIEW_ALL);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "global/sub"))
- return "ITER_VIEW_ALL failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NO_HOST);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "global/sub"))
- return "ITER_VIEW_NO_HOST failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NODE_ID);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "global"))
- return "ITER_VIEW_NODE_ID failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_NODE_SPECIFIC);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "sub"))
- return "ITER_VIEW_NODE_SPECIFIC failed";
-
- dx_field_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
- if (!dx_field_iterator_equal(iter, (unsigned char*) "Mglobal/sub"))
- return "ITER_VIEW_ADDRESS_HASH failed";
-
- return 0;
-}
-
-
-static char* test_view_address_hash(void *context)
-{
- struct {const char *addr; const char *view;} cases[] = {
- {"amqp:/_local/my-addr/sub", "Lmy-addr/sub"},
- {"amqp:/_local/my-addr", "Lmy-addr"},
- {"amqp:/_topo/area/router/local/sub", "Aarea"},
- {"amqp:/_topo/my-area/router/local/sub", "Rrouter"},
- {"amqp:/_topo/my-area/my-router/local/sub", "Llocal/sub"},
- {"amqp:/_topo/area/all/local/sub", "Aarea"},
- {"amqp:/_topo/my-area/all/local/sub", "Llocal/sub"},
- {"amqp:/_topo/all/all/local/sub", "Llocal/sub"},
- {"amqp://host:port/_local/my-addr", "Lmy-addr"},
- {"_topo/area/router/my-addr", "Aarea"},
- {"_topo/my-area/router/my-addr", "Rrouter"},
- {"_topo/my-area/my-router/my-addr", "Lmy-addr"},
- {"_topo/my-area/router", "Rrouter"},
- {0, 0}
- };
- int idx;
-
- for (idx = 0; cases[idx].addr; idx++) {
- dx_field_iterator_t *iter = dx_field_iterator_string(cases[idx].addr, ITER_VIEW_ADDRESS_HASH);
- if (!dx_field_iterator_equal(iter, (unsigned char*) cases[idx].view)) {
- char *got = (char*) dx_field_iterator_copy(iter);
- snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed. Expected '%s', got '%s'",
- cases[idx].addr, cases[idx].view, got);
- return fail_text;
- }
- }
-
- return 0;
-}
-
-
-static char* test_view_node_hash(void *context)
-{
- struct {const char *addr; const char *view;} cases[] = {
- {"area/router", "Aarea"},
- {"my-area/router", "Rrouter"},
- {"my-area/my-router", "Rmy-router"},
- {0, 0}
- };
- int idx;
-
- for (idx = 0; cases[idx].addr; idx++) {
- dx_field_iterator_t *iter = dx_field_iterator_string(cases[idx].addr, ITER_VIEW_NODE_HASH);
- if (!dx_field_iterator_equal(iter, (unsigned char*) cases[idx].view)) {
- char *got = (char*) dx_field_iterator_copy(iter);
- snprintf(fail_text, FAIL_TEXT_SIZE, "Addr '%s' failed. Expected '%s', got '%s'",
- cases[idx].addr, cases[idx].view, got);
- return fail_text;
- }
- }
-
- return 0;
-}
-
-
-int field_tests(void)
-{
- int result = 0;
-
- dx_field_iterator_set_address("my-area", "my-router");
-
- TEST_CASE(test_view_global_dns, 0);
- TEST_CASE(test_view_global_non_dns, 0);
- TEST_CASE(test_view_global_no_host, 0);
- TEST_CASE(test_view_address_hash, 0);
- TEST_CASE(test_view_node_hash, 0);
-
- return result;
-}
-
diff --git a/extras/dispatch/tests/message_test.c b/extras/dispatch/tests/message_test.c
deleted file mode 100644
index 59f4e444dc..0000000000
--- a/extras/dispatch/tests/message_test.c
+++ /dev/null
@@ -1,193 +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 "test_case.h"
-#include <stdio.h>
-#include <string.h>
-#include "message_private.h"
-#include <qpid/dispatch/iterator.h>
-#include <proton/message.h>
-
-static char buffer[10000];
-
-static size_t flatten_bufs(dx_message_content_t *content)
-{
- char *cursor = buffer;
- dx_buffer_t *buf = DEQ_HEAD(content->buffers);
-
- while (buf) {
- memcpy(cursor, dx_buffer_base(buf), dx_buffer_size(buf));
- cursor += dx_buffer_size(buf);
- buf = buf->next;
- }
-
- return (size_t) (cursor - buffer);
-}
-
-
-static void set_content(dx_message_content_t *content, size_t len)
-{
- char *cursor = buffer;
- dx_buffer_t *buf;
-
- while (len > (size_t) (cursor - buffer)) {
- buf = dx_buffer();
- size_t segment = dx_buffer_capacity(buf);
- size_t remaining = len - (size_t) (cursor - buffer);
- if (segment > remaining)
- segment = remaining;
- memcpy(dx_buffer_base(buf), cursor, segment);
- cursor += segment;
- dx_buffer_insert(buf, segment);
- DEQ_INSERT_TAIL(content->buffers, buf);
- }
-}
-
-
-static char* test_send_to_messenger(void *context)
-{
- dx_message_t *msg = dx_message();
- dx_message_content_t *content = MSG_CONTENT(msg);
-
- dx_message_compose_1(msg, "test_addr_0", 0);
- dx_buffer_t *buf = DEQ_HEAD(content->buffers);
- if (buf == 0) return "Expected a buffer in the test message";
-
- pn_message_t *pn_msg = pn_message();
- size_t len = flatten_bufs(content);
- int result = pn_message_decode(pn_msg, buffer, len);
- if (result != 0) return "Error in pn_message_decode";
-
- if (strcmp(pn_message_get_address(pn_msg), "test_addr_0") != 0)
- return "Address mismatch in received message";
-
- pn_message_free(pn_msg);
- dx_message_free(msg);
-
- return 0;
-}
-
-
-static char* test_receive_from_messenger(void *context)
-{
- pn_message_t *pn_msg = pn_message();
- pn_message_set_address(pn_msg, "test_addr_1");
-
- size_t size = 10000;
- int result = pn_message_encode(pn_msg, buffer, &size);
- if (result != 0) return "Error in pn_message_encode";
-
- dx_message_t *msg = dx_message();
- dx_message_content_t *content = MSG_CONTENT(msg);
-
- set_content(content, size);
-
- int valid = dx_message_check(msg, DX_DEPTH_ALL);
- if (!valid) return "dx_message_check returns 'invalid'";
-
- dx_field_iterator_t *iter = dx_message_field_iterator(msg, DX_FIELD_TO);
- if (iter == 0) return "Expected an iterator for the 'to' field";
-
- if (!dx_field_iterator_equal(iter, (unsigned char*) "test_addr_1"))
- return "Mismatched 'to' field contents";
-
- ssize_t test_len = dx_message_field_length(msg, DX_FIELD_TO);
- if (test_len != 11) return "Incorrect field length";
-
- char test_field[15];
- test_len = dx_message_field_copy(msg, DX_FIELD_TO, test_field);
- if (test_len != 11) return "Incorrect length returned from field_copy";
- test_field[test_len] = '\0';
- if (strcmp(test_field, "test_addr_1") != 0)
- return "Incorrect field content returned from field_copy";
-
- pn_message_free(pn_msg);
- dx_message_free(msg);
-
- return 0;
-}
-
-
-static char* test_insufficient_check_depth(void *context)
-{
- pn_message_t *pn_msg = pn_message();
- pn_message_set_address(pn_msg, "test_addr_2");
-
- size_t size = 10000;
- int result = pn_message_encode(pn_msg, buffer, &size);
- if (result != 0) return "Error in pn_message_encode";
-
- dx_message_t *msg = dx_message();
- dx_message_content_t *content = MSG_CONTENT(msg);
-
- set_content(content, size);
-
- int valid = dx_message_check(msg, DX_DEPTH_DELIVERY_ANNOTATIONS);
- if (!valid) return "dx_message_check returns 'invalid'";
-
- dx_field_iterator_t *iter = dx_message_field_iterator(msg, DX_FIELD_TO);
- if (iter) return "Expected no iterator for the 'to' field";
-
- dx_message_free(msg);
-
- return 0;
-}
-
-
-static char* test_check_multiple(void *context)
-{
- pn_message_t *pn_msg = pn_message();
- pn_message_set_address(pn_msg, "test_addr_2");
-
- size_t size = 10000;
- int result = pn_message_encode(pn_msg, buffer, &size);
- if (result != 0) return "Error in pn_message_encode";
-
- dx_message_t *msg = dx_message();
- dx_message_content_t *content = MSG_CONTENT(msg);
-
- set_content(content, size);
-
- int valid = dx_message_check(msg, DX_DEPTH_DELIVERY_ANNOTATIONS);
- if (!valid) return "dx_message_check returns 'invalid' for DELIVERY_ANNOTATIONS";
-
- valid = dx_message_check(msg, DX_DEPTH_BODY);
- if (!valid) return "dx_message_check returns 'invalid' for BODY";
-
- valid = dx_message_check(msg, DX_DEPTH_PROPERTIES);
- if (!valid) return "dx_message_check returns 'invalid' for PROPERTIES";
-
- dx_message_free(msg);
-
- return 0;
-}
-
-
-int message_tests(void)
-{
- int result = 0;
-
- TEST_CASE(test_send_to_messenger, 0);
- TEST_CASE(test_receive_from_messenger, 0);
- TEST_CASE(test_insufficient_check_depth, 0);
- TEST_CASE(test_check_multiple, 0);
-
- return result;
-}
-
diff --git a/extras/dispatch/tests/parse_test.c b/extras/dispatch/tests/parse_test.c
deleted file mode 100644
index 124ba1c0d4..0000000000
--- a/extras/dispatch/tests/parse_test.c
+++ /dev/null
@@ -1,166 +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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <inttypes.h>
-#include "test_case.h"
-#include <qpid/dispatch.h>
-
-struct fs_vector_t {
- const char *data;
- int length;
- uint8_t expected_tag;
- int check_uint;
- int check_ulong;
- int check_int;
- int check_long;
- uint64_t expected_ulong;
- int64_t expected_long;
-} fs_vectors[] = {
-{"\x40", 1, DX_AMQP_NULL, 0, 0, 0, 0, 0, 0}, // 0
-{"\x41", 1, DX_AMQP_TRUE, 1, 0, 0, 0, 1, 0}, // 1
-{"\x42", 1, DX_AMQP_FALSE, 1, 0, 0, 0, 0, 0}, // 2
-{"\x56\x00", 2, DX_AMQP_BOOLEAN, 1, 0, 0, 0, 0, 0}, // 3
-{"\x56\x01", 2, DX_AMQP_BOOLEAN, 1, 0, 0, 0, 1, 0}, // 4
-{"\x50\x45", 2, DX_AMQP_UBYTE, 1, 0, 0, 0, 0x45, 0}, // 5
-{"\x60\x02\x04", 3, DX_AMQP_USHORT, 1, 0, 0, 0, 0x0204, 0}, // 6
-{"\x70\x01\x02\x03\x04", 5, DX_AMQP_UINT, 1, 0, 0, 0, 0x01020304, 0}, // 7
-{"\x52\x06", 2, DX_AMQP_SMALLUINT, 1, 0, 0, 0, 6, 0}, // 8
-{"\x43", 1, DX_AMQP_UINT0, 1, 0, 0, 0, 0, 0}, // 9
-{"\x80\x01\x02\x03\x04\x05\x06\x07\x08",
- 9, DX_AMQP_ULONG, 0, 1, 0, 0, 0x0102030405060708, 0}, // 10
-{"\x53\x08", 2, DX_AMQP_SMALLULONG, 0, 1, 0, 0, 0x08, 0}, // 11
-{"\x44", 1, DX_AMQP_ULONG0, 0, 1, 0, 0, 0, 0}, // 12
-{"\x71\x01\x02\x03\x04", 5, DX_AMQP_INT, 0, 0, 1, 0, 0, 0x01020304}, // 13
-{"\x54\x02", 2, DX_AMQP_SMALLINT, 0, 0, 1, 0, 0, 2}, // 14
-{"\x81\x01\x02\x03\x04\x05\x06\x07\x08",
- 9, DX_AMQP_LONG, 0, 0, 0, 1, 0, 0x0102030405060708}, // 15
-{"\x55\x08", 2, DX_AMQP_SMALLLONG, 0, 0, 0, 1, 0, 0x08}, // 16
-{0, 0, 0, 0, 0}
-};
-
-
-static char *test_parser_fixed_scalars(void *context)
-{
- int idx = 0;
- static char error[1024];
-
- while (fs_vectors[idx].data) {
- dx_field_iterator_t *field = dx_field_iterator_binary(fs_vectors[idx].data,
- fs_vectors[idx].length,
- ITER_VIEW_ALL);
- dx_parsed_field_t *parsed = dx_parse(field);
- if (!dx_parse_ok(parsed)) return "Unexpected Parse Error";
- if (dx_parse_tag(parsed) != fs_vectors[idx].expected_tag) {
- sprintf(error, "(%d) Tag: Expected %02x, Got %02x", idx,
- fs_vectors[idx].expected_tag, dx_parse_tag(parsed));
- return error;
- }
- if (fs_vectors[idx].check_uint &&
- dx_parse_as_uint(parsed) != fs_vectors[idx].expected_ulong) {
- sprintf(error, "(%d) UINT: Expected %"PRIx64", Got %"PRIx32, idx,
- fs_vectors[idx].expected_ulong, dx_parse_as_uint(parsed));
- return error;
- }
- if (fs_vectors[idx].check_ulong &&
- dx_parse_as_ulong(parsed) != fs_vectors[idx].expected_ulong) {
- sprintf(error, "(%d) ULONG: Expected %"PRIx64", Got %"PRIx64, idx,
- fs_vectors[idx].expected_ulong, dx_parse_as_ulong(parsed));
- return error;
- }
- if (fs_vectors[idx].check_int &&
- dx_parse_as_int(parsed) != fs_vectors[idx].expected_long) {
- sprintf(error, "(%d) INT: Expected %"PRIx64", Got %"PRIx32, idx,
- fs_vectors[idx].expected_long, dx_parse_as_int(parsed));
- return error;
- }
- if (fs_vectors[idx].check_long &&
- dx_parse_as_long(parsed) != fs_vectors[idx].expected_long) {
- sprintf(error, "(%d) LONG: Expected %"PRIx64", Got %"PRIx64, idx,
- fs_vectors[idx].expected_long, dx_parse_as_long(parsed));
- return error;
- }
- idx++;
-
- dx_field_iterator_free(field);
- dx_parse_free(parsed);
- }
-
- return 0;
-}
-
-
-struct err_vector_t {
- const char *data;
- int length;
- const char *expected_error;
-} err_vectors[] = {
-{"", 0, "Insufficient Data to Determine Tag"}, // 0
-{"\x21", 1, "Invalid Tag - No Length Information"}, // 1
-//{"\x56", 1, "w"}, // 2
-{"\xa0", 1, "Insufficient Data to Determine Length"}, // 3
-{"\xb0", 1, "Insufficient Data to Determine Length"}, // 4
-{"\xb0\x00", 2, "Insufficient Data to Determine Length"}, // 5
-{"\xb0\x00\x00", 3, "Insufficient Data to Determine Length"}, // 6
-{"\xb0\x00\x00\x00", 4, "Insufficient Data to Determine Length"}, // 7
-{"\xc0\x04", 2, "Insufficient Data to Determine Count"}, // 8
-{"\xd0\x00\x00\x00\x00\x00\x00\x00\x01", 9, "Insufficient Length to Determine Count"}, // 9
-{0, 0, 0}
-};
-
-static char *test_parser_errors(void *context)
-{
- int idx = 0;
- static char error[1024];
-
- while (err_vectors[idx].data) {
- dx_field_iterator_t *field = dx_field_iterator_binary(err_vectors[idx].data,
- err_vectors[idx].length,
- ITER_VIEW_ALL);
- dx_parsed_field_t *parsed = dx_parse(field);
- if (dx_parse_ok(parsed)) {
- sprintf(error, "(%d) Unexpected Parse Success", idx);
- return error;
- }
- if (strcmp(dx_parse_error(parsed), err_vectors[idx].expected_error) != 0) {
- sprintf(error, "(%d) Error: Expected %s, Got %s", idx,
- err_vectors[idx].expected_error, dx_parse_error(parsed));
- return error;
- }
- idx++;
- }
-
- return 0;
-}
-
-
-int parse_tests()
-{
- int result = 0;
- dx_log_set_mask(LOG_NONE);
-
- TEST_CASE(test_parser_fixed_scalars, 0);
- TEST_CASE(test_parser_errors, 0);
-
- return result;
-}
-
diff --git a/extras/dispatch/tests/router_engine_test.py b/extras/dispatch/tests/router_engine_test.py
deleted file mode 100644
index e25ce35d22..0000000000
--- a/extras/dispatch/tests/router_engine_test.py
+++ /dev/null
@@ -1,651 +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 unittest
-from qpid.dispatch.router.router_engine import NeighborEngine, PathEngine, Configuration, NodeTracker
-from qpid.dispatch.router.data import LinkState, MessageHELLO
-
-class Adapter(object):
- def __init__(self, domain):
- self._domain = domain
-
- def log(self, level, text):
- print "Adapter.log(%d): domain=%s, text=%s" % (level, self._domain, text)
-
- def send(self, dest, opcode, body):
- print "Adapter.send: domain=%s, dest=%s, opcode=%s, body=%s" % (self._domain, dest, opcode, body)
-
- def remote_bind(self, subject, peer):
- print "Adapter.remote_bind: subject=%s, peer=%s" % (subject, peer)
-
- def remote_unbind(self, subject, peer):
- print "Adapter.remote_unbind: subject=%s, peer=%s" % (subject, peer)
-
- def node_updated(self, address, reachable, neighbor, link_bit, router_bit):
- print "Adapter.node_updated: address=%s, reachable=%r, neighbor=%r, link_bit=%d, router_bit=%d" % \
- (address, reachable, neighbor, link_bit, router_bit)
-
-
-class DataTest(unittest.TestCase):
- def test_link_state(self):
- ls = LinkState(None, 'R1', 'area', 1, ['R2', 'R3'])
- self.assertEqual(ls.id, 'R1')
- self.assertEqual(ls.area, 'area')
- self.assertEqual(ls.ls_seq, 1)
- self.assertEqual(ls.peers, ['R2', 'R3'])
- ls.bump_sequence()
- self.assertEqual(ls.id, 'R1')
- self.assertEqual(ls.area, 'area')
- self.assertEqual(ls.ls_seq, 2)
- self.assertEqual(ls.peers, ['R2', 'R3'])
-
- result = ls.add_peer('R4')
- self.assertTrue(result)
- self.assertEqual(ls.peers, ['R2', 'R3', 'R4'])
- result = ls.add_peer('R2')
- self.assertFalse(result)
- self.assertEqual(ls.peers, ['R2', 'R3', 'R4'])
-
- result = ls.del_peer('R3')
- self.assertTrue(result)
- self.assertEqual(ls.peers, ['R2', 'R4'])
- result = ls.del_peer('R5')
- self.assertFalse(result)
- self.assertEqual(ls.peers, ['R2', 'R4'])
-
- encoded = ls.to_dict()
- new_ls = LinkState(encoded)
- self.assertEqual(new_ls.id, 'R1')
- self.assertEqual(new_ls.area, 'area')
- self.assertEqual(new_ls.ls_seq, 2)
- self.assertEqual(new_ls.peers, ['R2', 'R4'])
-
-
- def test_hello_message(self):
- msg1 = MessageHELLO(None, 'R1', 'area', ['R2', 'R3', 'R4'])
- self.assertEqual(msg1.get_opcode(), "HELLO")
- self.assertEqual(msg1.id, 'R1')
- self.assertEqual(msg1.area, 'area')
- self.assertEqual(msg1.seen_peers, ['R2', 'R3', 'R4'])
- encoded = msg1.to_dict()
- msg2 = MessageHELLO(encoded)
- self.assertEqual(msg2.get_opcode(), "HELLO")
- self.assertEqual(msg2.id, 'R1')
- self.assertEqual(msg2.area, 'area')
- self.assertEqual(msg2.seen_peers, ['R2', 'R3', 'R4'])
- self.assertTrue(msg2.is_seen('R3'))
- self.assertFalse(msg2.is_seen('R9'))
-
-
-class NodeTrackerTest(unittest.TestCase):
- def log(self, level, text):
- pass
-
- def add_neighbor_router(self, address, router_bit, link_bit):
- self.address = address
- self.router_bit = router_bit
- self.link_bit = link_bit
- self.calls += 1
-
- def del_neighbor_router(self, router_bit):
- self.address = None
- self.router_bit = router_bit
- self.link_bit = None
- self.calls += 1
-
- def add_remote_router(self, address, router_bit):
- self.address = address
- self.router_bit = router_bit
- self.link_bit = None
- self.calls += 1
-
- def del_remote_router(self, router_bit):
- self.address = None
- self.router_bit = router_bit
- self.link_bit = None
- self.calls += 1
-
- def reset(self):
- self.address = None
- self.router_bit = None
- self.link_bit = None
- self.area = "area"
- self.calls = 0
-
- def test_node_tracker_limits(self):
- tracker = NodeTracker(self, 5)
-
- self.reset()
- tracker.new_neighbor('A', 1)
- self.assertEqual(self.address, 'amqp:/_topo/area/A')
- self.assertEqual(self.link_bit, 1)
- self.assertEqual(self.router_bit, 1)
- self.assertEqual(self.calls, 1)
-
- self.reset()
- tracker.new_neighbor('B', 5)
- self.assertEqual(self.address, 'amqp:/_topo/area/B')
- self.assertEqual(self.link_bit, 5)
- self.assertEqual(self.router_bit, 2)
- self.assertEqual(self.calls, 1)
-
- self.reset()
- tracker.new_neighbor('C', 6)
- self.assertEqual(self.address, 'amqp:/_topo/area/C')
- self.assertEqual(self.link_bit, 6)
- self.assertEqual(self.router_bit, 3)
- self.assertEqual(self.calls, 1)
-
- self.reset()
- tracker.new_neighbor('D', 7)
- self.assertEqual(self.address, 'amqp:/_topo/area/D')
- self.assertEqual(self.link_bit, 7)
- self.assertEqual(self.router_bit, 4)
- self.assertEqual(self.calls, 1)
-
- self.reset()
- try:
- tracker.new_neighbor('E', 9)
- AssertFalse("We shouldn't be here")
- except:
- pass
-
- self.reset()
- tracker.lost_neighbor('C')
- self.assertEqual(self.router_bit, 3)
- self.assertEqual(self.calls, 1)
-
- self.reset()
- tracker.new_neighbor('E', 9)
- self.assertEqual(self.address, 'amqp:/_topo/area/E')
- self.assertEqual(self.link_bit, 9)
- self.assertEqual(self.router_bit, 3)
- self.assertEqual(self.calls, 1)
-
-
- def test_node_tracker_remote_neighbor(self):
- tracker = NodeTracker(self, 5)
-
- self.reset()
- tracker.new_node('A')
- self.assertEqual(self.address, 'amqp:/_topo/area/A')
- self.assertFalse(self.link_bit)
- self.assertEqual(self.router_bit, 1)
- self.assertEqual(self.calls, 1)
-
- self.reset()
- tracker.new_neighbor('A', 3)
- self.assertEqual(self.address, 'amqp:/_topo/area/A')
- self.assertEqual(self.link_bit, 3)
- self.assertEqual(self.router_bit, 1)
- self.assertEqual(self.calls, 2)
-
- self.reset()
- tracker.lost_node('A')
- self.assertFalse(self.address)
- self.assertFalse(self.link_bit)
- self.assertFalse(self.router_bit)
- self.assertEqual(self.calls, 0)
-
- self.reset()
- tracker.lost_neighbor('A')
- self.assertEqual(self.router_bit, 1)
- self.assertEqual(self.calls, 1)
-
-
- def test_node_tracker_neighbor_remote(self):
- tracker = NodeTracker(self, 5)
-
- self.reset()
- tracker.new_neighbor('A', 3)
- self.assertEqual(self.address, 'amqp:/_topo/area/A')
- self.assertEqual(self.link_bit, 3)
- self.assertEqual(self.router_bit, 1)
- self.assertEqual(self.calls, 1)
-
- self.reset()
- tracker.new_node('A')
- self.assertFalse(self.address)
- self.assertFalse(self.link_bit)
- self.assertFalse(self.router_bit)
- self.assertEqual(self.calls, 0)
-
- self.reset()
- tracker.lost_neighbor('A')
- self.assertEqual(self.address, 'amqp:/_topo/area/A')
- self.assertEqual(self.router_bit, 1)
- self.assertEqual(self.calls, 2)
-
- self.reset()
- tracker.lost_node('A')
- self.assertEqual(self.router_bit, 1)
- self.assertEqual(self.calls, 1)
-
-
-class NeighborTest(unittest.TestCase):
- def log(self, level, text):
- pass
-
- def send(self, dest, msg):
- self.sent.append((dest, msg))
-
- def local_link_state_changed(self, link_state):
- self.local_link_state = link_state
-
- def new_neighbor(self, rid, lbit):
- self.neighbors[rid] = None
-
- def lost_neighbor(self, rid):
- self.neighbors.pop(rid)
-
- def setUp(self):
- self.sent = []
- self.local_link_state = None
- self.id = "R1"
- self.area = "area"
- self.config = Configuration()
- self.neighbors = {}
-
- def test_hello_sent(self):
- self.sent = []
- self.local_link_state = None
- self.engine = NeighborEngine(self)
- self.engine.tick(0.5)
- self.assertEqual(self.sent, [])
- self.engine.tick(1.5)
- self.assertEqual(len(self.sent), 1)
- dest, msg = self.sent.pop(0)
- self.assertEqual(dest, "amqp:/_local/qdxhello")
- self.assertEqual(msg.get_opcode(), "HELLO")
- self.assertEqual(msg.id, self.id)
- self.assertEqual(msg.area, self.area)
- self.assertEqual(msg.seen_peers, [])
- self.assertEqual(self.local_link_state, None)
-
- def test_sees_peer(self):
- self.sent = []
- self.local_link_state = None
- self.engine = NeighborEngine(self)
- self.engine.handle_hello(MessageHELLO(None, 'R2', 'area', []), 2.0, 0)
- self.engine.tick(5.0)
- self.assertEqual(len(self.sent), 1)
- dest, msg = self.sent.pop(0)
- self.assertEqual(msg.seen_peers, ['R2'])
-
- def test_establish_peer(self):
- self.sent = []
- self.local_link_state = None
- self.engine = NeighborEngine(self)
- self.engine.handle_hello(MessageHELLO(None, 'R2', 'area', ['R1']), 0.5, 0)
- self.engine.tick(1.0)
- self.engine.tick(2.0)
- self.engine.tick(3.0)
- self.assertEqual(self.local_link_state.id, 'R1')
- self.assertEqual(self.local_link_state.area, 'area')
- self.assertEqual(self.local_link_state.ls_seq, 1)
- self.assertEqual(self.local_link_state.peers, ['R2'])
-
- def test_establish_multiple_peers(self):
- self.sent = []
- self.local_link_state = None
- self.engine = NeighborEngine(self)
- self.engine.handle_hello(MessageHELLO(None, 'R2', 'area', ['R1']), 0.5, 0)
- self.engine.tick(1.0)
- self.engine.handle_hello(MessageHELLO(None, 'R3', 'area', ['R1', 'R2']), 1.5, 0)
- self.engine.tick(2.0)
- self.engine.handle_hello(MessageHELLO(None, 'R4', 'area', ['R1']), 2.5, 0)
- self.engine.handle_hello(MessageHELLO(None, 'R5', 'area', ['R2']), 2.5, 0)
- self.engine.handle_hello(MessageHELLO(None, 'R6', 'area', ['R1']), 2.5, 0)
- self.engine.tick(3.0)
- self.assertEqual(self.local_link_state.id, 'R1')
- self.assertEqual(self.local_link_state.area, 'area')
- self.assertEqual(self.local_link_state.ls_seq, 3)
- self.local_link_state.peers.sort()
- self.assertEqual(self.local_link_state.peers, ['R2', 'R3', 'R4', 'R6'])
-
- def test_timeout_peer(self):
- self.sent = []
- self.local_link_state = None
- self.engine = NeighborEngine(self)
- self.engine.handle_hello(MessageHELLO(None, 'R2', 'area', ['R3', 'R1']), 2.0, 0)
- self.engine.tick(5.0)
- self.engine.tick(17.1)
- self.assertEqual(self.local_link_state.id, 'R1')
- self.assertEqual(self.local_link_state.area, 'area')
- self.assertEqual(self.local_link_state.ls_seq, 2)
- self.assertEqual(self.local_link_state.peers, [])
-
-
-class PathTest(unittest.TestCase):
- def setUp(self):
- self.id = 'R1'
- self.area = 'area'
- self.next_hops = None
- self.valid_origins = None
- self.engine = PathEngine(self)
-
- def log(self, level, text):
- pass
-
- def next_hops_changed(self, nh):
- self.next_hops = nh
-
- def valid_origins_changed(self, vo):
- self.valid_origins = vo
-
- def test_topology1(self):
- """
-
- +====+ +----+ +----+
- | R1 |------| R2 |------| R3 |
- +====+ +----+ +----+
-
- """
- collection = { 'R1': LinkState(None, 'R1', 'area', 1, ['R2']),
- 'R2': LinkState(None, 'R2', 'area', 1, ['R1', 'R3']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R2']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 2)
- self.assertEqual(self.next_hops['R2'], 'R2')
- self.assertEqual(self.next_hops['R3'], 'R2')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.assertEqual(self.valid_origins['R2'], [])
- self.assertEqual(self.valid_origins['R3'], [])
-
- def test_topology2(self):
- """
-
- +====+ +----+ +----+
- | R1 |------| R2 |------| R4 |
- +====+ +----+ +----+
- | |
- +----+ +----+ +----+
- | R3 |------| R5 |------| R6 |
- +----+ +----+ +----+
-
- """
- collection = { 'R1': LinkState(None, 'R1', 'area', 1, ['R2']),
- 'R2': LinkState(None, 'R2', 'area', 1, ['R1', 'R3', 'R4']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R2', 'R5']),
- 'R4': LinkState(None, 'R4', 'area', 1, ['R2', 'R5']),
- 'R5': LinkState(None, 'R5', 'area', 1, ['R3', 'R4', 'R6']),
- 'R6': LinkState(None, 'R6', 'area', 1, ['R5']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 5)
- self.assertEqual(self.next_hops['R2'], 'R2')
- self.assertEqual(self.next_hops['R3'], 'R2')
- self.assertEqual(self.next_hops['R4'], 'R2')
- self.assertEqual(self.next_hops['R5'], 'R2')
- self.assertEqual(self.next_hops['R6'], 'R2')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.valid_origins['R4'].sort()
- self.valid_origins['R5'].sort()
- self.valid_origins['R6'].sort()
- self.assertEqual(self.valid_origins['R2'], [])
- self.assertEqual(self.valid_origins['R3'], [])
- self.assertEqual(self.valid_origins['R4'], [])
- self.assertEqual(self.valid_origins['R5'], [])
- self.assertEqual(self.valid_origins['R6'], [])
-
- def test_topology3(self):
- """
-
- +----+ +----+ +----+
- | R2 |------| R3 |------| R4 |
- +----+ +----+ +----+
- | |
- +====+ +----+ +----+
- | R1 |------| R5 |------| R6 |
- +====+ +----+ +----+
-
- """
- collection = { 'R2': LinkState(None, 'R2', 'area', 1, ['R3']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R1', 'R2', 'R4']),
- 'R4': LinkState(None, 'R4', 'area', 1, ['R3', 'R5']),
- 'R1': LinkState(None, 'R1', 'area', 1, ['R3', 'R5']),
- 'R5': LinkState(None, 'R5', 'area', 1, ['R1', 'R4', 'R6']),
- 'R6': LinkState(None, 'R6', 'area', 1, ['R5']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 5)
- self.assertEqual(self.next_hops['R2'], 'R3')
- self.assertEqual(self.next_hops['R3'], 'R3')
- self.assertEqual(self.next_hops['R4'], 'R3')
- self.assertEqual(self.next_hops['R5'], 'R5')
- self.assertEqual(self.next_hops['R6'], 'R5')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.valid_origins['R4'].sort()
- self.valid_origins['R5'].sort()
- self.valid_origins['R6'].sort()
- self.assertEqual(self.valid_origins['R2'], ['R5', 'R6'])
- self.assertEqual(self.valid_origins['R3'], ['R5', 'R6'])
- self.assertEqual(self.valid_origins['R4'], [])
- self.assertEqual(self.valid_origins['R5'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R6'], ['R2', 'R3'])
-
- def test_topology4(self):
- """
-
- +----+ +----+ +----+
- | R2 |------| R3 |------| R4 |
- +----+ +----+ +----+
- | |
- +====+ +----+ +----+
- | R1 |------| R5 |------| R6 |------ R7 (no ls from R7)
- +====+ +----+ +----+
-
- """
- collection = { 'R2': LinkState(None, 'R2', 'area', 1, ['R3']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R1', 'R2', 'R4']),
- 'R4': LinkState(None, 'R4', 'area', 1, ['R3', 'R5']),
- 'R1': LinkState(None, 'R1', 'area', 1, ['R3', 'R5']),
- 'R5': LinkState(None, 'R5', 'area', 1, ['R1', 'R4', 'R6']),
- 'R6': LinkState(None, 'R6', 'area', 1, ['R5', 'R7']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 6)
- self.assertEqual(self.next_hops['R2'], 'R3')
- self.assertEqual(self.next_hops['R3'], 'R3')
- self.assertEqual(self.next_hops['R4'], 'R3')
- self.assertEqual(self.next_hops['R5'], 'R5')
- self.assertEqual(self.next_hops['R6'], 'R5')
- self.assertEqual(self.next_hops['R7'], 'R5')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.valid_origins['R4'].sort()
- self.valid_origins['R5'].sort()
- self.valid_origins['R6'].sort()
- self.valid_origins['R7'].sort()
- self.assertEqual(self.valid_origins['R2'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R3'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R4'], [])
- self.assertEqual(self.valid_origins['R5'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R6'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R7'], ['R2', 'R3'])
-
- def test_topology5(self):
- """
-
- +----+ +----+ +----+
- | R2 |------| R3 |------| R4 |
- +----+ +----+ +----+
- | | |
- | +====+ +----+ +----+
- +--------| R1 |------| R5 |------| R6 |------ R7 (no ls from R7)
- +====+ +----+ +----+
-
- """
- collection = { 'R2': LinkState(None, 'R2', 'area', 1, ['R3', 'R1']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R1', 'R2', 'R4']),
- 'R4': LinkState(None, 'R4', 'area', 1, ['R3', 'R5']),
- 'R1': LinkState(None, 'R1', 'area', 1, ['R3', 'R5', 'R2']),
- 'R5': LinkState(None, 'R5', 'area', 1, ['R1', 'R4', 'R6']),
- 'R6': LinkState(None, 'R6', 'area', 1, ['R5', 'R7']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 6)
- self.assertEqual(self.next_hops['R2'], 'R2')
- self.assertEqual(self.next_hops['R3'], 'R3')
- self.assertEqual(self.next_hops['R4'], 'R3')
- self.assertEqual(self.next_hops['R5'], 'R5')
- self.assertEqual(self.next_hops['R6'], 'R5')
- self.assertEqual(self.next_hops['R7'], 'R5')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.valid_origins['R4'].sort()
- self.valid_origins['R5'].sort()
- self.valid_origins['R6'].sort()
- self.valid_origins['R7'].sort()
- self.assertEqual(self.valid_origins['R2'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R3'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R4'], [])
- self.assertEqual(self.valid_origins['R5'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R6'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R7'], ['R2', 'R3'])
-
- def test_topology5_with_asymmetry1(self):
- """
-
- +----+ +----+ +----+
- | R2 |------| R3 |------| R4 |
- +----+ +----+ +----+
- ^ | |
- ^ +====+ +----+ +----+
- +-<-<-<--| R1 |------| R5 |------| R6 |------ R7 (no ls from R7)
- +====+ +----+ +----+
-
- """
- collection = { 'R2': LinkState(None, 'R2', 'area', 1, ['R3']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R1', 'R2', 'R4']),
- 'R4': LinkState(None, 'R4', 'area', 1, ['R3', 'R5']),
- 'R1': LinkState(None, 'R1', 'area', 1, ['R3', 'R5', 'R2']),
- 'R5': LinkState(None, 'R5', 'area', 1, ['R1', 'R4', 'R6']),
- 'R6': LinkState(None, 'R6', 'area', 1, ['R5', 'R7']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 6)
- self.assertEqual(self.next_hops['R2'], 'R2')
- self.assertEqual(self.next_hops['R3'], 'R3')
- self.assertEqual(self.next_hops['R4'], 'R3')
- self.assertEqual(self.next_hops['R5'], 'R5')
- self.assertEqual(self.next_hops['R6'], 'R5')
- self.assertEqual(self.next_hops['R7'], 'R5')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.valid_origins['R4'].sort()
- self.valid_origins['R5'].sort()
- self.valid_origins['R6'].sort()
- self.valid_origins['R7'].sort()
- self.assertEqual(self.valid_origins['R2'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R3'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R4'], [])
- self.assertEqual(self.valid_origins['R5'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R6'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R7'], ['R2', 'R3'])
-
- def test_topology5_with_asymmetry2(self):
- """
-
- +----+ +----+ +----+
- | R2 |------| R3 |------| R4 |
- +----+ +----+ +----+
- v | |
- v +====+ +----+ +----+
- +->->->->| R1 |------| R5 |------| R6 |------ R7 (no ls from R7)
- +====+ +----+ +----+
-
- """
- collection = { 'R2': LinkState(None, 'R2', 'area', 1, ['R3', 'R1']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R1', 'R2', 'R4']),
- 'R4': LinkState(None, 'R4', 'area', 1, ['R3', 'R5']),
- 'R1': LinkState(None, 'R1', 'area', 1, ['R3', 'R5']),
- 'R5': LinkState(None, 'R5', 'area', 1, ['R1', 'R4', 'R6']),
- 'R6': LinkState(None, 'R6', 'area', 1, ['R5', 'R7']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 6)
- self.assertEqual(self.next_hops['R2'], 'R3')
- self.assertEqual(self.next_hops['R3'], 'R3')
- self.assertEqual(self.next_hops['R4'], 'R3')
- self.assertEqual(self.next_hops['R5'], 'R5')
- self.assertEqual(self.next_hops['R6'], 'R5')
- self.assertEqual(self.next_hops['R7'], 'R5')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.valid_origins['R4'].sort()
- self.valid_origins['R5'].sort()
- self.valid_origins['R6'].sort()
- self.valid_origins['R7'].sort()
- self.assertEqual(self.valid_origins['R2'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R3'], ['R5', 'R6', 'R7'])
- self.assertEqual(self.valid_origins['R4'], [])
- self.assertEqual(self.valid_origins['R5'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R6'], ['R2', 'R3'])
- self.assertEqual(self.valid_origins['R7'], ['R2', 'R3'])
-
- def test_topology5_with_asymmetry3(self):
- """
-
- +----+ +----+ +----+
- | R2 |------| R3 |------| R4 |
- +----+ +----+ +----+
- v | |
- v +====+ +----+ +----+
- +->->->->| R1 |------| R5 |<-<-<-| R6 |------ R7 (no ls from R7)
- +====+ +----+ +----+
-
- """
- collection = { 'R2': LinkState(None, 'R2', 'area', 1, ['R3', 'R1']),
- 'R3': LinkState(None, 'R3', 'area', 1, ['R1', 'R2', 'R4']),
- 'R4': LinkState(None, 'R4', 'area', 1, ['R3', 'R5']),
- 'R1': LinkState(None, 'R1', 'area', 1, ['R3', 'R5']),
- 'R5': LinkState(None, 'R5', 'area', 1, ['R1', 'R4']),
- 'R6': LinkState(None, 'R6', 'area', 1, ['R5', 'R7']) }
- self.engine.ls_collection_changed(collection)
- self.engine.tick(1.0)
- self.assertEqual(len(self.next_hops), 4)
- self.assertEqual(self.next_hops['R2'], 'R3')
- self.assertEqual(self.next_hops['R3'], 'R3')
- self.assertEqual(self.next_hops['R4'], 'R3')
- self.assertEqual(self.next_hops['R5'], 'R5')
-
- self.valid_origins['R2'].sort()
- self.valid_origins['R3'].sort()
- self.valid_origins['R4'].sort()
- self.valid_origins['R5'].sort()
- self.assertEqual(self.valid_origins['R2'], ['R5'])
- self.assertEqual(self.valid_origins['R3'], ['R5'])
- self.assertEqual(self.valid_origins['R4'], [])
- self.assertEqual(self.valid_origins['R5'], ['R2', 'R3'])
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/extras/dispatch/tests/run_unit_tests.c b/extras/dispatch/tests/run_unit_tests.c
deleted file mode 100644
index 2cb75169c1..0000000000
--- a/extras/dispatch/tests/run_unit_tests.c
+++ /dev/null
@@ -1,46 +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/dispatch/buffer.h>
-#include <stdio.h>
-
-int tool_tests();
-int timer_tests();
-int alloc_tests();
-int server_tests();
-int parse_tests();
-int compose_tests();
-
-int main(int argc, char** argv)
-{
- if (argc != 2) {
- fprintf(stderr, "usage: %s <config-file>\n", argv[0]);
- exit(1);
- }
-
- int result = 0;
- result += tool_tests();
- result += timer_tests();
- result += alloc_tests();
- result += server_tests(argv[1]);
- result += parse_tests(0);
- result += compose_tests(0);
- return result;
-}
-
diff --git a/extras/dispatch/tests/run_unit_tests_size.c b/extras/dispatch/tests/run_unit_tests_size.c
deleted file mode 100644
index 1c6a78c38a..0000000000
--- a/extras/dispatch/tests/run_unit_tests_size.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <qpid/dispatch/buffer.h>
-#include "alloc_private.h"
-
-int message_tests();
-int field_tests();
-
-int main(int argc, char** argv)
-{
- ssize_t buffer_size = 512;
-
- if (argc > 1) {
- buffer_size = atoi(argv[1]);
- if (buffer_size < 1)
- return 1;
- }
-
- dx_alloc_initialize();
- dx_buffer_set_size(buffer_size);
-
- int result = 0;
- result += message_tests();
- result += field_tests();
- return result;
-}
-
diff --git a/extras/dispatch/tests/server_test.c b/extras/dispatch/tests/server_test.c
deleted file mode 100644
index 525d8b6a9f..0000000000
--- a/extras/dispatch/tests/server_test.c
+++ /dev/null
@@ -1,209 +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.
- */
-
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-#include "test_case.h"
-#include <qpid/dispatch.h>
-
-#define THREAD_COUNT 4
-#define OCTET_COUNT 100
-
-static const char *config_file;
-static dx_dispatch_t *dx;
-static sys_mutex_t *test_lock;
-
-static void *expected_context;
-static int call_count;
-static int threads_seen[THREAD_COUNT];
-static char stored_error[512];
-
-static int write_count;
-static int read_count;
-static int fd[2];
-static dx_user_fd_t *ufd_write;
-static dx_user_fd_t *ufd_read;
-
-
-static void thread_start_handler(void *context, int thread_id)
-{
- sys_mutex_lock(test_lock);
- if (context != expected_context && !stored_error[0])
- sprintf(stored_error, "Unexpected Context Value: %lx", (long) context);
- if (thread_id >= THREAD_COUNT && !stored_error[0])
- sprintf(stored_error, "Thread_ID too large: %d", thread_id);
- if (thread_id < 0 && !stored_error[0])
- sprintf(stored_error, "Thread_ID negative: %d", thread_id);
-
- call_count++;
- if (thread_id >= 0 && thread_id < THREAD_COUNT)
- threads_seen[thread_id]++;
-
- if (call_count == THREAD_COUNT)
- dx_server_stop(dx);
- sys_mutex_unlock(test_lock);
-}
-
-
-static void ufd_handler(void *context, dx_user_fd_t *ufd)
-{
- long dir = (long) context;
- char buffer;
- ssize_t len;
- static int in_read = 0;
- static int in_write = 0;
-
- if (dir == 0) { // READ
- in_read++;
- assert(in_read == 1);
- if (!dx_user_fd_is_readable(ufd_read)) {
- sprintf(stored_error, "Expected Readable");
- dx_server_stop(dx);
- } else {
- len = read(fd[0], &buffer, 1);
- if (len == 1) {
- read_count++;
- if (read_count == OCTET_COUNT)
- dx_server_stop(dx);
- }
- dx_user_fd_activate_read(ufd_read);
- }
- in_read--;
- } else { // WRITE
- in_write++;
- assert(in_write == 1);
- if (!dx_user_fd_is_writeable(ufd_write)) {
- sprintf(stored_error, "Expected Writable");
- dx_server_stop(dx);
- } else {
- write(fd[1], "X", 1);
-
- write_count++;
- if (write_count < OCTET_COUNT)
- dx_user_fd_activate_write(ufd_write);
- }
- in_write--;
- }
-}
-
-
-static void fd_test_start(void *context)
-{
- dx_user_fd_activate_read(ufd_read);
-}
-
-
-static char* test_start_handler(void *context)
-{
- int i;
-
- dx = dx_dispatch(config_file);
-
- expected_context = (void*) 0x00112233;
- stored_error[0] = 0x0;
- call_count = 0;
- for (i = 0; i < THREAD_COUNT; i++)
- threads_seen[i] = 0;
-
- dx_server_set_start_handler(dx, thread_start_handler, expected_context);
- dx_server_run(dx);
- dx_dispatch_free(dx);
-
- if (stored_error[0]) return stored_error;
- if (call_count != THREAD_COUNT) return "Incorrect number of thread-start callbacks";
- for (i = 0; i < THREAD_COUNT; i++)
- if (threads_seen[i] != 1) return "Incorrect count on one thread ID";
-
- return 0;
-}
-
-
-static char *test_server_start(void *context)
-{
- dx = dx_dispatch(config_file);
- dx_server_start(dx);
- dx_server_stop(dx);
- dx_dispatch_free(dx);
-
- return 0;
-}
-
-
-static char* test_user_fd(void *context)
-{
- int res;
- dx_timer_t *timer;
-
- dx = dx_dispatch(config_file);
- dx_server_set_user_fd_handler(dx, ufd_handler);
- timer = dx_timer(dx, fd_test_start, 0);
- dx_timer_schedule(timer, 0);
-
- stored_error[0] = 0x0;
-
- res = pipe(fd); // Don't use pipe2 because it's not available on RHEL5
- if (res != 0) return "Error creating pipe2";
-
- for (int i = 0; i < 2; i++) {
- int flags = fcntl(fd[i], F_GETFL);
- flags |= O_NONBLOCK;
- if (fcntl(fd[i], F_SETFL, flags) < 0) {
- perror("fcntl");
- return "Failed to set socket to non-blocking";
- }
- }
-
- ufd_write = dx_user_fd(dx, fd[1], (void*) 1);
- ufd_read = dx_user_fd(dx, fd[0], (void*) 0);
-
- dx_server_run(dx);
- dx_timer_free(timer);
- dx_dispatch_free(dx);
- close(fd[0]);
- close(fd[1]);
-
- if (stored_error[0]) return stored_error;
- if (write_count - OCTET_COUNT > 2) sprintf(stored_error, "Excessively high Write Count: %d", write_count);
- if (read_count != OCTET_COUNT) sprintf(stored_error, "Incorrect Read Count: %d", read_count);;
-
- if (stored_error[0]) return stored_error;
- return 0;
-}
-
-
-int server_tests(const char *_config_file)
-{
- int result = 0;
- test_lock = sys_mutex();
- dx_log_set_mask(LOG_NONE);
-
- config_file = _config_file;
-
- TEST_CASE(test_server_start, 0);
- TEST_CASE(test_start_handler, 0);
- TEST_CASE(test_user_fd, 0);
-
- sys_mutex_free(test_lock);
- return result;
-}
-
diff --git a/extras/dispatch/tests/system_tests_one_router.py b/extras/dispatch/tests/system_tests_one_router.py
deleted file mode 100644
index 59e2569eff..0000000000
--- a/extras/dispatch/tests/system_tests_one_router.py
+++ /dev/null
@@ -1,452 +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 os
-import time
-import unittest
-import subprocess
-from proton import Messenger, Message, PENDING, ACCEPTED, REJECTED
-
-class RouterTest(unittest.TestCase):
-
- def setUp(self):
- if 'CTEST_SOURCE_DIR' not in os.environ:
- raise Exception("Environment variable 'CTEST_SOURCE_DIR' not set")
- srcdir = os.environ['CTEST_SOURCE_DIR']
- self.router = subprocess.Popen(['../router/dispatch-router', '-c', '%s/config-1/A.conf' % srcdir],
- stderr=subprocess.PIPE, stdout=subprocess.PIPE)
- time.sleep(1)
-
- def tearDown(self):
- self.router.terminate()
- self.router.wait()
-
- def flush(self, messenger):
- while messenger.work(0.1):
- pass
-
- def subscribe(self, messenger, address):
- messenger.subscribe(address)
- self.flush(messenger)
-
-
- def test_0_discard(self):
- addr = "amqp://0.0.0.0:20000/discard/1"
- M1 = Messenger()
- M1.timeout = 1.0
- M1.start()
- tm = Message()
- tm.address = addr
- for i in range(100):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
- M1.stop()
-
-
- def test_1_pre_settled(self):
- addr = "amqp://0.0.0.0:20000/pre_settled/1"
- M1 = Messenger()
- M2 = Messenger()
-
- M1.timeout = 1.0
- M2.timeout = 1.0
-
- M1.start()
- M2.start()
- self.subscribe(M2, addr)
-
- tm = Message()
- rm = Message()
-
- tm.address = addr
- for i in range(100):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
-
- for i in range(100):
- M2.recv(1)
- M2.get(rm)
- self.assertEqual(i, rm.body['number'])
-
- M1.stop()
- M2.stop()
-
-
- def test_2_multicast(self):
- addr = "amqp://0.0.0.0:20000/pre_settled/multicast/1"
- M1 = Messenger()
- M2 = Messenger()
- M3 = Messenger()
- M4 = Messenger()
-
- M1.timeout = 1.0
- M2.timeout = 1.0
- M3.timeout = 1.0
- M4.timeout = 1.0
-
- M1.start()
- M2.start()
- M3.start()
- M4.start()
- self.subscribe(M2, addr)
- self.subscribe(M3, addr)
- self.subscribe(M4, addr)
-
- tm = Message()
- rm = Message()
-
- tm.address = addr
- for i in range(100):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
-
- for i in range(100):
- M2.recv(1)
- M2.get(rm)
- self.assertEqual(i, rm.body['number'])
-
- M3.recv(1)
- M3.get(rm)
- self.assertEqual(i, rm.body['number'])
-
- M4.recv(1)
- M4.get(rm)
- self.assertEqual(i, rm.body['number'])
-
- M1.stop()
- M2.stop()
- M3.stop()
- M4.stop()
-
-
- def test_2a_multicast_unsettled(self):
- addr = "amqp://0.0.0.0:20000/pre_settled/multicast/1"
- M1 = Messenger()
- M2 = Messenger()
- M3 = Messenger()
- M4 = Messenger()
-
- M1.timeout = 1.0
- M2.timeout = 1.0
- M3.timeout = 1.0
- M4.timeout = 1.0
-
- M1.outgoing_window = 5
- M2.incoming_window = 5
- M3.incoming_window = 5
- M4.incoming_window = 5
-
- M1.start()
- M2.start()
- M3.start()
- M4.start()
- self.subscribe(M2, addr)
- self.subscribe(M3, addr)
- self.subscribe(M4, addr)
-
- tm = Message()
- rm = Message()
-
- tm.address = addr
- for i in range(2):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send(0)
-
- for i in range(2):
- M2.recv(1)
- trk = M2.get(rm)
- M2.accept(trk)
- M2.settle(trk)
- self.assertEqual(i, rm.body['number'])
-
- M3.recv(1)
- trk = M3.get(rm)
- M3.accept(trk)
- M3.settle(trk)
- self.assertEqual(i, rm.body['number'])
-
- M4.recv(1)
- trk = M4.get(rm)
- M4.accept(trk)
- M4.settle(trk)
- self.assertEqual(i, rm.body['number'])
-
- M1.stop()
- M2.stop()
- M3.stop()
- M4.stop()
-
-
- def test_3_propagated_disposition(self):
- addr = "amqp://0.0.0.0:20000/unsettled/1"
- M1 = Messenger()
- M2 = Messenger()
-
- M1.timeout = 1.0
- M2.timeout = 1.0
- M1.outgoing_window = 5
- M2.incoming_window = 5
-
- M1.start()
- M2.start()
- self.subscribe(M2, addr)
-
- tm = Message()
- rm = Message()
-
- tm.address = addr
- tm.body = {'number': 0}
-
- ##
- ## Test ACCEPT
- ##
- tx_tracker = M1.put(tm)
- M1.send(0)
- M2.recv(1)
- rx_tracker = M2.get(rm)
- self.assertEqual(0, rm.body['number'])
- self.assertEqual(PENDING, M1.status(tx_tracker))
-
- M2.accept(rx_tracker)
- M2.settle(rx_tracker)
-
- self.flush(M2)
- self.flush(M1)
-
- self.assertEqual(ACCEPTED, M1.status(tx_tracker))
-
- ##
- ## Test REJECT
- ##
- tx_tracker = M1.put(tm)
- M1.send(0)
- M2.recv(1)
- rx_tracker = M2.get(rm)
- self.assertEqual(0, rm.body['number'])
- self.assertEqual(PENDING, M1.status(tx_tracker))
-
- M2.reject(rx_tracker)
- M2.settle(rx_tracker)
-
- self.flush(M2)
- self.flush(M1)
-
- self.assertEqual(REJECTED, M1.status(tx_tracker))
-
- M1.stop()
- M2.stop()
-
-
- def test_4_unsettled_undeliverable(self):
- addr = "amqp://0.0.0.0:20000/unsettled_undeliverable/1"
- M1 = Messenger()
-
- M1.timeout = 1.0
- M1.outgoing_window = 5
-
- M1.start()
- tm = Message()
- tm.address = addr
- tm.body = {'number': 200}
-
- tx_tracker = M1.put(tm)
- M1.send(0)
- self.flush(M1)
- self.assertEqual(PENDING, M1.status(tx_tracker)) ## Is this right???
-
- M1.stop()
-
-
- def test_5_three_ack(self):
- addr = "amqp://0.0.0.0:20000/three_ack/1"
- M1 = Messenger()
- M2 = Messenger()
-
- M1.timeout = 1.0
- M2.timeout = 1.0
- M1.outgoing_window = 5
- M2.incoming_window = 5
-
- M1.start()
- M2.start()
- self.subscribe(M2, addr)
-
- tm = Message()
- rm = Message()
-
- tm.address = addr
- tm.body = {'number': 200}
-
- tx_tracker = M1.put(tm)
- M1.send(0)
- M2.recv(1)
- rx_tracker = M2.get(rm)
- self.assertEqual(200, rm.body['number'])
- self.assertEqual(PENDING, M1.status(tx_tracker))
-
- M2.accept(rx_tracker)
-
- self.flush(M2)
- self.flush(M1)
-
- self.assertEqual(ACCEPTED, M1.status(tx_tracker))
-
- M1.settle(tx_tracker)
-
- self.flush(M1)
- self.flush(M2)
-
- ##
- ## We need a way to verify on M2 (receiver) that the tracker has been
- ## settled on the M1 (sender). [ See PROTON-395 ]
- ##
-
- M2.settle(rx_tracker)
-
- self.flush(M2)
- self.flush(M1)
-
- M1.stop()
- M2.stop()
-
-
-# def test_6_link_route_sender(self):
-# pass
-
-# def test_7_link_route_receiver(self):
-# pass
-
-
- def test_8_delivery_annotations(self):
- addr = "amqp://0.0.0.0:20000/da/1"
- M1 = Messenger()
- M2 = Messenger()
-
- M1.timeout = 1.0
- M2.timeout = 1.0
-
- M1.start()
- M2.start()
- self.subscribe(M2, addr)
-
- tm = Message()
- rm = Message()
-
- tm.address = addr
-
-
- ##
- ## No inbound delivery annotations
- ##
- for i in range(10):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
-
- for i in range(10):
- M2.recv(1)
- M2.get(rm)
- self.assertEqual(i, rm.body['number'])
- da = rm.instructions
- self.assertEqual(da.__class__, dict)
- self.assertEqual(da['qdx.ingress'], '0/Qpid.Dispatch.Router.A')
- self.assertEqual(da['qdx.trace'], ['0/Qpid.Dispatch.Router.A'])
-
- ##
- ## Pre-existing ingress
- ##
- tm.instructions = {'qdx.ingress': 'ingress-router'}
- for i in range(10):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
-
- for i in range(10):
- M2.recv(1)
- M2.get(rm)
- self.assertEqual(i, rm.body['number'])
- da = rm.instructions
- self.assertEqual(da.__class__, dict)
- self.assertEqual(da['qdx.ingress'], 'ingress-router')
- self.assertEqual(da['qdx.trace'], ['0/Qpid.Dispatch.Router.A'])
-
- ##
- ## Invalid trace type
- ##
- tm.instructions = {'qdx.trace' : 45}
- for i in range(10):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
-
- for i in range(10):
- M2.recv(1)
- M2.get(rm)
- self.assertEqual(i, rm.body['number'])
- da = rm.instructions
- self.assertEqual(da.__class__, dict)
- self.assertEqual(da['qdx.ingress'], '0/Qpid.Dispatch.Router.A')
- self.assertEqual(da['qdx.trace'], ['0/Qpid.Dispatch.Router.A'])
-
- ##
- ## Empty trace
- ##
- tm.instructions = {'qdx.trace' : []}
- for i in range(10):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
-
- for i in range(10):
- M2.recv(1)
- M2.get(rm)
- self.assertEqual(i, rm.body['number'])
- da = rm.instructions
- self.assertEqual(da.__class__, dict)
- self.assertEqual(da['qdx.ingress'], '0/Qpid.Dispatch.Router.A')
- self.assertEqual(da['qdx.trace'], ['0/Qpid.Dispatch.Router.A'])
-
- ##
- ## Non-empty trace
- ##
- tm.instructions = {'qdx.trace' : ['0/first.hop']}
- for i in range(10):
- tm.body = {'number': i}
- M1.put(tm)
- M1.send()
-
- for i in range(10):
- M2.recv(1)
- M2.get(rm)
- self.assertEqual(i, rm.body['number'])
- da = rm.instructions
- self.assertEqual(da.__class__, dict)
- self.assertEqual(da['qdx.ingress'], '0/Qpid.Dispatch.Router.A')
- self.assertEqual(da['qdx.trace'], ['0/first.hop', '0/Qpid.Dispatch.Router.A'])
-
- M1.stop()
- M2.stop()
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/extras/dispatch/tests/test_case.h b/extras/dispatch/tests/test_case.h
deleted file mode 100644
index 6e36b440a5..0000000000
--- a/extras/dispatch/tests/test_case.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef _nexus_test_case_h_
-#define _nexus_test_case_h_ 1
-/*
- * 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.
- */
-
-typedef char* (*testcase_t)(void *context);
-
-#define TEST_CASE(T,C) do { \
- char *r = T(C); \
- printf("Test Case %s.%s: ", __FUNCTION__, #T); \
- if (r) { \
- printf("FAIL: %s\n", r); \
- result++; \
- } else \
- printf("PASS\n"); \
-} while(0);
-
-
-#endif
-
diff --git a/extras/dispatch/tests/threads4.conf b/extras/dispatch/tests/threads4.conf
deleted file mode 100644
index 1466e11cca..0000000000
--- a/extras/dispatch/tests/threads4.conf
+++ /dev/null
@@ -1,26 +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
-##
-
-
-##
-## Container section - Configures the general operation of the AMQP container.
-##
-container {
- worker-threads: 4
-}
diff --git a/extras/dispatch/tests/timer_test.c b/extras/dispatch/tests/timer_test.c
deleted file mode 100644
index 93725dde4b..0000000000
--- a/extras/dispatch/tests/timer_test.c
+++ /dev/null
@@ -1,413 +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 <stdio.h>
-#include <qpid/dispatch/timer.h>
-#include "alloc_private.h"
-#include "timer_private.h"
-#include "test_case.h"
-#include <qpid/dispatch/threading.h>
-
-
-static unsigned long fire_mask;
-static dx_timer_list_t pending_timers;
-static sys_mutex_t *lock;
-static long time;
-static dx_timer_t *timers[16];
-
-
-void dx_server_timer_pending_LH(dx_timer_t *timer)
-{
- DEQ_INSERT_TAIL(pending_timers, timer);
-}
-
-
-void dx_server_timer_cancel_LH(dx_timer_t *timer)
-{
- if (timer->state == TIMER_PENDING)
- DEQ_REMOVE(pending_timers, timer);
-}
-
-
-static int fire_head()
-{
- sys_mutex_lock(lock);
- int result = DEQ_SIZE(pending_timers);
- dx_timer_t *timer = DEQ_HEAD(pending_timers);
- if (timer) {
- DEQ_REMOVE_HEAD(pending_timers);
- dx_timer_idle_LH(timer);
- fire_mask |= (unsigned long) timer->context;
- }
- sys_mutex_unlock(lock);
- return result;
-}
-
-
-static char* test_quiet(void *context)
-{
- fire_mask = 0;
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
-
- while(fire_head());
-
- if (fire_mask != 0)
- return "Expected zero timers fired";
- return 0;
-}
-
-static char* test_immediate(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 0);
-
- if (fire_mask != 0) return "Premature firing";
- if (fire_head() > 1) return "Too many firings";
- if (fire_mask != 1) return "Incorrect fire mask";
-
- return 0;
-}
-
-
-static char* test_immediate_reschedule(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 0);
- dx_timer_schedule(timers[0], 0);
-
- if (fire_mask != 0) return "pass 1 - Premature firing";
- if (fire_head() > 1) return "pass 1 - Too many firings";
- if (fire_mask != 1) return "pass 1 - Incorrect fire mask";
-
- fire_mask = 0;
- dx_timer_schedule(timers[0], 0);
- dx_timer_schedule(timers[0], 0);
-
- if (fire_mask != 0) return "pass 2 - Premature firing";
- if (fire_head() > 1) return "pass 2 - Too many firings";
- if (fire_mask != 1) return "pass 2 - Incorrect fire mask";
-
- return 0;
-}
-
-
-static char* test_immediate_plus_delayed(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 0);
- dx_timer_schedule(timers[1], 5);
-
- if (fire_mask != 0) return "Premature firing";
- if (fire_head() > 1) return "Too many firings";
- if (fire_mask != 1) return "Incorrect fire mask 1";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- time += 8;
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
-
- if (fire_head() < 1) return "Delayed Failed to fire";
- if (fire_mask != 3) return "Incorrect fire mask 3";
-
- return 0;
-}
-
-
-static char* test_single(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 2);
- if (fire_head() > 0) return "Premature firing 1";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- if (fire_head() > 0) return "Premature firing 2";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- if (fire_head() < 1) return "Failed to fire";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- if (fire_head() != 0) return "Spurious fires";
-
- if (fire_mask != 1) return "Incorrect fire mask";
- if (timers[0]->state != TIMER_IDLE) return "Expected idle timer state";
-
- return 0;
-}
-
-
-static char* test_two_inorder(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 2);
- dx_timer_schedule(timers[1], 4);
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- int count = fire_head();
- if (count < 1) return "First failed to fire";
- if (count > 1) return "Second fired prematurely";
- if (fire_mask != 1) return "Incorrect fire mask 1";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- if (fire_head() < 1) return "Second failed to fire";
- if (fire_mask != 3) return "Incorrect fire mask 3";
-
- return 0;
-}
-
-
-static char* test_two_reverse(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 4);
- dx_timer_schedule(timers[1], 2);
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- int count = fire_head();
- if (count < 1) return "First failed to fire";
- if (count > 1) return "Second fired prematurely";
- if (fire_mask != 2) return "Incorrect fire mask 2";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- if (fire_head() < 1) return "Second failed to fire";
- if (fire_mask != 3) return "Incorrect fire mask 3";
-
- return 0;
-}
-
-
-static char* test_two_duplicate(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 2);
- dx_timer_schedule(timers[1], 2);
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- int count = fire_head();
- if (count != 2) return "Expected two firings";
- fire_head();
- if (fire_mask != 3) return "Incorrect fire mask 3";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- if (fire_head() > 0) return "Spurious timer fires";
-
- return 0;
-}
-
-
-static char* test_separated(void *context)
-{
- int count;
-
- while(fire_head());
- fire_mask = 0;
-
- dx_timer_schedule(timers[0], 2);
- dx_timer_schedule(timers[1], 4);
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- count = fire_head();
- if (count < 1) return "First failed to fire";
- if (count > 1) return "Second fired prematurely";
- if (fire_mask != 1) return "Incorrect fire mask 1";
-
- dx_timer_schedule(timers[2], 2);
- dx_timer_schedule(timers[3], 4);
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- count = fire_head();
- fire_head();
- if (count < 1) return "Second failed to fire";
- if (count < 2) return "Third failed to fire";
- if (fire_mask != 7) return "Incorrect fire mask 7";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- count = fire_head();
- if (count < 1) return "Fourth failed to fire";
- if (fire_mask != 15) return "Incorrect fire mask 15";
-
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- count = fire_head();
- if (count > 0) return "Spurious fire";
-
- return 0;
-}
-
-
-static char* test_big(void *context)
-{
- while(fire_head());
- fire_mask = 0;
-
- long durations[16] =
- { 5, 8, 7, 6,
- 14, 10, 16, 15,
- 11, 12, 9, 12,
- 1, 2, 3, 4};
- unsigned long masks[18] = {
- 0x1000,
- 0x3000,
- 0x7000,
- 0xf000,
- 0xf001,
- 0xf009,
- 0xf00d,
- 0xf00f,
- 0xf40f,
- 0xf42f,
- 0xf52f,
- 0xff2f,
- 0xff2f,
- 0xff3f,
- 0xffbf,
- 0xffff,
- 0xffff,
- 0xffff
- };
-
- int i;
- for (i = 0; i < 16; i++)
- dx_timer_schedule(timers[i], durations[i]);
- for (i = 0; i < 18; i++) {
- sys_mutex_lock(lock);
- dx_timer_visit_LH(time++);
- sys_mutex_unlock(lock);
- while(fire_head());
- if (fire_mask != masks[i]) {
- static char error[100];
- sprintf(error, "Iteration %d: expected mask %04lx, got %04lx", i, masks[i], fire_mask);
- return error;
- }
- }
-
- return 0;
-}
-
-
-int timer_tests(void)
-{
- int result = 0;
- dx_alloc_initialize();
-
- fire_mask = 0;
- DEQ_INIT(pending_timers);
- lock = sys_mutex();
- dx_timer_initialize(lock);
- time = 1;
-
- timers[0] = dx_timer(0, 0, (void*) 0x00000001);
- timers[1] = dx_timer(0, 0, (void*) 0x00000002);
- timers[2] = dx_timer(0, 0, (void*) 0x00000004);
- timers[3] = dx_timer(0, 0, (void*) 0x00000008);
- timers[4] = dx_timer(0, 0, (void*) 0x00000010);
- timers[5] = dx_timer(0, 0, (void*) 0x00000020);
- timers[6] = dx_timer(0, 0, (void*) 0x00000040);
- timers[7] = dx_timer(0, 0, (void*) 0x00000080);
- timers[8] = dx_timer(0, 0, (void*) 0x00000100);
- timers[9] = dx_timer(0, 0, (void*) 0x00000200);
- timers[10] = dx_timer(0, 0, (void*) 0x00000400);
- timers[11] = dx_timer(0, 0, (void*) 0x00000800);
- timers[12] = dx_timer(0, 0, (void*) 0x00001000);
- timers[13] = dx_timer(0, 0, (void*) 0x00002000);
- timers[14] = dx_timer(0, 0, (void*) 0x00004000);
- timers[15] = dx_timer(0, 0, (void*) 0x00008000);
-
- TEST_CASE(test_quiet, 0);
- TEST_CASE(test_immediate, 0);
- TEST_CASE(test_immediate_reschedule, 0);
- TEST_CASE(test_immediate_plus_delayed, 0);
- TEST_CASE(test_single, 0);
- TEST_CASE(test_two_inorder, 0);
- TEST_CASE(test_two_reverse, 0);
- TEST_CASE(test_two_duplicate, 0);
- TEST_CASE(test_separated, 0);
- TEST_CASE(test_big, 0);
-
- int i;
- for (i = 0; i < 16; i++)
- dx_timer_free(timers[i]);
-
- dx_timer_finalize();
-
- return result;
-}
-
diff --git a/extras/dispatch/tests/tool_test.c b/extras/dispatch/tests/tool_test.c
deleted file mode 100644
index 2c90714b3d..0000000000
--- a/extras/dispatch/tests/tool_test.c
+++ /dev/null
@@ -1,233 +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 "test_case.h"
-#include <stdio.h>
-#include <string.h>
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/bitmask.h>
-#include "alloc_private.h"
-
-typedef struct item_t {
- DEQ_LINKS(struct item_t);
- char letter;
-} item_t;
-
-DEQ_DECLARE(item_t, item_list_t);
-
-
-static char* list_well_formed(item_list_t list, char *key)
-{
- item_t *ptr;
- item_t *last = 0;
- int size = DEQ_SIZE(list);
- int count = 0;
- char str[32];
-
- ptr = DEQ_HEAD(list);
- while (ptr) {
- str[count] = ptr->letter;
- count++;
- if (DEQ_PREV(ptr) != last) return "Corrupt previous link";
- last = ptr;
- ptr = DEQ_NEXT(ptr);
- }
- str[count] = '\0';
- if (strcmp(str, key) != 0) return "Invalid key";
-
- if (count != size) return "Size different from number of items (forward)";
-
- count = 0;
- last = 0;
- ptr = DEQ_TAIL(list);
- while (ptr) {
- count++;
- if (DEQ_NEXT(ptr) != last) return "Corrupt next link";
- last = ptr;
- ptr = DEQ_PREV(ptr);
- }
-
- if (count != size) return "Size different from number of items (backward)";
-
- return 0;
-}
-
-
-static char* test_deq_basic(void *context)
-{
- item_list_t list;
- item_t item[10];
- item_t *ptr;
- int idx;
- char *subtest;
-
- DEQ_INIT(list);
- if (DEQ_SIZE(list) != 0) return "Expected zero initial size";
-
- for (idx = 0; idx < 10; idx++) {
- DEQ_ITEM_INIT(&item[idx]);
- item[idx].letter = 'A' + idx;
- DEQ_INSERT_TAIL(list, &item[idx]);
- }
- if (DEQ_SIZE(list) != 10) return "Expected 10 items in list";
-
- ptr = DEQ_HEAD(list);
- if (!ptr) return "Expected valid head item";
- if (DEQ_PREV(ptr)) return "Head item has non-null previous link";
- if (ptr->letter != 'A') return "Expected item A at the head";
- if (DEQ_NEXT(ptr) == 0) return "Head item has null next link";
- subtest = list_well_formed(list, "ABCDEFGHIJ");
- if (subtest) return subtest;
-
- DEQ_REMOVE_HEAD(list);
- if (DEQ_SIZE(list) != 9) return "Expected 9 items in list";
- ptr = DEQ_HEAD(list);
- if (ptr->letter != 'B') return "Expected item B at the head";
- subtest = list_well_formed(list, "BCDEFGHIJ");
- if (subtest) return subtest;
-
- DEQ_REMOVE_TAIL(list);
- if (DEQ_SIZE(list) != 8) return "Expected 8 items in list";
- ptr = DEQ_TAIL(list);
- if (ptr->letter != 'I') return "Expected item I at the tail";
- subtest = list_well_formed(list, "BCDEFGHI");
- if (subtest) return subtest;
-
- DEQ_REMOVE(list, &item[4]);
- if (DEQ_SIZE(list) != 7) return "Expected 7 items in list";
- subtest = list_well_formed(list, "BCDFGHI");
- if (subtest) return subtest;
-
- DEQ_REMOVE(list, &item[1]);
- if (DEQ_SIZE(list) != 6) return "Expected 6 items in list";
- subtest = list_well_formed(list, "CDFGHI");
- if (subtest) return subtest;
-
- DEQ_REMOVE(list, &item[8]);
- if (DEQ_SIZE(list) != 5) return "Expected 5 items in list";
- subtest = list_well_formed(list, "CDFGH");
- if (subtest) return subtest;
-
- DEQ_INSERT_HEAD(list, &item[8]);
- if (DEQ_SIZE(list) != 6) return "Expected 6 items in list";
- ptr = DEQ_HEAD(list);
- if (ptr->letter != 'I') return "Expected item I at the head";
- subtest = list_well_formed(list, "ICDFGH");
- if (subtest) return subtest;
-
- DEQ_INSERT_AFTER(list, &item[4], &item[7]);
- if (DEQ_SIZE(list) != 7) return "Expected 7 items in list";
- ptr = DEQ_TAIL(list);
- if (ptr->letter != 'E') return "Expected item E at the head";
- subtest = list_well_formed(list, "ICDFGHE");
- if (subtest) return subtest;
-
- DEQ_INSERT_AFTER(list, &item[1], &item[5]);
- if (DEQ_SIZE(list) != 8) return "Expected 8 items in list";
- subtest = list_well_formed(list, "ICDFBGHE");
- if (subtest) return subtest;
-
- if (item[0].prev || item[0].next) return "Unlisted item A has non-null pointers";
- if (item[9].prev || item[9].next) return "Unlisted item J has non-null pointers";
-
- return 0;
-}
-
-
-static char* test_deq_basic2(void *context)
-{
- item_list_t list;
- item_t item[10];
- item_t *ptr;
- int idx;
- char *subtest;
-
- DEQ_INIT(list);
- if (DEQ_SIZE(list) != 0) return "Expected zero initial size";
-
- for (idx = 0; idx < 10; idx++) {
- DEQ_ITEM_INIT(&item[idx]);
- item[idx].letter = '0' + idx;
- }
-
- DEQ_INSERT_TAIL(list, &item[0]);
- if (DEQ_SIZE(list) != 1) return "Expected 1 items in list";
- subtest = list_well_formed(list, "0");
- if (subtest) return subtest;
-
- ptr = DEQ_HEAD(list);
- DEQ_REMOVE_HEAD(list);
- if (ptr->letter != '0') return "Expected item '0'";
- if (DEQ_SIZE(list) != 0) return "Expected 0 items in list";
-
- DEQ_INSERT_TAIL(list, &item[0]);
- if (DEQ_SIZE(list) != 1) return "Expected 1 items in list";
- subtest = list_well_formed(list, "0");
- if (subtest) return subtest;
-
- ptr = DEQ_HEAD(list);
- DEQ_REMOVE_HEAD(list);
- if (ptr->letter != '0') return "Expected item '0'";
- if (DEQ_SIZE(list) != 0) return "Expected 0 items in list";
-
- return 0;
-}
-
-
-static char* test_bitmask(void *context)
-{
- dx_bitmask_t *bm;
- int num;
-
- bm = dx_bitmask(0);
- if (!bm) return "Can't allocate a bit mask";
- if (dx_bitmask_first_set(bm, &num)) return "Expected no first set bit";
-
- dx_bitmask_set_bit(bm, 3);
- dx_bitmask_set_bit(bm, 500);
-
- if (!dx_bitmask_first_set(bm, &num)) return "Expected first set bit";
- if (num != 3) return "Expected first set bit to be 3";
-
- dx_bitmask_clear_bit(bm, num);
-
- if (!dx_bitmask_first_set(bm, &num)) return "Expected first set bit (2)";
- if (num != 500) return "Expected first set bit to be 500";
-
- dx_bitmask_clear_bit(bm, num);
- if (dx_bitmask_first_set(bm, &num)) return "Expected no first set bit (2)";
-
- dx_bitmask_free(bm);
-
- return 0;
-}
-
-
-int tool_tests(void)
-{
- int result = 0;
- dx_alloc_initialize();
-
- TEST_CASE(test_deq_basic, 0);
- TEST_CASE(test_deq_basic2, 0);
- TEST_CASE(test_bitmask, 0);
-
- return result;
-}
-
diff --git a/extras/dispatch/tools/src/py/qdstat b/extras/dispatch/tools/src/py/qdstat
deleted file mode 100755
index 32594b4d4e..0000000000
--- a/extras/dispatch/tools/src/py/qdstat
+++ /dev/null
@@ -1,328 +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 os
-from optparse import OptionParser, OptionGroup
-import sys
-import locale
-import socket
-import re
-from proton import Messenger, Message
-
-home = os.environ.get("QD_TOOLS_HOME", os.path.normpath("/usr/share/qd-tools"))
-sys.path.append(os.path.join(home, "python"))
-
-from qdtoollibs import Display, Header, Sorter, YN, Commas, TimeLong
-
-
-class Config:
- def __init__(self):
- self._host = "0.0.0.0"
- self._connTimeout = 10
- self._types = ""
- self._limit = 50
- self._increasing = False
- self._sortcol = None
-
-config = Config()
-conn_options = {}
-
-def OptionsAndArguments(argv):
- """ Set global variables for options, return arguments """
-
- global config
- global conn_options
-
- usage = \
-"""%prog -g [options]
- %prog -c [options]
- %prog -l [options]
- %prog -n [options]
- %prog -a [options]
- %prog -m [options]"""
-
- parser = OptionParser(usage=usage)
-
- group1 = OptionGroup(parser, "General Options")
- group1.add_option("-b", "--bus", action="store", type="string", default="0.0.0.0", metavar="<url>",
- help="URL of the messaging bus to connect to")
- group1.add_option("-t", "--timeout", action="store", type="int", default=10, metavar="<secs>",
- help="Maximum time to wait for connection (in seconds)")
- group1.add_option("--sasl-mechanism", action="store", type="string", metavar="<mech>",
- help="SASL mechanism for authentication (e.g. EXTERNAL, ANONYMOUS, PLAIN, CRAM-MD5, DIGEST-MD5, GSSAPI). SASL automatically picks the most secure available mechanism - use this option to override.")
- group1.add_option("--ssl-certificate", action="store", type="string", metavar="<cert>", help="Client SSL certificate (PEM Format)")
- group1.add_option("--ssl-key", action="store", type="string", metavar="<key>", help="Client SSL private key (PEM Format)")
- parser.add_option_group(group1)
-
- group2 = OptionGroup(parser, "Command Options")
- group2.add_option("-g", "--general", help="Show General Broker Stats", action="store_const", const="g", dest="show")
- group2.add_option("-c", "--connections", help="Show Connections", action="store_const", const="c", dest="show")
- group2.add_option("-l", "--links", help="Show Router Links", action="store_const", const="l", dest="show")
- group2.add_option("-n", "--nodes", help="Show Router Nodes", action="store_const", const="n", dest="show")
- group2.add_option("-a", "--address", help="Show Router Addresses", action="store_const", const="a", dest="show")
- group2.add_option("-m", "--memory", help="Show Broker Memory Stats", action="store_const", const="m", dest="show")
- parser.add_option_group(group2)
-
- opts, args = parser.parse_args(args=argv)
-
- if not opts.show:
- parser.error("You must specify one of these options: -g, -c, -l, -n, -a, or -m. For details, try $ qdstat --help")
-
- config._types = opts.show
- config._host = opts.bus
- config._connTimeout = opts.timeout
-
- return args
-
-
-class BusManager:
- def __init__(self):
- pass
-
- def SetHost(self, host):
- self.M = Messenger()
- self.M.start()
- self.M.route("amqp:/*", "amqp://%s/$1" % host)
- self.address = "amqp:/_local/$management"
- self.reply = "amqp:/temp.reply-address/0001" # FIX THIS!
- self.M.subscribe(self.reply)
-
- def Disconnect(self):
- self.M.stop()
-
- def displayConn(self):
- pass
-
- def _addr_class(self, addr):
- if not addr:
- return "-"
- if addr[0] == 'M' : return "mobile"
- if addr[0] == 'R' : return "router"
- if addr[0] == 'A' : return "area"
- if addr[0] == 'L' : return "local"
- return "unknown: %s" % addr[0]
-
- def _addr_text(self, addr):
- if not addr:
- return "-"
- return addr[1:]
-
- def displayRouterLinks(self):
- disp = Display(prefix=" ")
- heads = []
- heads.append(Header("type"))
- heads.append(Header("dir"))
- heads.append(Header("rindex"))
- heads.append(Header("class"))
- heads.append(Header("addr"))
- rows = []
-
- request = Message()
- response = Message()
-
- request.address = self.address
- request.reply_to = self.reply
- request.correlation_id = 1
- request.properties = {u'operation':u'GET', u'type':u'org.apache.qpid.dispatch.router.link'}
-
- self.M.put(request)
- self.M.send()
-
- self.M.recv()
- self.M.get(response)
-
- for link in response.body:
- row = []
- row.append(link['link-type'])
- row.append(link['link-dir'])
- if link['link-type'] == "router":
- row.append(link['index'])
- else:
- row.append('-')
- row.append(self._addr_class(link['owning-addr']))
- row.append(self._addr_text(link['owning-addr']))
- rows.append(row)
- title = "Router Links"
- dispRows = rows
- disp.formattedTable(title, heads, dispRows)
-
- def displayRouterNodes(self):
- disp = Display(prefix=" ")
- heads = []
- heads.append(Header("class"))
- heads.append(Header("address"))
- heads.append(Header("rindex"))
- heads.append(Header("next-hop"))
- heads.append(Header("link"))
- rows = []
-
- request = Message()
- response = Message()
-
- request.address = self.address
- request.reply_to = self.reply
- request.correlation_id = 1
- request.properties = {u'operation':u'GET', u'type':u'org.apache.qpid.dispatch.router.node'}
-
- self.M.put(request)
- self.M.send()
-
- self.M.recv()
- self.M.get(response)
-
- for node in response.body:
- row = []
- row.append(self._addr_class(node['addr']))
- row.append(self._addr_text(node['addr']))
- row.append(node['index'])
- if node['next-hop'] != None:
- row.append(node['next-hop'])
- else:
- row.append('-')
- if node['router-link'] != None:
- row.append(node['router-link'])
- else:
- row.append('-')
- rows.append(row)
- title = "Router Nodes"
- dispRows = rows
- disp.formattedTable(title, heads, dispRows)
-
- def displayAddresses(self):
- disp = Display(prefix=" ")
- heads = []
- heads.append(Header("class"))
- heads.append(Header("address"))
- heads.append(Header("in-proc", Header.Y))
- heads.append(Header("local", Header.COMMAS))
- heads.append(Header("remote", Header.COMMAS))
- heads.append(Header("in", Header.COMMAS))
- heads.append(Header("out", Header.COMMAS))
- heads.append(Header("thru", Header.COMMAS))
- heads.append(Header("to-proc", Header.COMMAS))
- heads.append(Header("from-proc", Header.COMMAS))
- rows = []
-
- request = Message()
- response = Message()
-
- request.address = self.address
- request.reply_to = self.reply
- request.correlation_id = 1
- request.properties = {u'operation':u'GET', u'type':u'org.apache.qpid.dispatch.router.address'}
-
- self.M.put(request)
- self.M.send()
-
- self.M.recv()
- self.M.get(response)
-
- for addr in response.body:
- row = []
- row.append(self._addr_class(addr['addr']))
- row.append(self._addr_text(addr['addr']))
- row.append(addr['in-process'])
- row.append(addr['subscriber-count'])
- row.append(addr['remote-count'])
- row.append(addr['deliveries-ingress'])
- row.append(addr['deliveries-egress'])
- row.append(addr['deliveries-transit'])
- row.append(addr['deliveries-to-container'])
- row.append(addr['deliveries-from-container'])
- rows.append(row)
- title = "Router Addresses"
- sorter = Sorter(heads, rows, 'address', 0, True)
- dispRows = sorter.getSorted()
- disp.formattedTable(title, heads, dispRows)
-
- def displayMemory(self):
- disp = Display(prefix=" ")
- heads = []
- heads.append(Header("type"))
- heads.append(Header("size", Header.COMMAS))
- heads.append(Header("batch"))
- heads.append(Header("thread-max", Header.COMMAS))
- heads.append(Header("total", Header.COMMAS))
- heads.append(Header("in-threads", Header.COMMAS))
- heads.append(Header("rebal-in", Header.COMMAS))
- heads.append(Header("rebal-out", Header.COMMAS))
- rows = []
-
- request = Message()
- response = Message()
-
- request.address = self.address
- request.reply_to = self.reply
- request.correlation_id = 1
- request.properties = {u'operation':u'GET', u'type':u'org.apache.qpid.dispatch.allocator'}
-
- self.M.put(request)
- self.M.send()
-
- self.M.recv()
- self.M.get(response)
-
- for t in response.body:
- row = []
- row.append(t['name'])
- row.append(t['type_size'])
- row.append(t['transfer_batch_size'])
- row.append(t['local_free_list_max'])
- row.append(t['total_alloc_from_heap'])
- row.append(t['held_by_threads'])
- row.append(t['batches_rebalanced_to_threads'])
- row.append(t['batches_rebalanced_to_global'])
- rows.append(row)
- title = "Types"
- sorter = Sorter(heads, rows, 'type', 0, True)
- dispRows = sorter.getSorted()
- disp.formattedTable(title, heads, dispRows)
-
- def displayMain(self, names, main):
- if main == 'l': self.displayRouterLinks()
- elif main == 'n': self.displayRouterNodes()
- elif main == 'a': self.displayAddresses()
- elif main == 'm': self.displayMemory()
-
- def display(self, names):
- self.displayMain(names, config._types)
-
-
-def main(argv=None):
-
- args = OptionsAndArguments(argv)
- bm = BusManager()
-
- try:
- bm.SetHost(config._host)
- bm.display(args)
- bm.Disconnect()
- return 0
- except KeyboardInterrupt:
- print
- except Exception,e:
- print "Failed: %s - %s" % (e.__class__.__name__, e)
-
- bm.Disconnect() # try to deallocate brokers
- return 1
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/extras/dispatch/tools/src/py/qdtoollibs/__init__.py b/extras/dispatch/tools/src/py/qdtoollibs/__init__.py
deleted file mode 100644
index 378bf24ef1..0000000000
--- a/extras/dispatch/tools/src/py/qdtoollibs/__init__.py
+++ /dev/null
@@ -1,21 +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.
-#
-
-from qdtoollibs.disp import *
-
diff --git a/extras/dispatch/tools/src/py/qdtoollibs/disp.py b/extras/dispatch/tools/src/py/qdtoollibs/disp.py
deleted file mode 100644
index 529a727449..0000000000
--- a/extras/dispatch/tools/src/py/qdtoollibs/disp.py
+++ /dev/null
@@ -1,270 +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.
-#
-
-from time import strftime, gmtime
-
-def YN(val):
- if val:
- return 'Y'
- return 'N'
-
-def Commas(value):
- sval = str(value)
- result = ""
- while True:
- if len(sval) == 0:
- return result
- left = sval[:-3]
- right = sval[-3:]
- result = right + result
- if len(left) > 0:
- result = ',' + result
- sval = left
-
-def TimeLong(value):
- return strftime("%c", gmtime(value / 1000000000))
-
-def TimeShort(value):
- return strftime("%X", gmtime(value / 1000000000))
-
-
-class Header:
- """ """
- NONE = 1
- KMG = 2
- YN = 3
- Y = 4
- TIME_LONG = 5
- TIME_SHORT = 6
- DURATION = 7
- COMMAS = 8
-
- def __init__(self, text, format=NONE):
- self.text = text
- self.format = format
-
- def __repr__(self):
- return self.text
-
- def __str__(self):
- return self.text
-
- def formatted(self, value):
- try:
- if value == None:
- return ''
- if self.format == Header.NONE:
- return value
- if self.format == Header.KMG:
- return self.num(value)
- if self.format == Header.YN:
- if value:
- return 'Y'
- return 'N'
- if self.format == Header.Y:
- if value:
- return 'Y'
- return ''
- if self.format == Header.TIME_LONG:
- return TimeLong(value)
- if self.format == Header.TIME_SHORT:
- return TimeShort(value)
- if self.format == Header.DURATION:
- if value < 0: value = 0
- sec = value / 1000000000
- min = sec / 60
- hour = min / 60
- day = hour / 24
- result = ""
- if day > 0:
- result = "%dd " % day
- if hour > 0 or result != "":
- result += "%dh " % (hour % 24)
- if min > 0 or result != "":
- result += "%dm " % (min % 60)
- result += "%ds" % (sec % 60)
- return result
- if self.format == Header.COMMAS:
- return Commas(value)
- except:
- return "?"
-
- def numCell(self, value, tag):
- fp = float(value) / 1000.
- if fp < 10.0:
- return "%1.2f%c" % (fp, tag)
- if fp < 100.0:
- return "%2.1f%c" % (fp, tag)
- return "%4d%c" % (value / 1000, tag)
-
- def num(self, value):
- if value < 1000:
- return "%4d" % value
- if value < 1000000:
- return self.numCell(value, 'k')
- value /= 1000
- if value < 1000000:
- return self.numCell(value, 'm')
- value /= 1000
- return self.numCell(value, 'g')
-
-
-class Display:
- """ Display formatting """
-
- def __init__(self, spacing=2, prefix=" "):
- self.tableSpacing = spacing
- self.tablePrefix = prefix
- self.timestampFormat = "%X"
-
- def formattedTable(self, title, heads, rows):
- fRows = []
- for row in rows:
- fRow = []
- col = 0
- for cell in row:
- fRow.append(heads[col].formatted(cell))
- col += 1
- fRows.append(fRow)
- headtext = []
- for head in heads:
- headtext.append(head.text)
- self.table(title, headtext, fRows)
-
- def table(self, title, heads, rows):
- """ Print a table with autosized columns """
-
- # Pad the rows to the number of heads
- for row in rows:
- diff = len(heads) - len(row)
- for idx in range(diff):
- row.append("")
-
- print title
- if len (rows) == 0:
- return
- colWidth = []
- col = 0
- line = self.tablePrefix
- for head in heads:
- width = len (head)
- for row in rows:
- text = row[col]
- if text.__class__ == str:
- text = text.decode('utf-8')
- cellWidth = len(unicode(text))
- if cellWidth > width:
- width = cellWidth
- colWidth.append (width + self.tableSpacing)
- line = line + head
- if col < len (heads) - 1:
- for i in range (colWidth[col] - len (head)):
- line = line + " "
- col = col + 1
- print line
- line = self.tablePrefix
- for width in colWidth:
- for i in range (width):
- line = line + "="
- print line
-
- for row in rows:
- line = self.tablePrefix
- col = 0
- for width in colWidth:
- text = row[col]
- if text.__class__ == str:
- text = text.decode('utf-8')
- line = line + unicode(text)
- if col < len (heads) - 1:
- for i in range (width - len(unicode(text))):
- line = line + " "
- col = col + 1
- print line
-
- def do_setTimeFormat (self, fmt):
- """ Select timestamp format """
- if fmt == "long":
- self.timestampFormat = "%c"
- elif fmt == "short":
- self.timestampFormat = "%X"
-
- def timestamp (self, nsec):
- """ Format a nanosecond-since-the-epoch timestamp for printing """
- return strftime (self.timestampFormat, gmtime (nsec / 1000000000))
-
- def duration(self, nsec):
- if nsec < 0: nsec = 0
- sec = nsec / 1000000000
- min = sec / 60
- hour = min / 60
- day = hour / 24
- result = ""
- if day > 0:
- result = "%dd " % day
- if hour > 0 or result != "":
- result += "%dh " % (hour % 24)
- if min > 0 or result != "":
- result += "%dm " % (min % 60)
- result += "%ds" % (sec % 60)
- return result
-
-class Sortable:
- """ """
- def __init__(self, row, sortIndex):
- self.row = row
- self.sortIndex = sortIndex
- if sortIndex >= len(row):
- raise Exception("sort index exceeds row boundary")
-
- def __cmp__(self, other):
- return cmp(self.row[self.sortIndex], other.row[self.sortIndex])
-
- def getRow(self):
- return self.row
-
-class Sorter:
- """ """
- def __init__(self, heads, rows, sortCol, limit=0, inc=True):
- col = 0
- for head in heads:
- if head.text == sortCol:
- break
- col += 1
- if col == len(heads):
- raise Exception("sortCol '%s', not found in headers" % sortCol)
-
- list = []
- for row in rows:
- list.append(Sortable(row, col))
- list.sort()
- if not inc:
- list.reverse()
- count = 0
- self.sorted = []
- for row in list:
- self.sorted.append(row.getRow())
- count += 1
- if count == limit:
- break
-
- def getSorted(self):
- return self.sorted