PROTON-1244: [C++ binding] Add conection options to set user and password
- Refactor to connection_options setting to minimize use of connector
- Improve broker example not to die if no queue address is supplied


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/0a398f60
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/0a398f60
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/0a398f60

Branch: refs/heads/master
Commit: 0a398f60494249411ef3b698c416022b276056c2
Parents: f8ad405
Author: Andrew Stitcher <[email protected]>
Authored: Thu Jul 21 02:00:38 2016 -0400
Committer: Andrew Stitcher <[email protected]>
Committed: Mon Jul 25 12:01:14 2016 -0400

----------------------------------------------------------------------
 examples/cpp/broker.cpp                         |  32 +++--
 examples/cpp/simple_recv.cpp                    |  18 ++-
 examples/cpp/simple_send.cpp                    |  16 ++-
 .../bindings/cpp/include/proton/connection.hpp  |   4 -
 .../cpp/include/proton/connection_options.hpp   |  15 ++-
 proton-c/bindings/cpp/src/connection.cpp        |  12 +-
 .../bindings/cpp/src/connection_options.cpp     | 127 ++++++++++---------
 proton-c/bindings/cpp/src/connector.cpp         |  22 +---
 proton-c/bindings/cpp/src/connector.hpp         |   9 +-
 proton-c/bindings/cpp/src/container_impl.cpp    |  16 ++-
 .../bindings/cpp/src/io/connection_engine.cpp   |   3 +-
 11 files changed, 148 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/examples/cpp/broker.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.cpp b/examples/cpp/broker.cpp
