This is an automated email from the ASF dual-hosted git repository. jdanek pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
The following commit(s) were added to refs/heads/master by this push: new 8ddf539 PROTON-2332: [C++] Allow access to link properties (#293) 8ddf539 is described below commit 8ddf5399013b02f1fd13bda3fee7886bd48a98be Author: Pete Fawcett <pjfawc...@users.noreply.github.com> AuthorDate: Wed Mar 24 09:59:52 2021 +0000 PROTON-2332: [C++] Allow access to link properties (#293) Enable setting of link properties via sender and receiver options Enable querying of link properties set by remote end --- cpp/include/proton/link.hpp | 4 ++ cpp/include/proton/receiver_options.hpp | 5 ++ cpp/include/proton/sender_options.hpp | 6 ++ cpp/src/container_test.cpp | 99 ++++++++++++++++++++++++++++++++- cpp/src/link.cpp | 10 ++++ cpp/src/receiver_options.cpp | 7 +++ cpp/src/sender_options.cpp | 7 +++ 7 files changed, 137 insertions(+), 1 deletion(-) diff --git a/cpp/include/proton/link.hpp b/cpp/include/proton/link.hpp index 5c5280e..c7d55b2 100644 --- a/cpp/include/proton/link.hpp +++ b/cpp/include/proton/link.hpp @@ -27,6 +27,7 @@ #include "./endpoint.hpp" #include "./internal/object.hpp" +#include <map> #include <string> /// @file @@ -90,6 +91,9 @@ PN_CPP_CLASS_EXTERN link : public internal::object<pn_link_t> , public endpoint /// The session that owns this link. PN_CPP_EXTERN class session session() const; + /// **Unsettled API** - Properties supplied by the remote link endpoint. + PN_CPP_EXTERN std::map<symbol, value> properties() const; + protected: /// @cond INTERNAL diff --git a/cpp/include/proton/receiver_options.hpp b/cpp/include/proton/receiver_options.hpp index 0efe55e..bcf8276 100644 --- a/cpp/include/proton/receiver_options.hpp +++ b/cpp/include/proton/receiver_options.hpp @@ -26,6 +26,9 @@ #include "./internal/export.hpp" #include "./internal/pn_unique_ptr.hpp" #include "./delivery_mode.hpp" +#include "./types_fwd.hpp" + +#include <map> #include <string> /// @file @@ -100,6 +103,8 @@ class receiver_options { /// Set the link name. If not set a unique name is generated. PN_CPP_EXTERN receiver_options& name(const std::string& name); + /// **Unsettled API** - Link properties. + PN_CPP_EXTERN receiver_options& properties(const std::map<symbol, value>&); private: void apply(receiver &) const; diff --git a/cpp/include/proton/sender_options.hpp b/cpp/include/proton/sender_options.hpp index 970da7e..143db3f 100644 --- a/cpp/include/proton/sender_options.hpp +++ b/cpp/include/proton/sender_options.hpp @@ -26,6 +26,9 @@ #include "./internal/export.hpp" #include "./internal/pn_unique_ptr.hpp" #include "./delivery_mode.hpp" +#include "./types_fwd.hpp" + +#include <map> #include <string> /// @file @@ -91,6 +94,9 @@ class sender_options { /// Set the link name. If not set a unique name is generated. PN_CPP_EXTERN sender_options& name(const std::string& name); + /// **Unsettled API** - Link properties. + PN_CPP_EXTERN sender_options& properties(const std::map<symbol, value>&); + private: void apply(sender&) const; const std::string* get_name() const; // Pointer to name if set, else 0 diff --git a/cpp/src/container_test.cpp b/cpp/src/container_test.cpp index a3e8b56..d6e347e 100644 --- a/cpp/src/container_test.cpp +++ b/cpp/src/container_test.cpp @@ -23,9 +23,13 @@ #include "proton/connection.hpp" #include "proton/connection_options.hpp" #include "proton/container.hpp" -#include "proton/messaging_handler.hpp" #include "proton/listener.hpp" #include "proton/listen_handler.hpp" +#include "proton/messaging_handler.hpp" +#include "proton/receiver.hpp" +#include "proton/receiver_options.hpp" +#include "proton/sender.hpp" +#include "proton/sender_options.hpp" #include "proton/work_queue.hpp" #include <cstdlib> @@ -336,6 +340,97 @@ int test_container_schedule_stop() { return 0; } +class link_test_handler : public proton::messaging_handler {//, public proton::listen_handler { + public: + bool had_receiver; + bool had_sender; + + test_listen_handler listen_handler; + proton::listener listener; + + proton::receiver_options receiver_options; + proton::sender_options sender_options; + + std::map<proton::symbol, proton::value> peer_receiver_properties; + std::map<proton::symbol, proton::value> peer_sender_properties; + + link_test_handler(const proton::receiver_options &r_opts=proton::receiver_options(), + const proton::sender_options &s_opts=proton::sender_options()) + : had_receiver(false), + had_sender(false), + receiver_options(r_opts), + sender_options(s_opts) + {} + + void on_container_start(proton::container &c) PN_CPP_OVERRIDE { + listener = c.listen("//:0", listen_handler); + } + + void on_connection_open(proton::connection &c) PN_CPP_OVERRIDE { + if (c.uninitialized()) { + proton::messaging_handler::on_connection_open(c); + c.open_receiver("", receiver_options); + c.open_sender("", sender_options); + } + } + + + void check_close(proton::link &l) { + if (had_receiver && had_sender) { + l.connection().close(); + listener.stop(); + } + } + + void on_receiver_open(proton::receiver &l) PN_CPP_OVERRIDE { + had_receiver = true; + // When a client creates a sender then the server is notified about it as a receiver + peer_sender_properties = l.properties(); + check_close(l); + } + + void on_sender_open(proton::sender &l) PN_CPP_OVERRIDE { + had_sender = true; + // When a client creates a receiver then the server is notified about it as a sender + peer_receiver_properties = l.properties(); + check_close(l); + } +}; + +int test_container_links_no_properties() { + link_test_handler th; + proton::container(th).run(); + ASSERT(th.had_receiver); + ASSERT(th.had_sender); + ASSERT_EQUAL(th.peer_receiver_properties.size(), 0u); + ASSERT_EQUAL(th.peer_sender_properties.size(), 0u); + return 0; +} + +int test_container_links_properties() { + proton::receiver_options r_opts; + std::map<proton::symbol, proton::value> r_props; + r_props["recv.prop_str"] = "receiver_string"; + r_opts.properties(r_props); + + proton::sender_options s_opts; + std::map<proton::symbol, proton::value> s_props; + s_props["send.prop_str"] = "sender_string"; + s_props["send.prop_int"] = 123456789; + s_opts.properties(s_props); + + link_test_handler th(r_opts, s_opts); + proton::container(th).run(); + + ASSERT(th.had_receiver); + ASSERT(th.had_sender); + ASSERT_EQUAL(th.peer_receiver_properties.size(), 1u); + ASSERT_EQUAL(th.peer_receiver_properties["recv.prop_str"], "receiver_string"); + ASSERT_EQUAL(th.peer_sender_properties.size(), 2u); + ASSERT_EQUAL(th.peer_sender_properties["send.prop_str"], "sender_string"); + ASSERT_EQUAL(th.peer_sender_properties["send.prop_int"], 123456789); + return 0; +} #if PN_CPP_SUPPORTS_THREADS // Tests that require thread support @@ -501,6 +596,8 @@ int main(int argc, char** argv) { RUN_ARGV_TEST(failed, test_container_immediate_stop()); RUN_ARGV_TEST(failed, test_container_pre_stop()); RUN_ARGV_TEST(failed, test_container_schedule_stop()); + RUN_ARGV_TEST(failed, test_container_links_no_properties()); + RUN_ARGV_TEST(failed, test_container_links_properties()); #if PN_CPP_SUPPORTS_THREADS RUN_ARGV_TEST(failed, test_container_mt_stop_empty()); RUN_ARGV_TEST(failed, test_container_mt_stop()); diff --git a/cpp/src/link.cpp b/cpp/src/link.cpp index 1cb87ba..c94fb44 100644 --- a/cpp/src/link.cpp +++ b/cpp/src/link.cpp @@ -21,6 +21,7 @@ #include "proton_bits.hpp" +#include "proton/codec/map.hpp" #include "proton/link.hpp" #include "proton/error.hpp" #include "proton/connection.hpp" @@ -82,6 +83,15 @@ class session link::session() const { return make_wrapper(pn_link_session(pn_object())); } +std::map<symbol, value> link::properties() const { + std::map<symbol, value> ret; + value props(pn_link_remote_properties(pn_object())); + if (!props.empty()) { + get(props, ret); + } + return ret; +} + error_condition link::error() const { return make_wrapper(pn_link_remote_condition(pn_object())); } diff --git a/cpp/src/receiver_options.cpp b/cpp/src/receiver_options.cpp index f7ef5a8..8f315e2 100644 --- a/cpp/src/receiver_options.cpp +++ b/cpp/src/receiver_options.cpp @@ -19,6 +19,7 @@ * */ +#include "proton/codec/map.hpp" #include "proton/receiver_options.hpp" #include "proton/messaging_handler.hpp" #include "proton/source_options.hpp" @@ -71,6 +72,7 @@ class receiver_options::impl { option<source_options> source; option<target_options> target; option<std::string> name; + option<std::map<symbol, value> > properties; void apply(receiver& r) { @@ -89,6 +91,9 @@ class receiver_options::impl { proton::target local_t(make_wrapper<proton::target>(pn_link_target(unwrap(r)))); target.value.apply(local_t); } + if (properties.set) { + value(pn_link_properties(unwrap(r))) = properties.value; + } } } @@ -102,6 +107,7 @@ class receiver_options::impl { source.update(x.source); target.update(x.target); name.update(x.name); + properties.update(x.properties); } }; @@ -126,6 +132,7 @@ receiver_options& receiver_options::credit_window(int w) {impl_->credit_window = receiver_options& receiver_options::source(source_options &s) {impl_->source = s; return *this; } receiver_options& receiver_options::target(target_options &s) {impl_->target = s; return *this; } receiver_options& receiver_options::name(const std::string &s) {impl_->name = s; return *this; } +receiver_options& receiver_options::properties(const std::map<symbol, value> &props) { impl_->properties = props; return *this; } void receiver_options::apply(receiver& r) const { impl_->apply(r); } diff --git a/cpp/src/sender_options.cpp b/cpp/src/sender_options.cpp index 1cc0643..fc6b39e 100644 --- a/cpp/src/sender_options.cpp +++ b/cpp/src/sender_options.cpp @@ -19,6 +19,7 @@ * */ +#include "proton/codec/map.hpp" #include "proton/sender_options.hpp" #include "proton/messaging_handler.hpp" #include "proton/source_options.hpp" @@ -66,6 +67,7 @@ class sender_options::impl { option<source_options> source; option<target_options> target; option<std::string> name; + option<std::map<symbol, value> > properties; void apply(sender& s) { if (s.uninitialized()) { @@ -80,6 +82,9 @@ class sender_options::impl { proton::target local_t(make_wrapper<proton::target>(pn_link_target(unwrap(s)))); target.value.apply(local_t); } + if (properties.set) { + value(pn_link_properties(unwrap(s))) = properties.value; + } } } @@ -90,6 +95,7 @@ class sender_options::impl { source.update(x.source); target.update(x.target); name.update(x.name); + properties.update(x.properties); } }; @@ -113,6 +119,7 @@ sender_options& sender_options::auto_settle(bool b) {impl_->auto_settle = b; ret sender_options& sender_options::source(const source_options &s) {impl_->source = s; return *this; } sender_options& sender_options::target(const target_options &s) {impl_->target = s; return *this; } sender_options& sender_options::name(const std::string &s) {impl_->name = s; return *this; } +sender_options& sender_options::properties(const std::map<symbol, value> &props) { impl_->properties = props; return *this; } void sender_options::apply(sender& s) const { impl_->apply(s); } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org