You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2015/08/07 22:41:36 UTC
[1/2] qpid-proton git commit: PROTON-865: Fix segmentation fault in
messaging_handler destructor.
Repository: qpid-proton
Updated Branches:
refs/heads/cjansen-cpp-client 8e1757ebc -> db11dee5a
PROTON-865: Fix segmentation fault in messaging_handler destructor.
Also fix const bug, using non-const std::string& for some in parameters.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/2b7f56d3
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/2b7f56d3
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/2b7f56d3
Branch: refs/heads/cjansen-cpp-client
Commit: 2b7f56d3782ecaaa205a583b408cd801d5d15260
Parents: 8e1757e
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Aug 7 09:37:47 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Aug 7 16:37:05 2015 -0400
----------------------------------------------------------------------
.../cpp/include/proton/blocking_connection.hpp | 4 ++--
proton-c/bindings/cpp/include/proton/terminus.hpp | 2 +-
proton-c/bindings/cpp/src/blocking_connection.cpp | 4 ++--
.../bindings/cpp/src/blocking_connection_impl.cpp | 4 ++--
.../bindings/cpp/src/blocking_connection_impl.hpp | 4 ++--
proton-c/bindings/cpp/src/messaging_handler.cpp | 16 ++++++----------
proton-c/bindings/cpp/src/terminus.cpp | 2 +-
7 files changed, 16 insertions(+), 20 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2b7f56d3/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
index cba5f60..a8eac72 100644
--- a/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/blocking_connection.hpp
@@ -58,8 +58,8 @@ class blocking_connection : public handle<blocking_connection_impl>
PN_CPP_EXTERN blocking_receiver create_receiver(const std::string &address, int credit = 0,
bool dynamic = false, handler *h=0, std::string name = std::string());
PN_CPP_EXTERN void wait(wait_condition &condition);
- PN_CPP_EXTERN void wait(wait_condition &condition, std::string &msg);
- PN_CPP_EXTERN void wait(wait_condition &condition, std::string &msg, duration timeout);
+ PN_CPP_EXTERN void wait(wait_condition &condition, const std::string &msg);
+ PN_CPP_EXTERN void wait(wait_condition &condition, const std::string &msg, duration timeout);
PN_CPP_EXTERN duration timeout();
private:
friend class private_impl_ref<blocking_connection>;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2b7f56d3/proton-c/bindings/cpp/include/proton/terminus.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/terminus.hpp b/proton-c/bindings/cpp/include/proton/terminus.hpp
index 62fb960..f53d6c3 100644
--- a/proton-c/bindings/cpp/include/proton/terminus.hpp
+++ b/proton-c/bindings/cpp/include/proton/terminus.hpp
@@ -72,7 +72,7 @@ class terminus : public proton_handle<pn_terminus_t>
PN_CPP_EXTERN distribution_mode_t distribution_mode();
PN_CPP_EXTERN void distribution_mode(distribution_mode_t);
PN_CPP_EXTERN std::string address();
- PN_CPP_EXTERN void address(std::string &);
+ PN_CPP_EXTERN void address(const std::string &);
PN_CPP_EXTERN bool is_dynamic();
PN_CPP_EXTERN void dynamic(bool);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2b7f56d3/proton-c/bindings/cpp/src/blocking_connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection.cpp b/proton-c/bindings/cpp/src/blocking_connection.cpp
index c0c1477..61475bc 100644
--- a/proton-c/bindings/cpp/src/blocking_connection.cpp
+++ b/proton-c/bindings/cpp/src/blocking_connection.cpp
@@ -50,10 +50,10 @@ blocking_connection::blocking_connection(const proton::url &url, duration d, ssl
void blocking_connection::close() { impl_->close(); }
void blocking_connection::wait(wait_condition &cond) { return impl_->wait(cond); }
-void blocking_connection::wait(wait_condition &cond, std::string &msg) {
+void blocking_connection::wait(wait_condition &cond, const std::string &msg) {
return impl_->wait(cond, msg);
}
-void blocking_connection::wait(wait_condition &cond, std::string &msg, duration timeout) {
+void blocking_connection::wait(wait_condition &cond, const std::string &msg, duration timeout) {
return impl_->wait(cond, msg, timeout);
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2b7f56d3/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection_impl.cpp b/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
index 0e78541..10b40ee 100644
--- a/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
+++ b/proton-c/bindings/cpp/src/blocking_connection_impl.cpp
@@ -88,11 +88,11 @@ void blocking_connection_impl::wait(wait_condition &condition) {
wait(condition, empty, timeout_);
}
-void blocking_connection_impl::wait(wait_condition &condition, std::string &msg) {
+void blocking_connection_impl::wait(wait_condition &condition, const std::string &msg) {
wait(condition, msg, timeout_);
}
-void blocking_connection_impl::wait(wait_condition &condition, std::string &msg, duration wait_timeout) {
+void blocking_connection_impl::wait(wait_condition &condition, const std::string &msg, duration wait_timeout) {
if (wait_timeout == duration::FOREVER) {
while (!condition.achieved()) {
container_.process();
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2b7f56d3/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/blocking_connection_impl.hpp b/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
index 11ff4fd..b70193d 100644
--- a/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
+++ b/proton-c/bindings/cpp/src/blocking_connection_impl.hpp
@@ -42,8 +42,8 @@ class ssl_domain;
PN_CPP_EXTERN ~blocking_connection_impl();
PN_CPP_EXTERN void close();
PN_CPP_EXTERN void wait(wait_condition &condition);
- PN_CPP_EXTERN void wait(wait_condition &condition, std::string &msg);
- PN_CPP_EXTERN void wait(wait_condition &condition, std::string &msg, duration timeout);
+ PN_CPP_EXTERN void wait(wait_condition &condition, const std::string &msg);
+ PN_CPP_EXTERN void wait(wait_condition &condition, const std::string &msg, duration timeout);
PN_CPP_EXTERN pn_connection_t *pn_blocking_connection();
duration timeout() { return timeout_; }
static void incref(blocking_connection_impl *);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2b7f56d3/proton-c/bindings/cpp/src/messaging_handler.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_handler.cpp b/proton-c/bindings/cpp/src/messaging_handler.cpp
index 76e3572..188d739 100644
--- a/proton-c/bindings/cpp/src/messaging_handler.cpp
+++ b/proton-c/bindings/cpp/src/messaging_handler.cpp
@@ -53,19 +53,15 @@ class Cflow_controller : public proton_handler
messaging_handler::messaging_handler(int prefetch0, bool auto_accept0, bool auto_settle0, bool peer_close_is_error0) :
- prefetch_(prefetch0), auto_accept_(auto_accept0), auto_settle_(auto_settle0), peer_close_iserror_(peer_close_is_error0)
+ prefetch_(prefetch0), auto_accept_(auto_accept0), auto_settle_(auto_settle0), peer_close_iserror_(peer_close_is_error0), messaging_adapter_(0), flow_controller_(0)
{
create_helpers();
}
-messaging_handler::messaging_handler(bool raw_handler, int prefetch0, bool auto_accept0, bool auto_settle0,
- bool peer_close_is_error0) :
- prefetch_(prefetch0), auto_accept_(auto_accept0), auto_settle_(auto_settle0), peer_close_iserror_(peer_close_is_error0)
+messaging_handler::messaging_handler(bool raw_handler, int prefetch0, bool auto_accept0, bool auto_settle0, bool peer_close_is_error0) :
+ prefetch_(prefetch0), auto_accept_(auto_accept0), auto_settle_(auto_settle0), peer_close_iserror_(peer_close_is_error0), messaging_adapter_(0), flow_controller_(0)
{
- if (raw_handler) {
- flow_controller_ = 0;
- messaging_adapter_ = 0;
- } else {
+ if (!raw_handler) {
create_helpers();
}
}
@@ -80,8 +76,8 @@ void messaging_handler::create_helpers() {
}
messaging_handler::~messaging_handler(){
- delete flow_controller_;
- delete messaging_adapter_;
+ if (flow_controller_) delete flow_controller_;
+ if (messaging_adapter_) delete messaging_adapter_;
}
void messaging_handler::on_abort(event &e) { on_unhandled(e); }
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2b7f56d3/proton-c/bindings/cpp/src/terminus.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/terminus.cpp b/proton-c/bindings/cpp/src/terminus.cpp
index 6db09d0..210d273 100644
--- a/proton-c/bindings/cpp/src/terminus.cpp
+++ b/proton-c/bindings/cpp/src/terminus.cpp
@@ -86,7 +86,7 @@ std::string terminus::address() {
return addr ? std::string(addr) : std::string();
}
-void terminus::address(std::string &addr) {
+void terminus::address(const std::string &addr) {
pn_terminus_set_address(impl_, addr.c_str());
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[2/2] qpid-proton git commit: PROTON-865: Tutorial and examples,
added client.cpp and server_direct.cpp
Posted by ac...@apache.org.
PROTON-865: Tutorial and examples, added client.cpp and server_direct.cpp
Fixed some minor bugs turned up by the examples.
server_direct implemented and in tutorial
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/db11dee5
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/db11dee5
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/db11dee5
Branch: refs/heads/cjansen-cpp-client
Commit: db11dee5af074e3b24f0666ee9ab52cac489d01a
Parents: 2b7f56d
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Aug 7 13:48:34 2015 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Aug 7 16:37:37 2015 -0400
----------------------------------------------------------------------
examples/cpp/CMakeLists.txt | 2 +
examples/cpp/README.hpp | 120 ++++++++++++++++
examples/cpp/README.md | 130 -----------------
examples/cpp/client.cpp | 97 +++++++++++++
examples/cpp/example_test.py | 66 ++++-----
examples/cpp/server.cpp | 38 ++---
examples/cpp/server_direct.cpp | 104 ++++++++++++++
examples/cpp/sync_client.cpp | 20 +--
examples/python/client.py | 5 +-
proton-c/bindings/cpp/CMakeLists.txt | 2 +-
proton-c/bindings/cpp/docs/tutorial.hpp | 138 +++++++++++++------
proton-c/bindings/cpp/docs/user.doxygen.in | 2 +-
.../bindings/cpp/include/proton/message.hpp | 2 +
.../cpp/include/proton/proton_handle.hpp | 7 +-
proton-c/bindings/cpp/src/message.cpp | 10 +-
15 files changed, 494 insertions(+), 249 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index f32c38a..1822c6a 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -31,7 +31,9 @@ foreach(example
direct_recv
direct_send
sync_client
+ client
server
+ server_direct
encode_decode)
add_executable(${example} ${example}.cpp)
target_link_libraries(${example} qpid-proton-cpp)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/README.hpp
----------------------------------------------------------------------
diff --git a/examples/cpp/README.hpp b/examples/cpp/README.hpp
new file mode 100644
index 0000000..d2a51eb
--- /dev/null
+++ b/examples/cpp/README.hpp
@@ -0,0 +1,120 @@
+// Examples overview.
+//
+// For a better overview, see the tutorial in the generated documentation.
+// In your build directory do:
+// make docs-cpp
+// then open proton-c/bindings/cpp/docs/html/tutorial.html in your browser.
+//
+
+// DEVELOPER NOTE: if you are adding or modifying examples you should keep this
+// file and ../proton-c/bindings/cpp/docs/tutorial.hpp up to date.
+
+/** \example broker.cpp
+
+A very simple "mini broker". You can use this to run other examples that reqiure
+an intermediary, or you can use any AMQP 1.0 broker. This broker creates queues
+automatically when a client tries to send or subscribe.
+
+*/
+
+/** \example helloworld.cpp
+
+Basic example that connects to an intermediary on 127.0.0.1:5672,
+establishes a subscription from the 'examples' nodeu on that
+intermediary, then creates a sending link to the same node and sends
+one message. On receving the message back via the subcription, the
+connection is closed.
+
+*/
+
+/** \example helloworld_direct.cpp
+
+A variant of the basic helloworld example, that does not use an
+intermediary, but listens for incoming connections itself. It
+establishes a connection to itself with a link over which a single
+message is sent. This demonstrates the ease with which a simple daemon
+can be built using the API.
+
+*/
+
+/** \example helloworld_blocking.cpp
+
+The same as the basic helloworld.cpp, but using a
+synchronous/sequential style wrapper on top of the
+asynchronous/reactive API. The purpose of this example is just to show
+how different functionality can be easily layered should it be
+desired.
+
+*/
+
+/** \example simple_send.cpp
+
+An example of sending a fixed number of messages and tracking their
+(asynchronous) acknowledgement. Messages are sent through the 'examples' node on
+an intermediary accessible on 127.0.0.1:5672.
+
+*/
+
+/** \example simple_recv.cpp
+
+Subscribes to the 'examples' node on an intermediary accessible
+on 127.0.0.1:5672. Simply prints out the body of received messages.
+
+*/
+
+/** \example direct_send.cpp
+
+Accepts an incoming connection and then sends like `simple_send`. You can
+connect directly to `direct_send` *without* a broker using \ref simple_recv.cpp.
+Make sure to stop the broker first or use a different port for `direct_send`.
+
+*/
+
+/** \example direct_recv.cpp
+
+Accepts an incoming connection and then receives like `simple_recv`. You can
+connect directly to `direct_recv` *without* a broker using \ref simple_send.cpp.
+Make sure to stop the broker first or use a different port for `direct_recv`.
+
+*/
+
+/** \example encode_decode.cpp
+
+Shows how C++ data types can be converted to and from AMQP types.
+
+*/
+
+/** \example client.cpp
+
+The client part of a request-response example. Sends requests and
+prints out responses. Requires an intermediary that supports the AMQP
+1.0 dynamic nodes on which the responses are received. The requests
+are sent through the 'examples' node.
+
+*/
+
+/** \example server.cpp
+
+The server part of a request-response example, that receives requests
+via the examples node, converts the body to uppercase and sends the
+result back to the indicated reply address.
+
+*/
+
+/** \example server_direct.cpp
+
+A variant of the server part of a request-response example, that
+accepts incoming connections and does not need an intermediary. Much
+like the original server, it receives incoming requests, converts the
+body to uppercase and sends the result back to the indicated reply
+address. Can be used in conjunction with any of the client
+alternatives.
+
+*/
+
+/** \example sync_client.cpp
+
+A variant of the client part, that uses a blocking/synchronous style
+instead of the reactive/asynchronous style.
+
+*/
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/README.md
----------------------------------------------------------------------
diff --git a/examples/cpp/README.md b/examples/cpp/README.md
deleted file mode 100644
index bd94b55..0000000
--- a/examples/cpp/README.md
+++ /dev/null
@@ -1,130 +0,0 @@
-C++ examples
-============
-
-Many of the examples expect a broker to be running on the standard AMQP
-port. You can use any broker that supports AMQP 1.0, or you can use the simple
-example `broker` provided here. Run the broker in a separate window before
-running the other examples.
-
-If you use another broker you will need to create a queue named `examples`.
-
-NOTE: Most of these examples are described in more detail as part of the \ref tutorial.
-
-Note on Brokers and URLs
-------------------------
-
-Some of the examples require an AMQP *broker* that can receive, store and send messages.
-
-There is a very simple broker included as an example (\ref broker.cpp) which you can use.
-Run it like this:
-
- broker [URL]
-
-The default URL is "0.0.0.0:5672" which listens on the standard AMQP port on all
-network interfaces.
-
-Instead of the example broker, you can use any AMQP 1.0 compliant broker. You
-must configure your broker to have a queue or topic named "examples".
-
-Most of the examples take an optional URL argument, the simplest form is:
-
- HOST:PORT/ADDRESS
-
-It usually defaults to `127.0.0.1:5672/examples`, but you can change this if
-your broker is on a different host or port, or you want to use a different queue
-or topic name (the ADDRESS part of the URL). URL details are at `proton::url`
-
-broker.cpp
-----------
-
-A very simple "mini broker". You can use this to run other examples that reqiure
-an intermediary, or you can use any AMQP 1.0 broker. This broker creates queues
-automatically when a client tries to send or subscribe.
-
-Source: \ref broker.cpp
-
-helloworld.cpp
---------------
-
-Basic example that connects to an intermediary on 127.0.0.1:5672,
-establishes a subscription from the 'examples' nodeu on that
-intermediary, then creates a sending link to the same node and sends
-one message. On receving the message back via the subcription, the
-connection is closed.
-
-Source: \ref helloworld.cpp
-
-helloworld_direct.cpp
----------------------
-
-A variant of the basic helloworld example, that does not use an
-intermediary, but listens for incoming connections itself. It
-establishes a connection to itself with a link over which a single
-message is sent. This demonstrates the ease with which a simple daemon
-can be built using the API.
-
-Source: \ref helloworld_direct.cpp
-
-helloworld_blocking.cpp
------------------------
-
-The same as the basic helloworld.cpp, but using a
-synchronous/sequential style wrapper on top of the
-asynchronous/reactive API. The purpose of this example is just to show
-how different functionality can be easily layered should it be
-desired.
-
-Source: \ref helloworld_blocking.cpp
-
-simple_send.cpp
----------------
-
-An example of sending a fixed number of messages and tracking their
-(asynchronous) acknowledgement. Messages are sent through the 'examples' node on
-an intermediary accessible on 127.0.0.1:5672.
-
-Source: \ref simple_send.cpp
-
-simple_recv.cpp
----------------
-
-Subscribes to the 'examples' node on an intermediary accessible
-on 127.0.0.1:5672. Simply prints out the body of received messages.
-
-Source: \ref simple_recv.cpp
-
-direct_send.cpp
----------------
-
-Accepts an incoming connection and then sends like `simple_send`. You can
-connect directly to `direct_send` *without* a broker using \ref simple_recv.cpp.
-Make sure to stop the broker first or use a different port for `direct_send`.
-
-Source: \ref direct_send.cpp
-
-direct_recv.cpp
----------------
-
-Accepts an incoming connection and then receives like `simple_recv`. You can
-connect directly to `direct_recv` *without* a broker using \ref simple_send.cpp.
-Make sure to stop the broker first or use a different port for `direct_recv`.
-
-Source: \ref direct_recv.cpp
-
-encode_decode.cpp
------------------
-
-Shows how C++ data types can be converted to and from AMQP types.
-
-Source: \ref encode_decode.cpp
-
- <!-- For generated doxygen docmentation. Note \ref tags above are also for doxygen -->
- \example helloworld.cpp
- \example helloworld_direct.cpp
- \example helloworld_blocking.cpp
- \example broker.cpp
- \example encode_decode.cpp
- \example simple_recv.cpp
- \example simple_send.cpp
- \example direct_recv.cpp
- \example direct_send.cpp
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
new file mode 100644
index 0000000..be5fc40
--- /dev/null
+++ b/examples/cpp/client.cpp
@@ -0,0 +1,97 @@
+/*
+ *
+ * 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 "options.hpp"
+#include "proton/container.hpp"
+#include "proton/messaging_handler.hpp"
+#include "proton/connection.hpp"
+#include <iostream>
+#include <vector>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+class client : public proton::messaging_handler {
+ private:
+ proton::url url;
+ std::vector<std::string> requests;
+ proton::sender sender;
+ proton::receiver receiver;
+
+ public:
+ client(const proton::url &u, const std::vector<std::string>& r) : url(u), requests(r) {}
+
+ void on_start(proton::event &e) {
+ sender = e.container().create_sender(url);
+ // Create a receiver with a dynamically chosen unique address.
+ receiver = e.container().create_receiver(sender.connection(), "", true/*dynamic*/);
+ }
+
+ void send_request() {
+ proton::message req;
+ req.body(requests.front());
+ req.reply_to(receiver.remote_source().address());
+ sender.send(req);
+ }
+
+ void on_link_opened(proton::event &e) {
+ if (e.link() == receiver)
+ send_request();
+ }
+
+ void on_message(proton::event &e) {
+ proton::message response = e.message();
+ std::cout << '"' << requests.front() << '"' << " => " << response.body() << std::endl;
+ requests.erase(requests.begin());
+ if (!requests.empty()) {
+ send_request();
+ } else {
+ e.connection().close();
+ }
+ }
+};
+
+int main(int argc, char **argv) {
+ // Command line options
+ proton::url url("127.0.0.1:5672/examples");
+ options opts(argc, argv);
+ opts.add_value(url, 'a', "address", "connect and send to URL", "URL");
+
+ try {
+ opts.parse();
+
+ std::vector<std::string> requests;
+ requests.push_back("Twas brillig, and the slithy toves");
+ requests.push_back("Did gire and gymble in the wabe.");
+ requests.push_back("All mimsy were the borogroves,");
+ requests.push_back("And the mome raths outgrabe.");
+
+ client c(url, requests);
+ proton::container(c).run();
+
+ return 0;
+ } catch (const bad_option& e) {
+ std::cout << opts << std::endl << e.what() << std::endl;
+ } catch (const std::exception& e) {
+ std::cerr << e.what() << std::endl;
+ }
+ return 1;
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/example_test.py
----------------------------------------------------------------------
diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py
index 38e3c2c..51e732d 100644
--- a/examples/cpp/example_test.py
+++ b/examples/cpp/example_test.py
@@ -102,31 +102,6 @@ class Broker(object):
except Exception as e:
raise Exception("Error running %s: %s", cmd, e)
-class Server(object):
- """Run the test server"""
-
- @classmethod
- def get(cls, addr):
- if not hasattr(cls, "_server"):
- cls._server = Server(addr)
- return cls._server
-
- @classmethod
- def stop(cls):
- if cls.get(None) and cls._server.process:
- cls._server.process.kill()
- cls._server = None
-
- def __init__(self, addr):
- self.addr = addr
- cmd = [exe_name("server"), "-a", self.addr]
- try:
- self.process = Popen(cmd, stdout=NULL, stderr=NULL)
- time.sleep(0.3)
-
- except Exception as e:
- raise Exception("Error running %s: %s", cmd, e)
-
class ExampleTest(unittest.TestCase):
"""Run the examples, verify they behave as expected."""
@@ -177,8 +152,13 @@ class ExampleTest(unittest.TestCase):
send_expect = "direct_send listening on amqp://%s\nall messages confirmed\n" % (addr)
self.assertEqual(send_expect, verify(send))
+ CLIENT_EXPECT=""""Twas brillig, and the slithy toves" => "TWAS BRILLIG, AND THE SLITHY TOVES"
+"Did gire and gymble in the wabe." => "DID GIRE AND GYMBLE IN THE WABE."
+"All mimsy were the borogroves," => "ALL MIMSY WERE THE BOROGROVES,"
+"And the mome raths outgrabe." => "AND THE MOME RATHS OUTGRABE."
+"""
def test_simple_recv_send(self):
- """Start receiver first, then run sender"""
+ # Start receiver first, then run sender"""
b = Broker.get()
recv = background("simple_recv", "-a", b.addr)
self.assertEqual("all messages confirmed\n", execute("simple_send", "-a", b.addr))
@@ -186,20 +166,30 @@ class ExampleTest(unittest.TestCase):
recv_expect += "".join(['{"sequence"=%s}\n' % (i+1) for i in range(100)])
self.assertEqual(recv_expect, verify(recv))
+ def test_request_response(self):
+ b = Broker.get()
+ server = background("server", "-a", b.addr)
+ try:
+ self.assertEqual(execute("client", "-a", b.addr), self.CLIENT_EXPECT)
+ finally:
+ server.kill()
+
def test_sync_request_response(self):
- """Start server first, then run sync_client"""
b = Broker.get()
- s = Server.get(b.addr)
- expect = """
-"Twas brillig, and the slithy toves" => "TWAS BRILLIG, AND THE SLITHY TOVES"
-"Did gire and gymble in the wabe." => "DID GIRE AND GYMBLE IN THE WABE."
-"All mimsy were the borogroves," => "ALL MIMSY WERE THE BOROGROVES,"
-"And the mome raths outgrabe." => "AND THE MOME RATHS OUTGRABE."
-"""
- sc = "\n"
- sc += execute("sync_client", "-a", b.addr)
- self.assertEqual(expect, sc)
- Server.stop()
+ server = background("server", "-a", b.addr)
+ try:
+ self.assertEqual(execute("sync_client", "-a", b.addr), self.CLIENT_EXPECT)
+ finally:
+ server.kill()
+
+ def test_request_response_direct(self):
+ addr = pick_addr()
+ server = background("server_direct", "-a", addr+"/examples")
+ wait_addr(addr)
+ try:
+ self.assertEqual(execute("client", "-a", addr+"/examples"), self.CLIENT_EXPECT)
+ finally:
+ server.kill()
def test_encode_decode(self):
expect="""
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/server.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server.cpp b/examples/cpp/server.cpp
index 78b78d3..bad49d3 100644
--- a/examples/cpp/server.cpp
+++ b/examples/cpp/server.cpp
@@ -38,12 +38,12 @@ class server : public proton::messaging_handler {
public:
- server(const proton::url &u) : url(u) {}
+ server(const std::string &u) : url(u) {}
void on_start(proton::event &e) {
connection = e.container().connect(url);
e.container().create_receiver(connection, url.path());
- std::cout << "server listening on " << url << std::endl;
+ std::cout << "server connected to " << url << std::endl;
}
std::string to_upper(const std::string &s) {
@@ -53,38 +53,28 @@ class server : public proton::messaging_handler {
return uc;
}
- // TODO: on_connection_opened() and ANONYMOUS-RELAY
-
void on_message(proton::event &e) {
- proton::sender sender;
- proton::message msg = e.message();
- std::cout << "Received " << msg.body() << std::endl;
- std::string sender_id = msg.reply_to();
- sender_map::iterator it = senders.find(sender_id);
- if (it == senders.end()) {
- sender = e.container().create_sender(connection, sender_id);
- senders[sender_id] = sender;
- }
- else {
- sender = it->second;
- }
+ std::cout << "Received " << e.message().body() << std::endl;
+ std::string reply_to = e.message().reply_to();
proton::message reply;
- reply.body(to_upper(msg.body().get<std::string>()));
- reply.correlation_id(msg.correlation_id());
- reply.address(sender_id);
- sender.send(reply);
+ reply.address(reply_to);
+ reply.body(to_upper(e.message().body().get<std::string>()));
+ reply.correlation_id(e.message().correlation_id());
+ if (!senders[reply_to])
+ senders[reply_to] = e.container().create_sender(connection, reply_to);
+ senders[reply_to].send(reply);
}
};
int main(int argc, char **argv) {
// Command line options
- proton::url url("amqp://127.0.0.1:5672/examples");
+ std::string address("amqp://127.0.0.1:5672/examples");
options opts(argc, argv);
- opts.add_value(url, 'a', "address", "listen on URL", "URL");
+ opts.add_value(address, 'a', "address", "listen on URL", "URL");
try {
opts.parse();
- server server(url);
- proton::container(server).run();
+ server srv(address);
+ proton::container(srv).run();
return 0;
} catch (const bad_option& e) {
std::cout << opts << std::endl << e.what() << std::endl;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
new file mode 100644
index 0000000..a2571ca
--- /dev/null
+++ b/examples/cpp/server_direct.cpp
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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 "options.hpp"
+
+#include "proton/container.hpp"
+#include "proton/messaging_handler.hpp"
+#include "proton/url.hpp"
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <sstream>
+
+class server : public proton::messaging_handler {
+ private:
+ typedef std::map<std::string, proton::sender> sender_map;
+ proton::url url;
+ proton::connection connection;
+ sender_map senders;
+ int address_counter;
+
+ public:
+
+ server(const std::string &u) : url(u), address_counter(0) {}
+
+ void on_start(proton::event &e) {
+ e.container().listen(url);
+ std::cout << "server listening on " << url << std::endl;
+ }
+
+ std::string to_upper(const std::string &s) {
+ std::string uc(s);
+ size_t l = uc.size();
+ for (size_t i=0; i<l; i++) uc[i] = std::toupper(uc[i]);
+ return uc;
+ }
+
+ std::string generate_address() {
+ std::ostringstream addr;
+ addr << "server" << address_counter++;
+ return addr.str();
+ }
+
+ void on_link_opening(proton::event& e) {
+ proton::link link = e.link();
+ if (link.is_sender() && link.remote_source() && link.remote_source().is_dynamic()) {
+ link.source().address(generate_address());
+ senders[link.source().address()] = link;
+ }
+ }
+
+ void on_message(proton::event &e) {
+ std::cout << "Received " << e.message().body() << std::endl;
+ std::string reply_to = e.message().reply_to();
+ sender_map::iterator it = senders.find(reply_to);
+ if (it == senders.end()) {
+ std::cout << "No link for reply_to: " << reply_to << std::endl;
+ } else {
+ proton::sender sender = it->second;
+ proton::message reply;
+ reply.address(reply_to);
+ reply.body(to_upper(e.message().body().get<std::string>()));
+ reply.correlation_id(e.message().correlation_id());
+ sender.send(reply);
+ }
+ }
+};
+
+int main(int argc, char **argv) {
+ // Command line options
+ std::string address("amqp://127.0.0.1:5672/examples");
+ options opts(argc, argv);
+ opts.add_value(address, 'a', "address", "listen on URL", "URL");
+ try {
+ opts.parse();
+ server srv(address);
+ proton::container(srv).run();
+ return 0;
+ } catch (const bad_option& e) {
+ std::cout << opts << std::endl << e.what() << std::endl;
+ } catch (const std::exception& e) {
+ std::cerr << e.what() << std::endl;
+ }
+ return 1;
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/cpp/sync_client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/sync_client.cpp b/examples/cpp/sync_client.cpp
index e141a3e..d0ad6fc 100644
--- a/examples/cpp/sync_client.cpp
+++ b/examples/cpp/sync_client.cpp
@@ -28,8 +28,10 @@
#include "proton/types.hpp"
#include <iostream>
+#include <vector>
#include <string>
+
int main(int argc, char **argv) {
// Command line options
proton::url url("127.0.0.1:5672/examples");
@@ -38,20 +40,20 @@ int main(int argc, char **argv) {
opts.add_value(url, 'a', "address", "connect to URL", "URL");
opts.add_value(timeout, 't', "timeout", "give up after this TIMEOUT (milliseconds)", "TIMEOUT");
- std::string requests[] = { "Twas brillig, and the slithy toves",
- "Did gire and gymble in the wabe.",
- "All mimsy were the borogroves,",
- "And the mome raths outgrabe." };
- int requests_size=4;
+ std::vector<std::string> requests;
+ requests.push_back("Twas brillig, and the slithy toves");
+ requests.push_back("Did gire and gymble in the wabe.");
+ requests.push_back("All mimsy were the borogroves,");
+ requests.push_back("And the mome raths outgrabe.");
try {
opts.parse();
- proton::duration d(timeout);
- proton::blocking_connection conn(url, d);
+
+ proton::blocking_connection conn(url, proton::duration(timeout));
proton::sync_request_response client(conn, url.path());
- for (int i=0; i<requests_size; i++) {
+ for (std::vector<std::string>::const_iterator i=requests.begin(); i != requests.end(); i++) {
proton::message request;
- request.body(requests[i]);
+ request.body(*i);
proton::message response = client.call(request);
std::cout << request.body() << " => " << response.body() << std::endl;
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/examples/python/client.py
----------------------------------------------------------------------
diff --git a/examples/python/client.py b/examples/python/client.py
index 18dc81a..b57e25b 100755
--- a/examples/python/client.py
+++ b/examples/python/client.py
@@ -35,9 +35,8 @@ class Client(MessagingHandler):
self.receiver = event.container.create_receiver(self.sender.connection, None, dynamic=True)
def next_request(self):
- if self.receiver.remote_source.address:
- req = Message(reply_to=self.receiver.remote_source.address, body=self.requests[0])
- self.sender.send(req)
+ req = Message(reply_to=self.receiver.remote_source.address, body=self.requests[0])
+ self.sender.send(req)
def on_link_opened(self, event):
if event.receiver == self.receiver:
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index d1b1ebc..519eb4e 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -108,7 +108,7 @@ macro(add_cpp_test test)
"PATH=$<TARGET_FILE_DIR:qpid-proton>"
$<TARGET_FILE:${test}> ${ARGN})
else ()
- add_test (NAME cpp_${test} COMMAND ${memcheck-cmd} ${test} ${ARGN})
+ add_test (NAME cpp_${test} COMMAND ${memcheck-cmd} ${CMAKE_CURRENT_BINARY_DIR}/${test} ${ARGN})
endif ()
endmacro(add_cpp_test)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/proton-c/bindings/cpp/docs/tutorial.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/tutorial.hpp b/proton-c/bindings/cpp/docs/tutorial.hpp
index 337ed21..51fe144 100644
--- a/proton-c/bindings/cpp/docs/tutorial.hpp
+++ b/proton-c/bindings/cpp/docs/tutorial.hpp
@@ -12,17 +12,17 @@ messaging applications in incremental steps. There are further examples, in
addition the ones mentioned in the tutorial.
Some of the examples require an AMQP *broker* that can receive, store and send
-messages. \ref broker.cpp is a simple example broker which you can use. When run
-without arguments it listens on `0.0.0.0:5672`, the standard AMQP port on all
-network interfaces. To use a different port or network interface:
+messages. \ref broker.cpp is a simple example broker. Run without arguments it
+listens on `0.0.0.0:5672`, the standard AMQP port on all network interfaces. To
+use a different port or network interface:
broker -a <host>:<port>
Instead of the example broker, you can use any AMQP 1.0 compliant broker. You
must configure your broker to have a queue (or topic) named "examples".
-Most of the examples take an optional URL argument or `-a URL` option the
-URL looks like:
+The `helloworld` examples take an optional URL argument. The other examples take
+an option `-a URL`. A URL looks like:
HOST:PORT/ADDRESS
@@ -41,10 +41,8 @@ receiving. In a realistic system the sender and receiver would normally be in
different processes. The complete example is \ref helloworld.cpp
We will include the following classes: `proton::container` runs an event loop
-which dispatches events to a `proton::messaging_handler`. This allows a
-*reactive* style of programming which is well suited to messaging
-applications. `proton::url` is a simple parser for the URL format described
-above.
+which dispatches events to a `proton::messaging_handler`. This allows a *reactive*
+style of programming which is well suited to messaging applications. `proton::url` is a simple parser for the URL format mentioned above.
\skip proton/container
\until proton/url
@@ -301,55 +299,117 @@ as a simple broker for testing purposes is an example of this).
Request/Response
----------------
-\todo TODO missing example in C++
-
A common pattern is to send a request message and expect a response message in
return. AMQP has special support for this pattern. Let's have a look at a simple
example. We'll start with \ref server.cpp, the program that will process the
request and send the response. Note that we are still using a broker in this
example.
-\todo TODO insert server snips
-
Our server will provide a very simple service: it will respond with the
body of the request converted to uppercase.
+\dontinclude server.cpp
+\skip class server
+\until };
+
The code here is not too different from the simple receiver example. When we
-receive a request however, we look at the proton::message::reply_to address on
-proton::message and create a sender for that over which to send the
-response. We'll cache the senders incase we get further requests with the same
-reply\_to.
+receive a request in `on_message` however, we look at the
+`proton::message::reply_to` address and create a sender with that address for
+the response. We'll cache the senders incase we get further requests with the
+same `reply_to`.
Now let's create a simple \ref client.cpp to test this service out.
-\todo TODO insert client snips
+\dontinclude client.cpp
+
+Our client takes a list of strings to send as requests
+
+\skipline client(
+
+Since we will be sending and receiving, we create a sender and a receiver in
+`on_start`. Our receiver has a blank address and sets the `dynamic` flag to
+true, which means we expect the remote end (broker or server) to assign a unique
+address for us.
-As well as sending requests, we need to be able to get back the
-responses. We create a receiver for that (see line 14), but we don't
-specify an address, we set the dynamic option which tells the broker we
-are connected to to create a temporary address over which we can receive
-our responses.
+\skip on_start
+\until }
+
+Now a function to send the next request from our list of requests. We set the
+reply_to address to be the dynamically assigned address of our receiver.
+
+\skip send_request
+\until }
-We need to use the address allocated by the broker as the reply\_to
-address of our requests, so we can't send them until the broker has
-confirmed our receiving link has been set up (at which point we will
-have our allocated address). To do that, we add an `on_link_opened()`
-method to our handler class, and if the link associated with event is
-the receiver, we use that as the trigger to send our first request.
+We need to use the address assigned by the broker as the `reply_to` address of
+our requests, so we can't send them until our receiver has been set up. To do
+that, we add an `on_link_opened()` method to our handler class, and if the link
+associated with event is the receiver, we use that as the trigger to send our
+first request.
+
+\skip on_link_opened
+\until }
+
+When we receive a reply, we send the next request.
+
+\skip on_message
+\until }
+\until }
+\until }
+
+Direct Request/Response
+-----------------------
-Again, we could avoid having any intermediary process here if we wished.
-The following code implementas a server to which the client above could
-connect directly without any need for a broker or similar.
+We can avoid the intermediary process by writing a server that accepts
+connections directly, \ref server_direct.cpp. It involves the following changes
+to our original server:
-\todo TODO missing server_direct.cpp
+\dontinclude server_direct.cpp
-Though this requires some more extensive changes than the simple sending
-and receiving examples, the essence of the program is still the same.
-Here though, rather than the server establishing a link for the
-response, it relies on the link that the client established, since that
-now comes in directly to the server process.
+First the server must generate a unique reply-to addreses for links from the
+client that request a dynamic address (previously this was done by the broker.)
+We use a simple counter.
+
+\skip generate_address
+\until }
+
+Next we need to handle incoming requests for links with dynamic addresses from
+the client. We give the link a unique address and record it in our `senders`
+map.
+
+\skip on_link_opening
+\until }
+
+Note we are interested in *sender* links above because we are implementing the
+server. A *receiver* link created on the client corresponds to a *sender* link
+on the server.
+
+Finally when we receive a message we look up its `reply_to` in our senders map and send the reply.
+
+\skip on_message
+\until }
+\until }
+\until }
+
+Synchronous Request/Response
+----------------------------
+
+The event-driven style of programming is extremely powerful, especially for
+server or mixed client-server programs. However for simple client-only programs
+a synchronous or blocking style of programming is sometimes simpler.
+
+`proton::blocking_connection` allows a blocking style of programming,
+`proton::sync_request_response` automates the common case of synchronous
+request/response, send a request and block for the response.
+
+\ref sync_client.cpp is our request/response client in blocking style. Here's the key section
+
+\dontinclude sync_client.cpp
+\skip conn(
+\until }
+
+*/
-### Miscellaneous
+/* TODO selector and browser
Many brokers offer the ability to consume messages based on a 'selector'
that defines which messages are of interest based on particular values
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/proton-c/bindings/cpp/docs/user.doxygen.in
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/docs/user.doxygen.in b/proton-c/bindings/cpp/docs/user.doxygen.in
index 93252d1..1d2eaf7 100644
--- a/proton-c/bindings/cpp/docs/user.doxygen.in
+++ b/proton-c/bindings/cpp/docs/user.doxygen.in
@@ -616,7 +616,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/include @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/docs @CMAKE_SOURCE_DIR@/examples/cpp/README.md
+INPUT = @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/include @CMAKE_SOURCE_DIR@/proton-c/bindings/cpp/docs @CMAKE_SOURCE_DIR@/examples/cpp/README.hpp
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/proton-c/bindings/cpp/include/proton/message.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message.hpp b/proton-c/bindings/cpp/include/proton/message.hpp
index 528088b..727d8a5 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -32,6 +32,8 @@ struct pn_data_t;
namespace proton {
+// TODO aconway 2015-08-07: make this a value-semantics class, hide pn_message_t.
+
/// An AMQP message.
class message : public proton_handle<pn_message_t>
{
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/proton-c/bindings/cpp/include/proton/proton_handle.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/proton_handle.hpp b/proton-c/bindings/cpp/include/proton/proton_handle.hpp
index 6fc9211..19ee90b 100644
--- a/proton-c/bindings/cpp/include/proton/proton_handle.hpp
+++ b/proton-c/bindings/cpp/include/proton/proton_handle.hpp
@@ -35,7 +35,6 @@ template <class> class proton_impl_ref;
*/
template <class T> class proton_handle {
public:
-
/**@return true if handle is valid, i.e. not null. */
bool is_valid() const { return impl_; }
@@ -50,8 +49,14 @@ template <class T> class proton_handle {
void swap(proton_handle<T>& h) { T* t = h.impl_; h.impl_ = impl_; impl_ = t; }
+ bool operator==(const proton_handle<T>& x) { return x.impl_ == impl_; }
+ bool operator!=(const proton_handle<T>& x) { return x.impl_ != impl_; }
+
+ T* raw() { return impl_; }
+
private:
// Not implemented, subclasses must implement.
+ // FIXME aconway 2015-08-07: why?
proton_handle(const proton_handle&);
proton_handle& operator=(const proton_handle&);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/db11dee5/proton-c/bindings/cpp/src/message.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/message.cpp b/proton-c/bindings/cpp/src/message.cpp
index 616f23d..e1bd535 100644
--- a/proton-c/bindings/cpp/src/message.cpp
+++ b/proton-c/bindings/cpp/src/message.cpp
@@ -73,9 +73,13 @@ void set_value(pn_data_t* d, const value& v) {
}
value get_value(pn_data_t* d) {
- values values(d);
- values.rewind();
- return values.get<value>();
+ if (d) {
+ values vals(d);
+ vals.rewind();
+ if (vals.more())
+ return vals.get<value>();
+ }
+ return value();
}
} // namespace
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org