index bb3aefb..2749966 100644
--- a/examples/cpp/broker.cpp
+++ b/examples/cpp/broker.cpp
@@ -117,7 +117,7 @@ class queues {
     virtual ~queues() {}
 
     // Get or create a queue.
-    virtual queue &get(const std::string &address = std::string()) {
+    virtual queue &get(const std::string &address) {
         if (address.empty()) {
             throw std::runtime_error("empty queue name");
         }
@@ -157,11 +157,18 @@ class broker_handler : public proton::messaging_handler {
 
     void on_sender_open(proton::sender &sender) OVERRIDE {
         proton::source src(sender.source());
-        queue &q = src.dynamic() ?
-            queues_.dynamic() : queues_.get(src.address());
-        
sender.open(proton::sender_options().source(proton::source_options().address(q.name())));
-        q.subscribe(sender);
-        std::cout << "broker outgoing link from " << q.name() << std::endl;
+        queue *q;
+        if (src.dynamic()) {
+            q = &queues_.dynamic();
+        } else if (!src.address().empty()) {
+            q = &queues_.get(src.address());
+        } else {
+            sender.close(proton::error_condition("No queue address supplied"));
+            return;
+        }
+        
sender.open(proton::sender_options().source(proton::source_options().address(q->name())));
+        q->subscribe(sender);
+        std::cout << "broker outgoing link from " << q->name() << std::endl;
     }
 
     void on_receiver_open(proton::receiver &receiver) OVERRIDE {
@@ -169,6 +176,8 @@ class broker_handler : public proton::messaging_handler {
         if (!address.empty()) {
             
receiver.open(proton::receiver_options().target(proton::target_options().address(address)));
             std::cout << "broker incoming link to " << address << std::endl;
+        } else {
+            receiver.close(proton::error_condition("No queue address 
supplied"));
         }
     }
 
@@ -201,13 +210,10 @@ class broker_handler : public proton::messaging_handler {
     }
 
     void remove_stale_consumers(proton::connection connection) {
-        proton::session_range r1 = connection.sessions();
-        for (proton::session_iterator i1 = r1.begin(); i1 != r1.end(); ++i1) {
-            proton::sender_range r2 = i1->senders();
-            for (proton::sender_iterator i2 = r2.begin(); i2 != r2.end(); 
++i2) {
-                if (i2->active())
-                    unsubscribe(*i2);
-            }
+        proton::sender_range r = connection.senders();
+        for (proton::sender_iterator i = r.begin(); i != r.end(); ++i) {
+            if (i->active())
+                unsubscribe(*i);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/examples/cpp/simple_recv.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_recv.cpp b/examples/cpp/simple_recv.cpp
index 7621941..47f4d94 100644
--- a/examples/cpp/simple_recv.cpp
+++ b/examples/cpp/simple_recv.cpp
@@ -37,15 +37,21 @@
 class simple_recv : public proton::messaging_handler {
   private:
     std::string url;
+    std::string user;
+    std::string password;
     proton::receiver receiver;
     uint64_t expected;
     uint64_t received;
 
   public:
-    simple_recv(const std::string &s, int c) : url(s), expected(c), 
received(0) {}
+    simple_recv(const std::string &s, const std::string &u, const std::string 
&p, int c) :
+        url(s), user(u), password(p), expected(c), received(0) {}
 
     void on_container_start(proton::container &c) OVERRIDE {
-        receiver = c.open_receiver(url);
+        proton::connection_options co;
+        if (!user.empty()) co.user(user);
+        if (!password.empty()) co.password(password);
+        receiver = c.open_receiver(url, proton::receiver_options(), co);
         std::cout << "simple_recv listening on " << url << std::endl;
     }
 
@@ -68,17 +74,21 @@ class simple_recv : public proton::messaging_handler {
 
 int main(int argc, char **argv) {
     std::string address("127.0.0.1:5672/examples");
-
+    std::string user;
+    std::string password;
     int message_count = 100;
     example::options opts(argc, argv);
 
     opts.add_value(address, 'a', "address", "connect to and receive from URL", 
"URL");
     opts.add_value(message_count, 'm', "messages", "receive COUNT messages", 
"COUNT");
+    opts.add_value(user, 'u', "user", "authenticate as USER", "USER");
+    opts.add_value(password, 'p', "password", "authenticate with PASSWORD", 
"PASSWORD");
+
 
     try {
         opts.parse();
 
-        simple_recv recv(address, message_count);
+        simple_recv recv(address, user, password, message_count);
         proton::default_container(recv).run();
 
         return 0;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/examples/cpp/simple_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/simple_send.cpp b/examples/cpp/simple_send.cpp
index 3ce72b4..d63b0a8 100644
--- a/examples/cpp/simple_send.cpp
+++ b/examples/cpp/simple_send.cpp
@@ -35,16 +35,22 @@
 class simple_send : public proton::messaging_handler {
   private:
     std::string url;
+    std::string user;
+    std::string password;
     proton::sender sender;
     int sent;
     int confirmed;
     int total;
 
   public:
-    simple_send(const std::string &s, int c) : url(s), sent(0), confirmed(0), 
total(c) {}
+    simple_send(const std::string &s, const std::string &u, const std::string 
&p, int c) :
+        url(s), user(u), password(p), sent(0), confirmed(0), total(c) {}
 
     void on_container_start(proton::container &c) OVERRIDE {
-        sender = c.open_sender(url);
+        proton::connection_options co;
+        if (!user.empty()) co.user(user);
+        if (!password.empty()) co.password(password);
+        sender = c.open_sender(url, proton::sender_options(), co);
     }
 
     void on_sendable(proton::sender &s) OVERRIDE {
@@ -77,16 +83,20 @@ class simple_send : public proton::messaging_handler {
 
 int main(int argc, char **argv) {
     std::string address("127.0.0.1:5672/examples");
+    std::string user;
+    std::string password;
     int message_count = 100;
     example::options opts(argc, argv);
 
     opts.add_value(address, 'a', "address", "connect and send to URL", "URL");
     opts.add_value(message_count, 'm', "messages", "send COUNT messages", 
"COUNT");
+    opts.add_value(user, 'u', "user", "authenticate as USER", "USER");
+    opts.add_value(password, 'p', "password", "authenticate with PASSWORD", 
"PASSWORD");
 
     try {
         opts.parse();
 
-        simple_send send(address, message_count);
+        simple_send send(address, user, password, message_count);
         proton::default_container(send).run();
 
         return 0;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/include/proton/connection.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection.hpp 
b/proton-c/bindings/cpp/include/proton/connection.hpp
index b4a0767..062805f 100644
--- a/proton-c/bindings/cpp/include/proton/connection.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection.hpp
@@ -138,10 +138,6 @@ PN_CPP_CLASS_EXTERN connection : public 
internal::object<pn_connection_t>, publi
     /// @see @ref connection_options::idle_timeout
     PN_CPP_EXTERN uint32_t idle_timeout() const;
 
-  private:
-    void user(const std::string &);
-    void password(const std::string &);
-
     /// @cond INTERNAL
   friend class internal::factory<connection>;
   friend class connector;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/include/proton/connection_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/connection_options.hpp 
b/proton-c/bindings/cpp/include/proton/connection_options.hpp
index bc00bb9..0c88042 100644
--- a/proton-c/bindings/cpp/include/proton/connection_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/connection_options.hpp
@@ -108,6 +108,17 @@ class connection_options {
     /// connections.
     PN_CPP_EXTERN connection_options& virtual_host(const std::string &name);
 
+    /// Set the user name used to authenticate the connection.
+    ///
+    /// This will override any user name that is specified in the url
+    /// used for container::connect.
+    /// It will be ignored if the connection is created by container::listen as
+    /// a listening connection has no user name.
+    PN_CPP_EXTERN connection_options& user(const std::string& user);
+
+    /// Set the password used to authenticate the connection
+    PN_CPP_EXTERN connection_options& password(const std::string& pass);
+
     /// @cond INTERNAL
     // XXX settle questions about reconnect_timer - consider simply
     // reconnect_options and making reconnect_timer internal
@@ -142,9 +153,9 @@ class connection_options {
     PN_CPP_EXTERN connection_options& update(const connection_options& other);
 
   private:
-    void apply(connection&) const;
+    void apply_unbound(connection&) const;
+    void apply_bound(connection&) const;
     proton_handler* handler() const;
-    bool is_virtual_host_set() const;
 
     class impl;
     internal::pn_unique_ptr<impl> impl_;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/src/connection.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection.cpp 
b/proton-c/bindings/cpp/src/connection.cpp
index 8acf163..dcc1ad5 100644
--- a/proton-c/bindings/cpp/src/connection.cpp
+++ b/proton-c/bindings/cpp/src/connection.cpp
@@ -50,13 +50,7 @@ void connection::open() {
 }
 
 void connection::open(const connection_options &opts) {
-    connector *connector = dynamic_cast<class connector*>(
-        connection_context::get(pn_object()).handler.get());
-    if (connector)
-        // connector has an internal copy of opts
-        connector->apply_options();
-    else
-        opts.apply(*this);
+    opts.apply_unbound(*this);
     pn_connection_open(pn_object());
 }
 
@@ -166,8 +160,4 @@ uint32_t connection::idle_timeout() const {
     return 
pn_transport_get_remote_idle_timeout(pn_connection_transport(pn_object()));
 }
 
-void connection::user(const std::string &name) { 
pn_connection_set_user(pn_object(), name.c_str()); }
-
-void connection::password(const std::string &pass) { 
pn_connection_set_password(pn_object(), pass.c_str()); }
-
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/src/connection_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connection_options.cpp 
b/proton-c/bindings/cpp/src/connection_options.cpp
index 87f0284..d953369 100644
--- a/proton-c/bindings/cpp/src/connection_options.cpp
+++ b/proton-c/bindings/cpp/src/connection_options.cpp
@@ -54,6 +54,8 @@ class connection_options::impl {
     option<duration> idle_timeout;
     option<std::string> container_id;
     option<std::string> virtual_host;
+    option<std::string> user;
+    option<std::string> password;
     option<reconnect_timer> reconnect;
     option<class ssl_client_options> ssl_client_options;
     option<class ssl_server_options> ssl_server_options;
@@ -70,75 +72,78 @@ class connection_options::impl {
      * transport options (set once per transport over the life of the
      * connection).
      */
-    void apply(connection& c) {
+    void apply_unbound(connection& c) {
         pn_connection_t *pnc = unwrap(c);
-        pn_transport_t *pnt = pn_connection_transport(pnc);
         connector *outbound = dynamic_cast<connector*>(
             connection_context::get(c).handler.get());
-        bool uninit = c.uninitialized();
 
         // Only apply connection options if uninit.
-        if (uninit) {
-            std::string vhost;
-            if (virtual_host.set)
-                vhost = virtual_host.value;
-            else if (outbound)
-                vhost = outbound->address().host();
-
-            if (reconnect.set && outbound)
-                outbound->reconnect_timer(reconnect.value);
-            if (container_id.set)
-                pn_connection_set_container(pnc, container_id.value.c_str());
-            if (!vhost.empty())
-                pn_connection_set_hostname(pnc, vhost.c_str());
-        }
+        bool uninit = c.uninitialized();
+        if (!uninit) return;
+
+        if (reconnect.set && outbound)
+            outbound->reconnect_timer(reconnect.value);
+        if (container_id.set)
+            pn_connection_set_container(pnc, container_id.value.c_str());
+        if (virtual_host.set)
+            pn_connection_set_hostname(pnc, virtual_host.value.c_str());
+        if (user.set)
+            pn_connection_set_user(pnc, user.value.c_str());
+        if (password.set)
+            pn_connection_set_password(pnc, password.value.c_str());
+    }
 
+    void apply_bound(connection& c) {
         // Transport options.  pnt is NULL between reconnect attempts
         // and if there is a pipelined open frame.
-        if (pnt && (uninit || (outbound && !outbound->transport_configured())))
-        {
-            // SSL
-            if (outbound && outbound->address().scheme() == url::AMQPS) {
-                // A side effect of pn_ssl() is to set the ssl peer
-                // hostname to the connection hostname, which has
-                // already been adjusted for the virtual_host option.
-                pn_ssl_t *ssl = pn_ssl(pnt);
-                if (pn_ssl_init(ssl, ssl_client_options.value.pn_domain(), 
NULL))
-                    throw error(MSG("client SSL/TLS initialization error"));
-            } else if (!outbound) {
-                // TODO aconway 2016-05-13: reactor only
-                pn_acceptor_t *pnp = pn_connection_acceptor(pnc);
-                if (pnp) {
-                    listener_context &lc(listener_context::get(pnp));
-                    if (lc.ssl) {
-                        pn_ssl_t *ssl = pn_ssl(pnt);
-                        if (pn_ssl_init(ssl, 
ssl_server_options.value.pn_domain(), NULL))
-                            throw error(MSG("server SSL/TLS initialization 
error"));
-                    }
-                }
-            }
+        pn_connection_t *pnc = unwrap(c);
+        connector *outbound = dynamic_cast<connector*>(
+            connection_context::get(c).handler.get());
 
-            // SASL
-            if (!sasl_enabled.set || sasl_enabled.value) {
-                if (sasl_enabled.set)  // Explicitly set, not just default 
behaviour.
-                    pn_sasl(pnt);          // Force a sasl instance.  Lazily 
create one otherwise.
-                if (sasl_allow_insecure_mechs.set)
-                    pn_sasl_set_allow_insecure_mechs(pn_sasl(pnt), 
sasl_allow_insecure_mechs.value);
-                if (sasl_allowed_mechs.set)
-                    pn_sasl_allowed_mechs(pn_sasl(pnt), 
sasl_allowed_mechs.value.c_str());
-                if (sasl_config_name.set)
-                    pn_sasl_config_name(pn_sasl(pnt), 
sasl_config_name.value.c_str());
-                if (sasl_config_path.set)
-                    pn_sasl_config_path(pn_sasl(pnt), 
sasl_config_path.value.c_str());
+        pn_transport_t *pnt = pn_connection_transport(pnc);
+        if (!pnt) return;
+
+        // SSL
+        if (outbound && outbound->address().scheme() == url::AMQPS) {
+            // A side effect of pn_ssl() is to set the ssl peer
+            // hostname to the connection hostname, which has
+            // already been adjusted for the virtual_host option.
+            pn_ssl_t *ssl = pn_ssl(pnt);
+            if (pn_ssl_init(ssl, ssl_client_options.value.pn_domain(), NULL))
+                throw error(MSG("client SSL/TLS initialization error"));
+        } else if (!outbound) {
+            // TODO aconway 2016-05-13: reactor only
+            pn_acceptor_t *pnp = pn_connection_acceptor(pnc);
+            if (pnp) {
+                listener_context &lc(listener_context::get(pnp));
+                if (lc.ssl) {
+                    pn_ssl_t *ssl = pn_ssl(pnt);
+                    if (pn_ssl_init(ssl, ssl_server_options.value.pn_domain(), 
NULL))
+                        throw error(MSG("server SSL/TLS initialization 
error"));
+                }
             }
+        }
 
-            if (max_frame_size.set)
-                pn_transport_set_max_frame(pnt, max_frame_size.value);
-            if (max_sessions.set)
-                pn_transport_set_channel_max(pnt, max_sessions.value);
-            if (idle_timeout.set)
-                pn_transport_set_idle_timeout(pnt, 
idle_timeout.value.milliseconds());
+        // SASL
+        if (!sasl_enabled.set || sasl_enabled.value) {
+            if (sasl_enabled.set)  // Explicitly set, not just default 
behaviour.
+                pn_sasl(pnt);          // Force a sasl instance.  Lazily 
create one otherwise.
+            if (sasl_allow_insecure_mechs.set)
+                pn_sasl_set_allow_insecure_mechs(pn_sasl(pnt), 
sasl_allow_insecure_mechs.value);
+            if (sasl_allowed_mechs.set)
+                pn_sasl_allowed_mechs(pn_sasl(pnt), 
sasl_allowed_mechs.value.c_str());
+            if (sasl_config_name.set)
+                pn_sasl_config_name(pn_sasl(pnt), 
sasl_config_name.value.c_str());
+            if (sasl_config_path.set)
+                pn_sasl_config_path(pn_sasl(pnt), 
sasl_config_path.value.c_str());
         }
+
+        if (max_frame_size.set)
+            pn_transport_set_max_frame(pnt, max_frame_size.value);
+        if (max_sessions.set)
+            pn_transport_set_channel_max(pnt, max_sessions.value);
+        if (idle_timeout.set)
+            pn_transport_set_idle_timeout(pnt, 
idle_timeout.value.milliseconds());
     }
 
     void update(const impl& x) {
@@ -148,6 +153,8 @@ class connection_options::impl {
         idle_timeout.update(x.idle_timeout);
         container_id.update(x.container_id);
         virtual_host.update(x.virtual_host);
+        user.update(x.user);
+        password.update(x.password);
         reconnect.update(x.reconnect);
         ssl_client_options.update(x.ssl_client_options);
         ssl_server_options.update(x.ssl_server_options);
@@ -186,6 +193,8 @@ connection_options& 
connection_options::max_sessions(uint16_t n) { impl_->max_se
 connection_options& connection_options::idle_timeout(duration t) { 
impl_->idle_timeout = t; return *this; }
 connection_options& connection_options::container_id(const std::string &id) { 
impl_->container_id = id; return *this; }
 connection_options& connection_options::virtual_host(const std::string &id) { 
impl_->virtual_host = id; return *this; }
+connection_options& connection_options::user(const std::string &user) { 
impl_->user = user; return *this; }
+connection_options& connection_options::password(const std::string &password) 
{ impl_->password = password; return *this; }
 connection_options& connection_options::reconnect(const reconnect_timer &rc) { 
impl_->reconnect = rc; return *this; }
 connection_options& connection_options::ssl_client_options(const class 
ssl_client_options &c) { impl_->ssl_client_options = c; return *this; }
 connection_options& connection_options::ssl_server_options(const class 
ssl_server_options &c) { impl_->ssl_server_options = c; return *this; }
@@ -195,7 +204,7 @@ connection_options& 
connection_options::sasl_allowed_mechs(const std::string &s)
 connection_options& connection_options::sasl_config_name(const std::string &n) 
{ impl_->sasl_config_name = n; return *this; }
 connection_options& connection_options::sasl_config_path(const std::string &p) 
{ impl_->sasl_config_path = p; return *this; }
 
-void connection_options::apply(connection& c) const { impl_->apply(c); }
+void connection_options::apply_unbound(connection& c) const { 
impl_->apply_unbound(c); }
+void connection_options::apply_bound(connection& c) const { 
impl_->apply_bound(c); }
 proton_handler* connection_options::handler() const { return 
impl_->handler.value; }
-bool connection_options::is_virtual_host_set() const { return 
impl_->virtual_host.set; }
 } // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/src/connector.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connector.cpp 
b/proton-c/bindings/cpp/src/connector.cpp
index d1b6936..5e6f0fd 100644
--- a/proton-c/bindings/cpp/src/connector.cpp
+++ b/proton-c/bindings/cpp/src/connector.cpp
@@ -38,19 +38,12 @@
 
 namespace proton {
 
-connector::connector(connection&c, const url& a, const connection_options 
&opts) :
-    connection_(c), address_(a), options_(opts), reconnect_timer_(0), 
transport_configured_(false)
+connector::connector(connection&c, const connection_options& options, const 
url& a) :
+    connection_(c), options_(options), address_(a), reconnect_timer_(0)
 {}
 
 connector::~connector() { delete reconnect_timer_; }
 
-void connector::apply_options() {
-    if (!connection_) return;
-    options_.apply(connection_);
-}
-
-bool connector::transport_configured() { return transport_configured_; }
-
 void connector::reconnect_timer(const class reconnect_timer &rt) {
     delete reconnect_timer_;
     reconnect_timer_ = new class reconnect_timer(rt);
@@ -59,18 +52,10 @@ void connector::reconnect_timer(const class reconnect_timer 
&rt) {
 void connector::connect() {
     pn_transport_t *pnt = pn_transport();
     transport t(make_wrapper(pnt));
-    if (!address_.user().empty())
-        connection_.user(address_.user());
-    if (!address_.password().empty())
-        connection_.password(address_.password());
     pn_transport_bind(pnt, unwrap(connection_));
     pn_decref(pnt);
     // Apply options to the new transport.
-    options_.apply(connection_);
-    // if virtual-host not set, use host from address as default
-    if (!options_.is_virtual_host_set())
-        pn_connection_set_hostname(unwrap(connection_), 
address_.host().c_str());
-    transport_configured_ = true;
+    options_.apply_bound(connection_);
 }
 
 void connector::on_connection_local_open(proton_event &) {
@@ -95,7 +80,6 @@ void connector::on_transport_closed(proton_event &) {
     if (connection_.active()) {
         if (reconnect_timer_) {
             pn_transport_unbind(unwrap(connection_.transport()));
-            transport_configured_ = false;
             int delay = reconnect_timer_->next_delay(timestamp::now());
             if (delay >= 0) {
                 if (delay == 0) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/src/connector.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/connector.hpp 
b/proton-c/bindings/cpp/src/connector.hpp
index 0970ed6..5b6707a 100644
--- a/proton-c/bindings/cpp/src/connector.hpp
+++ b/proton-c/bindings/cpp/src/connector.hpp
@@ -40,13 +40,11 @@ class reconnect_timer;
 class connector : public proton_handler
 {
   public:
-    connector(connection &c, const url&, const connection_options &opts);
+    connector(connection &c, const connection_options &options, const url&);
     ~connector();
     const url &address() const { return address_; }
     void connect();
-    void apply_options();
     void reconnect_timer(const class reconnect_timer &);
-    bool transport_configured();
     virtual void on_connection_local_open(proton_event &e);
     virtual void on_connection_remote_open(proton_event &e);
     virtual void on_connection_init(proton_event &e);
@@ -56,10 +54,9 @@ class connector : public proton_handler
 
   private:
     connection connection_;
-    url address_;
-    connection_options options_;
+    const connection_options options_;
+    const url address_;
     class reconnect_timer *reconnect_timer_;
-    bool transport_configured_;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp 
b/proton-c/bindings/cpp/src/container_impl.cpp
index eee56ed..7b14afa 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -44,9 +44,9 @@
 #include "proton_event.hpp"
 
 #include <proton/connection.h>
-#include <proton/session.h>
 #include <proton/handlers.h>
 #include <proton/reactor.h>
+#include <proton/session.h>
 
 namespace proton {
 
@@ -184,11 +184,18 @@ returned<connection> container_impl::connect(const 
std::string &urlstr, const co
     proton::url  url(urlstr);
     internal::pn_ptr<pn_handler_t> chandler = h ? cpp_handler(h) : 
internal::pn_ptr<pn_handler_t>();
     connection conn(reactor_.connection_to_host(url.host(), url.port(), 
chandler.get()));
-    internal::pn_unique_ptr<connector> ctor(new connector(conn, url, opts));
+    internal::pn_unique_ptr<connector> ctor(new connector(conn, opts, url));
     connection_context& cc(connection_context::get(conn));
     cc.handler.reset(ctor.release());
     cc.event_loop.reset(new immediate_event_loop);
-    pn_connection_set_container(unwrap(conn), id_.c_str());
+
+    pn_connection_t *pnc = unwrap(conn);
+    pn_connection_set_container(pnc, id_.c_str());
+    pn_connection_set_hostname(pnc, url.host().c_str());
+    if (!url.user().empty())
+        pn_connection_set_user(pnc, url.user().c_str());
+    if (!url.password().empty())
+        pn_connection_set_password(pnc, url.password().c_str());
 
     conn.open(opts);
     return make_thread_safe(conn);
@@ -310,7 +317,8 @@ void container_impl::configure_server_connection(connection 
&c) {
     pn_connection_set_container(unwrap(c), id_.c_str());
     connection_options opts = server_connection_options_;
     opts.update(lc.get_options());
-    opts.apply(c);
+    // Unbound options don't apply to server connection
+    opts.apply_bound(c);
     // Handler applied separately
     proton_handler *h = opts.handler();
     if (h) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0a398f60/proton-c/bindings/cpp/src/io/connection_engine.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/io/connection_engine.cpp 
b/proton-c/bindings/cpp/src/io/connection_engine.cpp
index 5c2c092..e93dbbb 100644
--- a/proton-c/bindings/cpp/src/io/connection_engine.cpp
+++ b/proton-c/bindings/cpp/src/io/connection_engine.cpp
@@ -64,7 +64,8 @@ connection_engine::connection_engine(class container& cont, 
event_loop* loop) :
 
 void connection_engine::configure(const connection_options& opts) {
     proton::connection c = connection();
-    opts.apply(c);
+    opts.apply_unbound(c);
+    opts.apply_bound(c);
     handler_ = opts.handler();
     connection_context::get(connection()).collector = c_engine_.collector;
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to