You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kp...@apache.org on 2013/10/22 00:05:07 UTC
svn commit: r1534394 [4/22] - in /qpid/branches/linearstore/qpid: ./ cpp/
cpp/bindings/qmf2/examples/python/ cpp/bindings/qmf2/python/
cpp/bindings/qpid/dotnet/ cpp/etc/ cpp/examples/ cpp/examples/messaging/
cpp/examples/qmf-agent/ cpp/include/qpid/ cp...
Modified: qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Cheat-Sheet-for-configuring-Queue-Options.xml
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Cheat-Sheet-for-configuring-Queue-Options.xml?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Cheat-Sheet-for-configuring-Queue-Options.xml (original)
+++ qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Cheat-Sheet-for-configuring-Queue-Options.xml Mon Oct 21 22:04:51 2013
@@ -52,9 +52,6 @@
<listitem><para>
<itemizedlist>
<listitem><para>
- <xref linkend="CheatSheetforconfiguringQueueOptions-PersistLastNode"/>
- </para></listitem>
- <listitem><para>
<xref linkend="CheatSheetforconfiguringQueueOptions-Queueeventgeneration"/>
</para></listitem>
</itemizedlist>
@@ -182,37 +179,6 @@
<section role="h3" id="CheatSheetforconfiguringQueueOptions-Settingadditionalbehaviors"><title>
Setting additional behaviors
</title>
- <section role="h4" id="CheatSheetforconfiguringQueueOptions-PersistLastNode"><title>
- Persist
- Last Node
- </title>
- <para>
- This option is used in conjunction with clustering. It allows for
- a queue configured with this option to persist transient messages
- if the cluster fails down to the last node. If additional nodes
- in the cluster are restored it will stop persisting transient
- messages.
- </para><para>
- Note
- </para><itemizedlist>
- <listitem><para>if a cluster is started with only one active node, this mode
- will not be triggered. It is only triggered the first time the
- cluster fails down to 1 node.
- </para></listitem>
- <listitem><para>The queue MUST be configured durable
- </para></listitem>
- </itemizedlist><para>
- Example:
- </para>
- <programlisting>
-#include "qpid/client/QueueOptions.h"
-
- QueueOptions qo;
- qo.clearPersistLastNode();
-
- session.queueDeclare(arg::queue=queue, arg::durable=true, arg::arguments=qo);
-</programlisting>
- <!--h4--></section>
<section role="h4" id="CheatSheetforconfiguringQueueOptions-Queueeventgeneration"><title>
Queue
event generation
Modified: qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Managing-CPP-Broker.xml
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Managing-CPP-Broker.xml?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Managing-CPP-Broker.xml (original)
+++ qpid/branches/linearstore/qpid/doc/book/src/cpp-broker/Managing-CPP-Broker.xml Mon Oct 21 22:04:51 2013
@@ -70,7 +70,6 @@ Options:
Add Queue Options:
--durable Queue is durable
- --cluster-durable Queue becomes durable if there is only one functioning cluster node
--file-count N (8) Number of files in queue's persistence journal
--file-size N (24) File size in pages (64Kib/page)
--max-queue-size N Maximum in-memory queue size as bytes
Modified: qpid/branches/linearstore/qpid/doc/book/src/java-broker/Java-Broker-Concepts-Exchanges.xml
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/doc/book/src/java-broker/Java-Broker-Concepts-Exchanges.xml?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/doc/book/src/java-broker/Java-Broker-Concepts-Exchanges.xml (original)
+++ qpid/branches/linearstore/qpid/doc/book/src/java-broker/Java-Broker-Concepts-Exchanges.xml Mon Oct 21 22:04:51 2013
@@ -22,34 +22,184 @@
<section id="Java-Broker-Concepts-Exchanges">
<title>Exchanges</title>
-<para>An <emphasis>Exchange</emphasis> is a named entity within the <emphasis>Virtual Host</emphasis> which receives
-messages from producers and routes them to matching message <emphasis>Queue</emphasis>s within the <emphasis>Virtual Host</emphasis>.
-Message routing occurs based on the particular Exchange's routing algorithm and its configured queue <emphasis>Binding</emphasis>s.</para>
-<para>
-The following <emphasis>Exchange</emphasis> types are supported by the <emphasis>Broker</emphasis>:
- <itemizedlist>
- <listitem><para><emphasis>Direct</emphasis>: routes messages to queues based on an exact match between
- the routing key of the message, and the binding key used to bind the queue to the exchange
- </para></listitem>
- <listitem><para><emphasis>Topic</emphasis>: routes messages to queues based on heirarchical pattern matching between the routing
- key for each message and the binding keys used to bind Queues to the Exchange. This exchange type is used to support the classic
- publish/subscribe paradigm using a topic namespace as the addressing model to select and deliver messages across multiple
- consumers based on a partial or full match on a topic pattern.
- </para>
- <para>
- Binding and routing keys for this Exchange use a "." deliminator to seperate words representing different levels of the heirarchy,
- with special meaning given to use of * and # as a word within a binding key such that a * matches any single word in a routing
- key and # matches zero or more words, allowing a binding key to match many routing keys for published messages. For example,
- a binding key of <emphasis>a.b.#</emphasis> would match the routing keys <emphasis>a.b</emphasis>, <emphasis>a.b.c</emphasis>, and
- <emphasis>a.b.c.d</emphasis>, but not the routing key <emphasis>a.z</emphasis>.</para></listitem>
- <listitem><para><emphasis>Fanout</emphasis>: routes messages to all queues bound to the exchange, regardless of the message's routing key.
- </para></listitem>
- <listitem><para><emphasis>Headers</emphasis>: routes messages to queues based on header properties within the AMQP message.
- The message is passed to a queue if the header properties of the message satisfy header matching arguments table with which the queue was bound.
- </para></listitem>
- </itemizedlist>
-</para>
-<para>Also, Broker supports the concept of a Default Exchange to which all queues are bound using their name as a binding key.</para>
-<para>Any number of exchanges of any type can be created on <emphasis>Virtual Host</emphasis>.</para>
-<para>Exchange configuration is covered in <xref linkend="Java-Broker-Exchanges"/>.</para>
+ <para>An <emphasis>Exchange</emphasis> is a named entity within the <emphasis>Virtual Host</emphasis> which receives
+ messages from producers and routes them to matching <emphasis>Queue</emphasis>s within the <emphasis>Virtual Host</emphasis>.</para>
+ <para>The server provides a set of exchange types with each exchange type implementing a different routing algorithm. For details of how
+ these exchanges types work see <xref linkend="Java-Broker-Concepts-Exchanges-Types"/> below.</para>
+ <para>The server predeclares a number of exchange instances with names starting with "<literal>amq.</literal>". These are defined in
+ <xref linkend="Java-Broker-Concepts-Exchanges-Predeclared"/>.</para>
+ <para>Applications can make use the pre-declared exchanges, or they may declare their own. The number of exchanges within a virtual host is
+ limited only by resource constraints.</para>
+ <para>The behaviour when an exchange is unable to route a message to any queue is defined in <xref linkend="Java-Broker-Concepts-Exchanges-UnroutableMessage"/></para>
+ <para>Exchange configuration is covered in <xref linkend="Java-Broker-Exchanges"/>.</para>
+ <section id="Java-Broker-Concepts-Exchanges-Predeclared">
+ <title>Predeclared Exchanges</title>
+ <para>Each virtual host pre-declares the following exchanges:
+ <itemizedlist>
+ <listitem>amq.direct (an instance of a direct exchange)</listitem>
+ <listitem>amq.topic (an instance of a topic exchange)</listitem>
+ <listitem>amq.fanout (an instance of a fanout exchange)</listitem>
+ <listitem>amq.match (an instance of a headers exchange)</listitem>
+ </itemizedlist>
+ </para>
+ <para>The conceptual "<literal>default exchange</literal>" always exists, effectively a special instance of
+ direct exchange which uses the empty string as its name. All queues are automatically bound to it upon their creation
+ using the queue name as the binding key, and unbound upon their deletion. It is not possible to manually add or remove
+ bindings within this exchange.</para>
+ <para>Applications may not declare exchanges with names beginning with "<literal>amq.</literal>". Such names are reserved for system use.</para>
+ </section>
+ <section id="Java-Broker-Concepts-Exchanges-Types">
+ <title>Exchange Types</title>
+ <para>
+ The following Exchange types are supported.
+ <itemizedlist>
+ <listitem>Direct</listitem>
+ <listitem>Topic</listitem>
+ <listitem>Fanout</listitem>
+ <listitem>Headers</listitem>
+ </itemizedlist>
+ These exchange types are described in the following sub-sections.</para>
+
+ <section id="Java-Broker-Concepts-Exchanges-Types-Direct">
+ <title>Direct</title>
+ <para>The direct exchange type routes messages to queues based on an exact match between
+ the routing key of the message, and the binding key used to bind the queue to the exchange. Additional
+ filter rules may be specified using a <link linkend="Java-Broker-Concepts-Exchanges-BindingArguments-JMSSelector">
+ binding argument specifying a JMS message selector</link>.
+ </para>
+ <para>This exchange type is often used to implement point to point messaging. When used in this manner, the normal
+ convention is that the binding key matches the name of the queue. It is also possible to use this exchange type
+ for multi-cast, in this case the same binding key is associated with many queues.</para>
+ <figure>
+ <title>Direct exchange</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Exchange-Direct.png" format="PNG" scalefit="1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para>The figure above illustrates the operation of direct exchange type. The yellow messages published with the routing key
+ "<literal>myqueue</literal>" match the binding key corresponding to queue "<literal>myqueue</literal>" and so are routed there. The red
+ messages published with the routing key "<literal>foo</literal>" match two bindings in the table so a copy of the message is
+ routed to both the "<literal>bar1</literal>" and "<literal>bar2</literal>" queues.</para>
+ <para>The routing key of the blue message matches no binding keys, so the message is unroutable. It is handled as described
+ in <xref linkend="Java-Broker-Concepts-Exchanges-UnroutableMessage"/>.</para>
+ </section>
+ <section id="Java-Broker-Concepts-Exchanges-Types-Topic">
+ <title>Topic</title>
+ <para>This exchange type is used to support the classic publish/subscribe paradigm.</para>
+ <para>The topic exchange is capable of routing messages to queues based on wildcard matches between the routing key and the
+ binding key pattern defined by the queue binding. Routing keys are formed from one or more words, with each word delimited
+ by a full-stop (.). The pattern matching characters are the * and # symbols. The * symbol matches a single word and the #
+ symbol matches zero or more words.</para>
+ <para>Additional filter rules may be specified using a <link linkend="Java-Broker-Concepts-Exchanges-BindingArguments-JMSSelector">
+ binding argument specifying a JMS message selector</link>.</para>
+ <para>The following three figures help explain how the topic exchange functions.</para>
+ <para></para>
+ <figure>
+ <title>Topic exchange - exact match on topic name</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Exchange-Topic.png" format="PNG" scalefit="1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para>The figure above illustrates publishing messages with routing key "<literal>weather</literal>". The exchange routes each
+ message to every bound queue whose binding key matches the routing key.</para>
+ <para>In the case illustrated, this means that each subscriber's queue receives every yellow message.</para>
+ <figure>
+ <title>Topic exchange - matching on hierarchical topic patterns</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Exchange-Topic-Hierarchical.png" format="PNG" scalefit="1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para>The figure above illustrates publishing messages with hierarchical routing keys. As before, the exchange routes each
+ message to every bound queue whose binding key matches the routing key but as the binding keys contain wildcards, the
+ wildcard rules described above apply.</para>
+ <para>In the case illustrated, <literal>sub1</literal> has received the red and green message as "<literal>news.uk</literal>" and "<literal>news.de</literal>"
+ match binding key "<literal>news.#</literal>". The red message has also gone to <literal>sub2</literal> and <literal>sub3</literal> as it's routing key
+ is matched exactly by "<literal>news.uk</literal>" and by "<literal>*.uk</literal>".</para>
+ <para>The routing key of the yellow message matches no binding keys, so the message is unroutable. It is handled as described
+ in <xref linkend="Java-Broker-Concepts-Exchanges-UnroutableMessage"/>.</para>
+ <figure>
+ <title>Topic exchange - matching on JMS message selector</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Exchange-Topic-JMSSelector.png" format="PNG" scalefit="1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ <para>The figure above illustrates messages with properties published with routing key "<literal>shipping</literal>".</para>
+ <para>As before, the exchange routes each message to every bound queue whose binding key matches the routing key but as a JMS selector
+ argument has been specified, the expression is evaluated against each matching message. Only messages whose message header values or properties
+ match the expression are routed to the queue.</para>
+ <para>In the case illustrated, <literal>sub1</literal> has received the yellow and blue message as their property "<literal>area</literal>"
+ cause expression "<literal>area in ('Forties', 'Cromarty')</literal>" to evaluate true. Similarly, the yellow message has also gone to
+ <literal>gale_alert</literal> as its property "<literal>speed</literal>" causes expression "<literal>speed > 7 and speed < 10</literal>"
+ to evaluate true.</para>
+ <para>The properties of purple message cause no expressions to evaluate true, so the message is unroutable. It is handled as described in
+ <xref linkend="Java-Broker-Concepts-Exchanges-UnroutableMessage"/>.</para>
+ </section>
+ <section id="Java-Broker-Concepts-Exchanges-Types-Fanout">
+ <title>Fanout</title>
+ <para>The fanout exchange type routes messages to all queues bound to the exchange, regardless of the message's routing key.</para>
+ <para>Filter rules may be specified using a <link linkend="Java-Broker-Concepts-Exchanges-BindingArguments-JMSSelector">
+ binding argument specifying a JMS message selector</link>.</para>
+ <figure>
+ <title>Fanout exchange</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/Exchange-Fanout.png" format="PNG" scalefit="1"/>
+ </imageobject>
+ </mediaobject>
+ </figure>
+ </section>
+ <section id="Java-Broker-Concepts-Exchanges-Types-Headers">
+ <title>Headers</title>
+ <para>The headers exchange type routes messages to queues based on header properties within the message. The message is passed to
+ a queue if the header properties of the message satisfy the <link linkend="Java-Broker-Concepts-Exchanges-BindingArguments-x-match">
+ x-match expression</link> specified by the binding arguments with which the queue was bound.
+ </para>
+ </section>
+ </section>
+ <section id="Java-Broker-Concepts-Exchanges-BindingArguments">
+ <title>Binding Arguments</title>
+ <para>Binding arguments are used by certain exchange types to further filter messages.</para>
+ <section id="Java-Broker-Concepts-Exchanges-BindingArguments-JMSSelector">
+ <title>JMS Selector</title>
+ <para>The binding argument <literal>x-filter-jms-selector</literal> specifies a JMS selector conditional expression. The expression
+ is written in terms of message header and message property names. If the expression evaluates to true, the message is routed to the queue.
+ This type of binding argument is understood by exchange types direct, topic and fanout.<footnote><para>
+ This is a Qpid specific extension.</para></footnote>.</para>
+ </section>
+ <section id="Java-Broker-Concepts-Exchanges-BindingArguments-x-match">
+ <title>x-match</title>
+ <para>The binding argument <literal>x-match</literal> is understood by exchange type headers. It can take two values, dictating how the
+ rest of the name value pairs are treated during matching.</para>
+ <itemizedlist>
+ <listitem><literal>all</literal> implies that all the other pairs must match the headers property of a message for that message to be routed
+ (i.e. an AND match)</listitem>
+ <listitem>any<literal></literal> implies that the message should be routed if any of the fields in the headers property match one of the
+ fields in the arguments table (i.e. an OR match)</listitem>
+ </itemizedlist>
+ <para>A field in the bind arguments matches a field in the message if either the field in the bind arguments has no value and a field of the
+ same name is present in the message headers or if the field in the bind arguments has a value and a field of the same name exists in the
+ message headers and has that same value.</para>
+ </section>
+ </section>
+ <section id="Java-Broker-Concepts-Exchanges-UnroutableMessage">
+ <title>Unrouteable Messages</title>
+ <para>If an exchange is unable to route a message to any queues, the Broker will:
+ <itemizedlist>
+ <listitem>If using AMQP 0-10 protocol, and an alternate exchange has been set on the exchange, the message is routed to the alternate exchange.
+ The alternate exchange routes the message according to its routing algorithm and its binding table. If the messages is still unroutable,
+ the message is discarded.</listitem>
+ <listitem>If using AMQP protocols 0-8..0-9-1, and the publisher set the mandatory flag and the<link linkend="Java-Broker-Close-Connection-When-No-Route">
+ close when no route</link> feature did not close the connection, the message is returned to the Producer.</listitem>
+ <listitem>Otherwise, the message is discarded.</listitem>
+ </itemizedlist>
+ </para>
+ </section>
</section>
Modified: qpid/branches/linearstore/qpid/doc/book/src/java-broker/commonEntities.xml
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/doc/book/src/java-broker/commonEntities.xml?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/doc/book/src/java-broker/commonEntities.xml (original)
+++ qpid/branches/linearstore/qpid/doc/book/src/java-broker/commonEntities.xml Mon Oct 21 22:04:51 2013
@@ -40,5 +40,5 @@
<!ENTITY oracleBdbProductOverviewUrl "http://www.oracle.com/technetwork/products/berkeleydb/overview/index-093405.html">
<!ENTITY oracleBdbRepGuideUrl "http://oracle.com/cd/E17277_02/html/ReplicationGuide/">
<!ENTITY oracleBdbJavaDocUrl "http://docs.oracle.com/cd/E17277_02/html/java/">
-<!ENTITY oracleBdbProductVersion "5.0.84">
+<!ENTITY oracleBdbProductVersion "5.0.97">
Modified: qpid/branches/linearstore/qpid/extras/dispatch/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/CMakeLists.txt?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/CMakeLists.txt (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/CMakeLists.txt Mon Oct 21 22:04:51 2013
@@ -51,6 +51,7 @@ set(INCLUDE_INSTALL_DIR include CACHE PA
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
@@ -61,13 +62,6 @@ if (PYTHONLIBS_FOUND)
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif (PYTHONLIBS_FOUND)
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/include
- ${CMAKE_CURRENT_SOURCE_DIR}/src
- ${proton_include}
- ${PYTHON_INCLUDE_PATH}
- )
-
##
## Find dependencies
##
@@ -76,6 +70,13 @@ 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")
@@ -85,6 +86,8 @@ set(CATCH_UNDEFINED "-Wl,--no-undefined"
set(server_SOURCES
src/agent.c
src/alloc.c
+ src/amqp.c
+ src/bitmask.c
src/buffer.c
src/compose.c
src/config.c
@@ -98,12 +101,18 @@ set(server_SOURCES
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
@@ -116,7 +125,7 @@ install(TARGETS qpid-dispatch
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})
+install(FILES etc/qpid-dispatch.conf DESTINATION ${SYSCONF_INSTALL_DIR}/qpid)
##
## Python modules installation
@@ -149,6 +158,13 @@ set(PYTHON_CONFIG_SOURCES
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)
@@ -163,6 +179,9 @@ install(FILES python/qpid/__init__.py
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
##
Modified: qpid/branches/linearstore/qpid/extras/dispatch/ChangeLog
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/ChangeLog?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/ChangeLog (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/ChangeLog Mon Oct 21 22:04:51 2013
@@ -1,2 +1,26 @@
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
Modified: qpid/branches/linearstore/qpid/extras/dispatch/README.md
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/README.md?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/README.md (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/README.md Mon Oct 21 22:04:51 2013
@@ -13,8 +13,18 @@ $ mkdir build
$ cd build
$ cmake ..
$ make
-$ make test
+$ 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.
Modified: qpid/branches/linearstore/qpid/extras/dispatch/TODO
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/TODO?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/TODO (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/TODO Mon Oct 21 22:04:51 2013
@@ -5,3 +5,50 @@ enhancements to be fixed by going to the
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
Modified: qpid/branches/linearstore/qpid/extras/dispatch/etc/qpid-dispatch.conf
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/etc/qpid-dispatch.conf?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/etc/qpid-dispatch.conf (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/etc/qpid-dispatch.conf Mon Oct 21 22:04:51 2013
@@ -102,6 +102,7 @@ listener {
listener {
label: Router Interconnect Access
+ role: inter-router
addr: 0.0.0.0
port: 5671
sasl-mechanisms: EXTERNAL
@@ -112,6 +113,7 @@ listener {
connector {
label: Router Uplink
+ role: inter-router
addr: backbone.enterprise.com
port: amqps
sasl-mechanisms: EXTERNAL
@@ -125,49 +127,27 @@ connector {
##
router {
##
- ## area and router-id - Each router is assigned an area name and a
- ## router-id that is unique within the area.
- ##
- area: all
- router-id: Router.A
-
- ##
- ## hello-interval - The interval, in seconds, between HELLO messages
- ## sent between connected routers. This interval can be relatively
- ## fast because HELLO messages do not propagate beyond one hop on the
- ## network. A good value is 1 second.
- ##
- hello-interval: 1
-
+ ## Router Mode:
##
- ## hello-max-age - The maximum time, in seconds, that can elapse
- ## without receiving a HELLO message from a neighbor before that
- ## neighbor is declared absent. A good value is 3 seconds.
+ ## 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.
##
- hello-max-age: 3
+ mode: standalone
##
- ## ra-interval - The interval, in seconds, between RA (Router
- ## Advertisement) messages sent by this router. This interval should
- ## be considerably longer than the hello interval because RA messages
- ## propagate across the area. A good value is 30 seconds.
+ ## For Interior router mode only.
##
- ra-interval: 30
-
- ##
- ## remote-ls-max-age - The maximum age, in seconds, of a remote
- ## link-state record. Any such records that are not updated and time
- ## out shall be removed from the set and the topology shall be
- ## recomputed. A good value is 60 seconds.
- ##
- remote-ls-max-age: 60
-
- ##
- ## mobile-addr-max-age - The maximum age, in seconds, of a remote
- ## mobile address record. Any record that exceeds this age shall be
- ## removed from the routing table. A good value is 60 seconds.
+ ## area and router-id - Each router is assigned an area name and a
+ ## router-id that is unique within the area.
##
- mobile-addr-max-age: 60
+ area: all
+ router-id: Router.A
}
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch.h Mon Oct 21 22:04:51 2013
@@ -20,6 +20,7 @@
*/
#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>
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/amqp.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/amqp.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/amqp.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/amqp.h Mon Oct 21 22:04:51 2013
@@ -76,5 +76,23 @@
#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
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/buffer.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/buffer.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/buffer.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/buffer.h Mon Oct 21 22:04:51 2013
@@ -36,12 +36,12 @@ void dx_buffer_set_size(size_t size);
/**
*/
-dx_buffer_t *dx_allocate_buffer(void);
+dx_buffer_t *dx_buffer(void);
/**
* @param buf A pointer to an allocated buffer
*/
-void dx_free_buffer(dx_buffer_t *buf);
+void dx_buffer_free(dx_buffer_t *buf);
/**
* @param buf A pointer to an allocated buffer
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/compose.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/compose.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/compose.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/compose.h Mon Oct 21 22:04:51 2013
@@ -167,7 +167,8 @@ void dx_compose_insert_string(dx_compose
* Insert a utf8-encoded string into the field from an iterator
*
* @param field A field created by dx_compose.
- * @param value A pointer to a null-terminated string.
+ * @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);
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/container.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/container.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/container.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/container.h Mon Oct 21 22:04:51 2013
@@ -152,8 +152,21 @@ dx_dist_mode_t dx_container_node_get_dis
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);
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/hash.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/hash.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/hash.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/hash.h Mon Oct 21 22:04:51 2013
@@ -23,16 +23,23 @@
#include <qpid/dispatch/iterator.h>
#include <qpid/dispatch/error.h>
-typedef struct hash_t hash_t;
+typedef struct dx_hash_t dx_hash_t;
+typedef struct dx_hash_handle_t dx_hash_handle_t;
-hash_t *hash(int bucket_exponent, int batch_size, int value_is_const);
-void hash_free(hash_t *h);
+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);
-size_t hash_size(hash_t *h);
-dx_error_t hash_insert(hash_t *h, dx_field_iterator_t *key, void *val);
-dx_error_t hash_insert_const(hash_t *h, dx_field_iterator_t *key, const void *val);
-dx_error_t hash_retrieve(hash_t *h, dx_field_iterator_t *key, void **val);
-dx_error_t hash_retrieve_const(hash_t *h, dx_field_iterator_t *key, const void **val);
-dx_error_t hash_remove(hash_t *h, dx_field_iterator_t *key);
#endif
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/message.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/message.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/message.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/message.h Mon Oct 21 22:04:51 2013
@@ -96,7 +96,7 @@ typedef enum {
* @return A pointer to a dx_message_t that is the sole reference to a newly allocated
* message.
*/
-dx_message_t *dx_allocate_message(void);
+dx_message_t *dx_message(void);
/**
* Free a message reference. If this is the last reference to the message, free the
@@ -104,7 +104,7 @@ dx_message_t *dx_allocate_message(void);
*
* @param msg A pointer to a dx_message_t that is no longer needed.
*/
-void dx_free_message(dx_message_t *msg);
+void dx_message_free(dx_message_t *msg);
/**
* Make a new reference to an existing message.
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/python_embedded.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/python_embedded.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/python_embedded.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/python_embedded.h Mon Oct 21 22:04:51 2013
@@ -71,4 +71,11 @@ void dx_py_to_composed(PyObject *value,
*/
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
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/router.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/router.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/router.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/router.h Mon Oct 21 22:04:51 2013
@@ -27,7 +27,7 @@
typedef struct dx_address_t dx_address_t;
-typedef void (*dx_router_message_cb)(void *context, dx_message_t *msg);
+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);
Modified: qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/server.h
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/server.h?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/server.h (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/include/qpid/dispatch/server.h Mon Oct 21 22:04:51 2013
@@ -186,7 +186,7 @@ typedef struct dx_connector_t dx_connect
typedef struct dx_connection_t dx_connection_t;
/**
- * Event type for the connection callback.
+ * \brief Event type for the connection callback.
*/
typedef enum {
/// The connection just opened via a listener (inbound).
@@ -204,79 +204,6 @@ typedef enum {
/**
- * \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 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 Configuration block for a connector or a listener.
*/
typedef struct dx_server_config_t {
@@ -367,10 +294,116 @@ typedef struct dx_server_config_t {
* 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.
Modified: qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/config/schema.py
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/config/schema.py?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/config/schema.py (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/config/schema.py Mon Oct 21 22:04:51 2013
@@ -57,6 +57,7 @@ config_schema = {
'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),
@@ -66,11 +67,13 @@ config_schema = {
'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),
Modified: qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/configuration.py
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/configuration.py?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/configuration.py (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/configuration.py Mon Oct 21 22:04:51 2013
@@ -18,30 +18,30 @@
#
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 }
+ """
+ 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
+ ##
+ ## 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 __getattr__(self, key):
+ if key in self.values:
+ return self.values[key]
+ raise KeyError
- def __repr__(self):
- return "%r" % self.values
+ def __repr__(self):
+ return "%r" % self.values
Modified: qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/data.py
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/data.py?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/data.py (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/data.py Mon Oct 21 22:04:51 2013
@@ -19,257 +19,257 @@
try:
- from dispatch import *
+ from dispatch import *
except ImportError:
- from ..stubs import *
+ 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)
+ """
+ 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
+ """
+ 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
+ """
+ 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
+ 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}
+ """
+ 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
+ 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}
+ """
+ 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()}
+ """
+ """
+ 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}
+ """
+ """
+ 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
+ """
+ """
+ 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}
+ """
+ """
+ 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}
Modified: qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/link.py
URL: http://svn.apache.org/viewvc/qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/link.py?rev=1534394&r1=1534393&r2=1534394&view=diff
==============================================================================
--- qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/link.py (original)
+++ qpid/branches/linearstore/qpid/extras/dispatch/python/qpid/dispatch/router/link.py Mon Oct 21 22:04:51 2013
@@ -21,123 +21,124 @@ from data import MessageRA, MessageLSU,
from time import time
try:
- from dispatch import *
+ from dispatch import *
except ImportError:
- from ..stubs import *
+ 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
+ """
+ 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
- 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.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('_topo/%s/%s' % (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('_topo/%s/%s' % (_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('_topo/%s/all' % self.area, MessageRA(None, self.id, self.area, ls_seq, self.mobile_seq))
+ 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))
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org