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

Reply via email to