Repository: qpid-proton
Updated Branches:
  refs/heads/master c275b4c59 -> a40b77be8


PROTON-1183: hide terminus, replace with source and target


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

Branch: refs/heads/master
Commit: a40b77be8ad267f9f57aa4012f4b6cebb47cdc53
Parents: c275b4c
Author: Clifford Jansen <cliffjan...@apache.org>
Authored: Tue Apr 26 11:50:16 2016 -0700
Committer: Clifford Jansen <cliffjan...@apache.org>
Committed: Tue Apr 26 11:50:16 2016 -0700

----------------------------------------------------------------------
 examples/cpp/broker.hpp                         |  23 +--
 examples/cpp/client.cpp                         |  14 +-
 examples/cpp/engine/client.cpp                  |  12 +-
 examples/cpp/queue_browser.cpp                  |   8 +-
 examples/cpp/server_direct.cpp                  |   8 +-
 proton-c/bindings/cpp/CMakeLists.txt            |   3 +
 proton-c/bindings/cpp/include/proton/link.hpp   |  15 +-
 .../bindings/cpp/include/proton/receiver.hpp    |   9 +-
 .../cpp/include/proton/receiver_options.hpp     |  12 +-
 proton-c/bindings/cpp/include/proton/sender.hpp |  12 +-
 .../cpp/include/proton/sender_options.hpp       |   8 +
 .../bindings/cpp/include/proton/settings.hpp    |  59 +++++++
 proton-c/bindings/cpp/include/proton/source.hpp |  59 +++++++
 .../cpp/include/proton/source_options.hpp       |  95 ++++++++++
 proton-c/bindings/cpp/include/proton/target.hpp |  60 +++++++
 .../cpp/include/proton/target_options.hpp       |  93 ++++++++++
 .../bindings/cpp/include/proton/terminus.hpp    | 109 ++++--------
 proton-c/bindings/cpp/src/link.cpp              |   5 -
 proton-c/bindings/cpp/src/node_options.cpp      | 177 +++++++++++++++++++
 proton-c/bindings/cpp/src/receiver.cpp          |   8 +
 proton-c/bindings/cpp/src/receiver_options.cpp  |  30 +++-
 proton-c/bindings/cpp/src/sender.cpp            |   8 +
 proton-c/bindings/cpp/src/sender_options.cpp    |  16 ++
 proton-c/bindings/cpp/src/session.cpp           |  10 +-
 proton-c/bindings/cpp/src/source.cpp            |  43 +++++
 proton-c/bindings/cpp/src/target.cpp            |  40 +++++
 proton-c/bindings/cpp/src/terminus.cpp          |  44 +++--
 27 files changed, 827 insertions(+), 153 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/examples/cpp/broker.hpp
----------------------------------------------------------------------
diff --git a/examples/cpp/broker.hpp b/examples/cpp/broker.hpp
index a89c948..0fc45fa 100644
--- a/examples/cpp/broker.hpp
+++ b/examples/cpp/broker.hpp
@@ -35,6 +35,10 @@
 #include "proton/tracker.hpp"
 #include "proton/transport.hpp"
 #include "proton/url.hpp"
+#include "proton/sender_options.hpp"
+#include "proton/receiver_options.hpp"
+#include "proton/source_options.hpp"
+#include "proton/target_options.hpp"
 
 #include <iostream>
 #include <deque>
@@ -157,25 +161,24 @@ class broker_handler : public proton::handler {
     broker_handler(queues& qs) : queues_(qs) {}
 
     void on_sender_open(proton::sender &sender) override {
-        proton::terminus remote_source(sender.remote_source());
-        queue &q = remote_source.dynamic() ?
-            queues_.dynamic() : queues_.get(remote_source.address());
-        sender.local_source().address(q.name());
-
+        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;
     }
 
     void on_receiver_open(proton::receiver &receiver) override {
-        std::string address = receiver.remote_target().address();
+        std::string address = receiver.target().address();
         if (!address.empty()) {
-            receiver.local_target().address(address);
+            
receiver.open(proton::receiver_options().target(proton::target_options().address(address)));
             std::cout << "broker incoming link to " << address << std::endl;
         }
     }
 
     void unsubscribe(proton::sender lnk) {
-        std::string address = lnk.local_source().address();
+        std::string address = lnk.source().address();
 
         if (queues_.get(address).unsubscribe(lnk)) {
             queues_.erase(address);
@@ -214,13 +217,13 @@ class broker_handler : public proton::handler {
     }
 
     void on_sendable(proton::sender &s) override {
-        std::string address = s.local_source().address();
+        std::string address = s.source().address();
 
         queues_.get(address).dispatch(&s);
     }
 
     void on_message(proton::delivery &d, proton::message &m) override {
-        std::string address = d.receiver().local_target().address();
+        std::string address = d.receiver().target().address();
         queues_.get(address).publish(m, d.receiver());
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index 6617a03..0c38ac6 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -25,12 +25,16 @@
 #include "proton/handler.hpp"
 #include "proton/connection.hpp"
 #include "proton/tracker.hpp"
+#include "proton/source_options.hpp"
 
 #include <iostream>
 #include <vector>
 
 #include "fake_cpp11.hpp"
 
+using proton::receiver_options;
+using proton::source_options;
+
 class client : public proton::handler {
   private:
     proton::url url;
@@ -43,16 +47,16 @@ class client : public proton::handler {
 
     void on_container_start(proton::container &c) override {
         sender = c.open_sender(url);
-        // Create a receiver with a dynamically chosen unique address.
-        // Note: the following signature is changing in Proton 0.13
-        receiver = sender.connection().open_receiver("", 
proton::receiver_options().dynamic_address(true));
+        // Create a receiver requesting a dynamically created queue
+        // for the message source.
+        receiver_options dynamic_addr = 
receiver_options().source(source_options().dynamic(true));
+        receiver = sender.connection().open_receiver("", dynamic_addr);
     }
 
     void send_request() {
         proton::message req;
         req.body(requests.front());
-        req.reply_to(receiver.remote_source().address());
-
+        req.reply_to(receiver.source().address());
         sender.send(req);
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/examples/cpp/engine/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/engine/client.cpp b/examples/cpp/engine/client.cpp
index 070133b..8e58a38 100644
--- a/examples/cpp/engine/client.cpp
+++ b/examples/cpp/engine/client.cpp
@@ -26,12 +26,16 @@
 #include "proton/handler.hpp"
 #include "proton/connection.hpp"
 #include "proton/tracker.hpp"
+#include "proton/source_options.hpp"
 
 #include <iostream>
 #include <vector>
 
 #include "../fake_cpp11.hpp"
 
+using proton::receiver_options;
+using proton::source_options;
+
 class client : public proton::handler {
   private:
     proton::url url;
@@ -44,14 +48,16 @@ class client : public proton::handler {
 
     void on_connection_open(proton::connection &c) override {
         sender = c.open_sender(url.path());
-        // Note: the following signature is changing in Proton 0.13
-        receiver = c.open_receiver("", 
proton::receiver_options().dynamic_address(true));
+        // Create a receiver requesting a dynamically created queue
+        // for the message source.
+        receiver_options dynamic_addr = 
receiver_options().source(source_options().dynamic(true));
+        receiver = c.open_receiver("", dynamic_addr);
     }
 
     void send_request() {
         proton::message req;
         req.body(requests.front());
-        req.reply_to(receiver.remote_source().address());
+        req.reply_to(receiver.source().address());
         sender.send(req);
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/examples/cpp/queue_browser.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/queue_browser.cpp b/examples/cpp/queue_browser.cpp
index d71a65c..dc76f9a 100644
--- a/examples/cpp/queue_browser.cpp
+++ b/examples/cpp/queue_browser.cpp
@@ -25,11 +25,15 @@
 #include "proton/handler.hpp"
 #include "proton/url.hpp"
 #include "proton/receiver_options.hpp"
+#include "proton/source_options.hpp"
+#include "proton/settings.hpp"
 
 #include <iostream>
 
 #include "fake_cpp11.hpp"
 
+using proton::source_options;
+
 class browser : public proton::handler {
   private:
     proton::url url;
@@ -39,8 +43,8 @@ class browser : public proton::handler {
 
     void on_container_start(proton::container &c) override {
         proton::connection conn = c.connect(url);
-        // Note: the following signature is changing in Proton 0.13
-        conn.open_receiver(url.path(), 
proton::receiver_options().browsing(true));
+        source_options browsing = 
source_options().distribution_mode(proton::COPY);
+        conn.open_receiver(url.path(), 
proton::receiver_options().source(browsing));
     }
 
     void on_message(proton::delivery &d, proton::message &m) override {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/examples/cpp/server_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/server_direct.cpp b/examples/cpp/server_direct.cpp
index a72d246..e092d5f 100644
--- a/examples/cpp/server_direct.cpp
+++ b/examples/cpp/server_direct.cpp
@@ -25,6 +25,7 @@
 #include "proton/container.hpp"
 #include "proton/handler.hpp"
 #include "proton/sender.hpp"
+#include "proton/source_options.hpp"
 #include "proton/tracker.hpp"
 #include "proton/url.hpp"
 
@@ -68,9 +69,10 @@ class server : public proton::handler {
     }
 
     void on_sender_open(proton::sender &sender) override {
-        if (sender.remote_source().dynamic()) {
-            sender.local_source().address(generate_address());
-            senders[sender.local_source().address()] = sender;
+        if (sender.source().dynamic()) {
+            std::string addr = generate_address();
+            
sender.open(proton::sender_options().source(proton::source_options().address(addr)));
+            senders[addr] = sender;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt 
b/proton-c/bindings/cpp/CMakeLists.txt
index f53c292..e1a826f 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -49,6 +49,7 @@ set(qpid-proton-cpp-source
   src/link.cpp
   src/message.cpp
   src/messaging_adapter.cpp
+  src/node_options.cpp
   src/object.cpp
   src/proton_bits.cpp
   src/proton_event.cpp
@@ -62,8 +63,10 @@ set(qpid-proton-cpp-source
   src/sender.cpp
   src/sender_options.cpp
   src/session.cpp
+  src/source.cpp
   src/ssl.cpp
   src/ssl_domain.cpp
+  src/target.cpp
   src/task.cpp
   src/terminus.cpp
   src/timestamp.cpp

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/link.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/link.hpp 
b/proton-c/bindings/cpp/include/proton/link.hpp
index d7386c4..515787c 100644
--- a/proton-c/bindings/cpp/include/proton/link.hpp
+++ b/proton-c/bindings/cpp/include/proton/link.hpp
@@ -25,7 +25,8 @@
 #include <proton/endpoint.hpp>
 #include <proton/export.hpp>
 #include <proton/message.hpp>
-#include <proton/terminus.hpp>
+#include <proton/source.hpp>
+#include <proton/target.hpp>
 #include <proton/object.hpp>
 #include <proton/sender_options.hpp>
 #include <proton/receiver_options.hpp>
@@ -115,18 +116,6 @@ PN_CPP_CLASS_EXTERN link : public object<pn_link_t> , 
public endpoint {
     PN_CPP_EXTERN int drained();
     /// @endcond
 
-    /// Local source of the link.
-    PN_CPP_EXTERN terminus local_source() const;
-
-    /// Local target of the link.
-    PN_CPP_EXTERN terminus local_target() const;
-
-    /// Remote source of the link.
-    PN_CPP_EXTERN terminus remote_source() const;
-
-    /// Remote target of the link.
-    PN_CPP_EXTERN terminus remote_target() const;
-
     /// Get the link name.
     PN_CPP_EXTERN std::string name() const;
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/receiver.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/receiver.hpp 
b/proton-c/bindings/cpp/include/proton/receiver.hpp
index 8123687..be47481 100644
--- a/proton-c/bindings/cpp/include/proton/receiver.hpp
+++ b/proton-c/bindings/cpp/include/proton/receiver.hpp
@@ -46,12 +46,19 @@ PN_CPP_CLASS_EXTERN receiver : public internal::link {
     /// handler::on_receiver_open.
     PN_CPP_EXTERN void open(const receiver_options &opts = receiver_options());
 
+    /// Get the source node.
+    PN_CPP_EXTERN class source source() const;
+
+    /// Get the target node.
+    PN_CPP_EXTERN class target target() const;
   /// @cond INTERNAL
   friend class internal::link;
   friend class delivery;
   friend class session;
   friend class messaging_adapter;
   friend class receiver_iterator;
+  friend class source;
+  friend class target;
   /// @endcond
 };
 
@@ -59,7 +66,7 @@ class receiver_iterator : public 
internal::iter_base<receiver, receiver_iterator
   public:
     ///@cond INTERNAL
     explicit receiver_iterator(receiver r = 0, pn_session_t* s = 0) :
-        iter_base<receiver, receiver_iterator>(r), session_(s) {}
+        internal::iter_base<receiver, receiver_iterator>(r), session_(s) {}
     ///@endcond
     /// Advance
     PN_CPP_EXTERN receiver_iterator operator++();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/receiver_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/receiver_options.hpp 
b/proton-c/bindings/cpp/include/proton/receiver_options.hpp
index e95147d..592e4ab 100644
--- a/proton-c/bindings/cpp/include/proton/receiver_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/receiver_options.hpp
@@ -36,6 +36,8 @@ namespace proton {
 
 class proton_handler;
 class receiver;
+class source_options;
+class target_options;
 
 /// Options for creating a receiver.
 ///
@@ -87,10 +89,6 @@ class receiver_options {
     PN_CPP_EXTERN receiver_options& delivery_mode(delivery_mode);
 
     /// @cond INTERNAL
-    /// XXX dynamic_address, browsing, selector, all to be moved to a new 
options mechanism
-    /// Request a dynamically generated node at the peer.
-    PN_CPP_EXTERN receiver_options& dynamic_address(bool);
-    PN_CPP_EXTERN receiver_options& browsing(bool);
     /// XXX need to discuss spec issues, jms versus amqp filters
     ///
     /// Set a selector on the receiver to str.  This sets a single
@@ -106,6 +104,12 @@ class receiver_options {
     /// Automatically settle messages (default value: true).
     PN_CPP_EXTERN receiver_options& auto_settle(bool);
 
+    /// Options for the source node of the receiver.
+    PN_CPP_EXTERN receiver_options& source(source_options &);
+
+    /// Options for the target node of the receiver.
+    PN_CPP_EXTERN receiver_options& target(target_options &);
+
     /// @cond INTERNAL
     /// XXX moving to ???
     /// Set automated flow control to pre-fetch this many messages

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/sender.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sender.hpp 
b/proton-c/bindings/cpp/include/proton/sender.hpp
index 0c7666a..87b9697 100644
--- a/proton-c/bindings/cpp/include/proton/sender.hpp
+++ b/proton-c/bindings/cpp/include/proton/sender.hpp
@@ -50,15 +50,23 @@ PN_CPP_CLASS_EXTERN sender : public internal::link
     /// handler::on_sender_open.
     PN_CPP_EXTERN void open(const sender_options &opts = sender_options());
 
-    /// Send a message on the link.
+    /// Send a message on the sender.
     PN_CPP_EXTERN tracker send(const message &m);
 
+    /// Get the source node.
+    PN_CPP_EXTERN class source source() const;
+
+    /// Get the target node.
+    PN_CPP_EXTERN class target target() const;
+
   /// @cond INTERNAL
   friend class internal::link;
   friend class tracker;
   friend class session;
   friend class messaging_adapter;
   friend class sender_iterator;
+  friend class source;
+  friend class target;
   /// @endcond
 };
 
@@ -66,7 +74,7 @@ class sender_iterator : public internal::iter_base<sender, 
sender_iterator> {
   public:
     ///@cond INTERNAL
     explicit sender_iterator(sender snd = 0, pn_session_t* s = 0) :
-        iter_base<sender, sender_iterator>(snd), session_(s) {}
+        internal::iter_base<sender, sender_iterator>(snd), session_(s) {}
     ///@endcond
     /// Advance
     PN_CPP_EXTERN sender_iterator operator++();

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/sender_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/sender_options.hpp 
b/proton-c/bindings/cpp/include/proton/sender_options.hpp
index 84084a4..d42880c 100644
--- a/proton-c/bindings/cpp/include/proton/sender_options.hpp
+++ b/proton-c/bindings/cpp/include/proton/sender_options.hpp
@@ -36,6 +36,8 @@ namespace proton {
 
 class proton_handler;
 class sender;
+class source_options;
+class target_options;
 
 /// Options for creating a sender.
 ///
@@ -88,6 +90,12 @@ class sender_options {
     /// Automatically settle messages (default value: true).
     PN_CPP_EXTERN sender_options& auto_settle(bool);
 
+    /// Options for the source node of the sender.
+    PN_CPP_EXTERN sender_options& source(source_options &);
+
+    /// Options for the receiver node of the receiver.
+    PN_CPP_EXTERN sender_options& target(target_options &);
+
 
     /// @cond INTERNAL
   private:

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/settings.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/settings.hpp 
b/proton-c/bindings/cpp/include/proton/settings.hpp
new file mode 100644
index 0000000..c655399
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/settings.hpp
@@ -0,0 +1,59 @@
+#ifndef PROTON_CPP_SETTINGS_H
+#define PROTON_CPP_SETTINGS_H
+
+/*
+ *
+ * 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 "proton/link.h"
+
+namespace proton {
+
+// Source/target settings
+
+/// Durability
+enum durability_mode {
+    NONE = PN_NONDURABLE,
+    CONFIGURATION = PN_CONFIGURATION,
+    UNSETTLED_STATE = PN_DELIVERIES
+};
+
+/// Expiry policy
+enum expiry_policy {
+    LINK_CLOSE = PN_EXPIRE_WITH_LINK,
+    SESSION_CLOSE = PN_EXPIRE_WITH_SESSION,
+    CONNECTION_CLOSE = PN_EXPIRE_WITH_CONNECTION,
+    NEVER = PN_EXPIRE_NEVER
+};
+
+
+// Source setting
+
+/// Distribution mode
+enum distribution_mode {
+    MODE_UNSPECIFIED = PN_DIST_MODE_UNSPECIFIED,
+    COPY = PN_DIST_MODE_COPY,
+    MOVE = PN_DIST_MODE_MOVE
+};
+
+
+}
+
+#endif // PROTON_CPP_SETTINGS_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/source.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/source.hpp 
b/proton-c/bindings/cpp/include/proton/source.hpp
new file mode 100644
index 0000000..4c95bbc
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/source.hpp
@@ -0,0 +1,59 @@
+#ifndef PROTON_CPP_SOURCE_H
+#define PROTON_CPP_SOURCE_H
+
+/*
+ *
+ * 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 "proton/export.hpp"
+#include "proton/object.hpp"
+#include "proton/value.hpp"
+#include "proton/terminus.hpp"
+
+#include <string>
+
+namespace proton {
+
+class sender;
+class receiver;
+
+///
+/// The source node is where messages originate.
+///
+/// @see proton::sender proton::receiver proton::target
+class source : public internal::terminus {
+  public:
+    source() : internal::terminus() {}
+    PN_CPP_EXTERN std::string address() const;
+    /// @cond INTERNAL
+  private:
+    source(pn_terminus_t* t);
+    source(const sender&);
+    source(const receiver&);
+  friend class sender;
+  friend class receiver;
+  friend class sender_options;
+  friend class receiver_options;
+    /// @endcond
+};
+
+}
+
+#endif // PROTON_CPP_SOURCE_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/source_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/source_options.hpp 
b/proton-c/bindings/cpp/include/proton/source_options.hpp
new file mode 100644
index 0000000..0dc945b
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/source_options.hpp
@@ -0,0 +1,95 @@
+#ifndef PROTON_CPP_SOURCE_OPTIONS_H
+#define PROTON_CPP_SOURCE_OPTIONS_H
+
+/*
+ *
+ * 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 "proton/config.hpp"
+#include "proton/export.hpp"
+#include "proton/pn_unique_ptr.hpp"
+#include "proton/types.hpp"
+#include "proton/delivery_mode.hpp"
+#include "proton/terminus.hpp"
+
+#include <vector>
+#include <string>
+
+namespace proton {
+
+class proton_handler;
+class source;
+
+/// Options for creating a source node for a sender or receiver.
+///
+/// Options can be "chained" (@see proton::connection_options).
+///
+/// Normal value semantics: copy or assign creates a separate copy of
+/// the options.
+class source_options {
+  public:
+
+    /// Create an empty set of options.
+    PN_CPP_EXTERN source_options();
+
+    /// Copy options.
+    PN_CPP_EXTERN source_options(const source_options&);
+
+    PN_CPP_EXTERN ~source_options();
+
+    /// Copy options.
+    PN_CPP_EXTERN source_options& operator=(const source_options&);
+
+    /// Set the address for the source.  Ignored if dynamic is true.
+    PN_CPP_EXTERN source_options& address(const std::string&);
+
+    /// Request a dynamically created node to be created by the remote peer.
+    /// Any specified source address is ignored.
+    PN_CPP_EXTERN source_options& dynamic(bool);
+
+    /// Control whether messsages are browsed or consumed.
+    PN_CPP_EXTERN source_options& distribution_mode(enum distribution_mode);
+
+    /// Control the persistence of source state.
+    PN_CPP_EXTERN source_options& durability_mode(enum durability_mode);
+
+    /// The expiry period after which the source is discarded.
+    PN_CPP_EXTERN source_options& timeout(duration);
+
+    /// Control when the clock for expiration begins.
+    PN_CPP_EXTERN source_options& expiry_policy(enum expiry_policy);
+
+    /// @cond INTERNAL
+  private:
+    void apply(source&) const;
+    PN_CPP_EXTERN void update(const source_options& other);
+
+    class impl;
+    internal::pn_unique_ptr<impl> impl_;
+
+    friend class source;
+    friend class sender_options;
+    friend class receiver_options;
+    /// @endcond
+};
+
+}
+
+#endif // PROTON_CPP_SOURCE_OPTIONS_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/target.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/target.hpp 
b/proton-c/bindings/cpp/include/proton/target.hpp
new file mode 100644
index 0000000..4eb77a4
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/target.hpp
@@ -0,0 +1,60 @@
+#ifndef PROTON_CPP_TARGET_H
+#define PROTON_CPP_TARGET_H
+
+/*
+ *
+ * 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 "proton/export.hpp"
+#include "proton/object.hpp"
+#include "proton/value.hpp"
+#include "proton/terminus.hpp"
+
+#include <string>
+
+namespace proton {
+
+class sender;
+class receiver;
+
+///
+/// The target is the destination node of a sent or received message.
+///
+/// @see proton::sender proton::receiver proton::target
+class target : public internal::terminus {
+  public:
+    target() : internal::terminus() {}
+    PN_CPP_EXTERN std::string address() const;
+    /// @cond INTERNAL
+  private:
+    target(pn_terminus_t* t);
+    target(const sender&);
+    target(const receiver&);
+  friend class sender;
+  friend class receiver;
+  friend class sender_options;
+  friend class receiver_options;
+    /// @endcond
+
+};
+
+}
+
+#endif // PROTON_CPP_TARGET_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/include/proton/target_options.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/target_options.hpp 
b/proton-c/bindings/cpp/include/proton/target_options.hpp
new file mode 100644
index 0000000..f23aca3
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/target_options.hpp
@@ -0,0 +1,93 @@
+#ifndef PROTON_CPP_TARGET_OPTIONS_H
+#define PROTON_CPP_TARGET_OPTIONS_H
+
+/*
+ *
+ * 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 "proton/config.hpp"
+#include "proton/export.hpp"
+#include "proton/pn_unique_ptr.hpp"
+#include "proton/types.hpp"
+#include "proton/delivery_mode.hpp"
+#include "proton/terminus.hpp"
+
+#include <vector>
+#include <string>
+
+namespace proton {
+
+class proton_handler;
+class target;
+
+/// Options for creating a target node for a sender or receiver.
+///
+/// Options can be "chained" (@see proton::connection_options).
+///
+/// Normal value semantics: copy or assign creates a separate copy of
+/// the options.
+class target_options {
+  public:
+
+    /// Create an empty set of options.
+    PN_CPP_EXTERN target_options();
+
+    /// Copy options.
+    PN_CPP_EXTERN target_options(const target_options&);
+
+    PN_CPP_EXTERN ~target_options();
+
+    /// Copy options.
+    PN_CPP_EXTERN target_options& operator=(const target_options&);
+
+    /// Set the address for the target.  Ignored if dynamic is true.
+    PN_CPP_EXTERN target_options& address(const std::string& addr);
+
+    /// Request a dynamically created node to be created by the peer.
+    /// Any specified target address is ignored.
+    PN_CPP_EXTERN target_options& dynamic(bool);
+
+    /// Control the persistence of target state.
+    PN_CPP_EXTERN target_options& durability_mode(enum durability_mode);
+
+    /// The expiry period after which the target is discarded.
+    PN_CPP_EXTERN target_options& timeout(duration);
+
+    /// Control when the clock for expiration begins.
+    PN_CPP_EXTERN target_options& expiry_policy(enum expiry_policy);
+
+
+    /// @cond INTERNAL
+  private:
+    void apply(target&) const;
+    PN_CPP_EXTERN void update(const target_options& other);
+
+    class impl;
+    internal::pn_unique_ptr<impl> impl_;
+
+    friend class target;
+    friend class sender_options;
+    friend class receiver_options;
+    /// @endcond
+};
+
+}
+
+#endif // PROTON_CPP_TARGET_OPTIONS_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/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 b0135a2..e3dd711 100644
--- a/proton-c/bindings/cpp/include/proton/terminus.hpp
+++ b/proton-c/bindings/cpp/include/proton/terminus.hpp
@@ -25,15 +25,21 @@
 #include "proton/export.hpp"
 #include "proton/object.hpp"
 #include "proton/value.hpp"
+#include "proton/settings.hpp"
 
 #include "proton/link.h"
 #include <string>
 
 namespace proton {
 
+class source;
+class target;
+class receiver_options;
+class source_options;
+class target_options;
+
+
 namespace internal {
-class link;
-}
 
 /// One end of a link, either a source or a target.
 ///
@@ -47,105 +53,60 @@ class terminus {
     /// @endcond
 
   public:
-    terminus() : object_(0) {}
-
-    /// Type of terminus
-    enum type {
-        TYPE_UNSPECIFIED = PN_UNSPECIFIED,
-        SOURCE = PN_SOURCE,
-        TARGET = PN_TARGET,
-        COORDINATOR = PN_COORDINATOR ///< Transaction coordinator
-    };
-
-    /// Durability
-    enum durability {
-        NONDURABLE = PN_NONDURABLE,
-        CONFIGURATION = PN_CONFIGURATION,
-        DELIVERIES = PN_DELIVERIES
-    };
-
-    /// Expiry policy
-    enum expiry_policy {
-        EXPIRE_WITH_LINK = PN_EXPIRE_WITH_LINK,
-        EXPIRE_WITH_SESSION = PN_EXPIRE_WITH_SESSION,
-        EXPIRE_WITH_CONNECTION = PN_EXPIRE_WITH_CONNECTION,
-        EXPIRE_NEVER = PN_EXPIRE_NEVER
-    };
-
-    /// Distribution mode
-    enum distribution_mode {
-        MODE_UNSPECIFIED = PN_DIST_MODE_UNSPECIFIED,
-        COPY = PN_DIST_MODE_COPY,
-        MOVE = PN_DIST_MODE_MOVE
-    };
-
-    /// Get the terminus type.
-    PN_CPP_EXTERN enum type type() const;
-
-    /// Set the terminus type.
-    PN_CPP_EXTERN void type(enum type);
-
-    /// Get the expiration policy.
+    terminus() : object_(0), parent_(0) {}
+
+    /// Control when the clock for expiration begins.
     PN_CPP_EXTERN enum expiry_policy expiry_policy() const;
 
-    /// Set the expiration policy.
-    PN_CPP_EXTERN void expiry_policy(enum expiry_policy);
-
-    /// @cond INTERNAL
-    /// XXX use duration
-    PN_CPP_EXTERN uint32_t timeout() const;
-    PN_CPP_EXTERN void timeout(uint32_t seconds);
-    /// @endcond
+    /// The period after which the source is discarded on expiry. The
+    /// duration is rounded to the nearest second.
+    PN_CPP_EXTERN duration timeout() const;
 
     /// Get the distribution mode.
     PN_CPP_EXTERN enum distribution_mode distribution_mode() const;
 
-    /// Set the distribution mode.
-    PN_CPP_EXTERN void distribution_mode(enum distribution_mode);
-
     /// Get the durability flag.
-    PN_CPP_EXTERN enum durability durability();
+    PN_CPP_EXTERN enum durability_mode durability_mode();
 
-    /// Set the durability flag.
-    PN_CPP_EXTERN void durability(enum durability);
-
-    /// Get the source or target address.
+    /// Get the source or target node's address.
     PN_CPP_EXTERN std::string address() const;
 
-    /// Set the source or target address.
-    PN_CPP_EXTERN void address(const std::string &);
-
     /// True if the remote node is created dynamically.
     PN_CPP_EXTERN bool dynamic() const;
 
-    /// Enable or disable dynamic creation of the remote node.
-    PN_CPP_EXTERN void dynamic(bool);
-
-    /// Obtain a reference to the AMQP dynamic node properties for the
-    /// terminus.  See also lifetime_policy.
-    PN_CPP_EXTERN value& node_properties();
-
     /// Obtain a reference to the AMQP dynamic node properties for the
     /// terminus.  See also lifetime_policy.
     PN_CPP_EXTERN const value& node_properties() const;
 
     /// Obtain a reference to the AMQP filter set for the terminus.
     /// See also selector.
-    PN_CPP_EXTERN value& filter();
-
-    /// Obtain a reference to the AMQP filter set for the terminus.
-    /// See also selector.
     PN_CPP_EXTERN const value& filter() const;
 
     /// @cond INTERNAL
   private:
+    void address(const std::string &);
+    void expiry_policy(enum expiry_policy);
+    void timeout(duration);
+    void distribution_mode(enum distribution_mode);
+    void durability_mode(enum durability_mode);
+    void dynamic(bool);
+    value& node_properties();
+    value& filter();
+
     pn_terminus_t* object_;
     value properties_, filter_;
-
-    friend class internal::link;
+    pn_link_t* parent_;
+
+    friend class link;
+    friend class noderef;
+    friend class proton::source;
+    friend class proton::target;
+    friend class proton::receiver_options;
+    friend class proton::source_options;
+    friend class proton::target_options;
     /// @endcond
 };
 
-}
+}}
 
 #endif // PROTON_CPP_TERMINUS_H

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/link.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/link.cpp 
b/proton-c/bindings/cpp/src/link.cpp
index a81a8ed..d12bd5a 100644
--- a/proton-c/bindings/cpp/src/link.cpp
+++ b/proton-c/bindings/cpp/src/link.cpp
@@ -69,11 +69,6 @@ int link::queued() { return pn_link_queued(pn_object()); }
 int link::unsettled() { return pn_link_unsettled(pn_object()); }
 int link::drained() { return pn_link_drained(pn_object()); }
 
-terminus link::local_source() const { return pn_link_source(pn_object()); }
-terminus link::local_target() const { return pn_link_target(pn_object()); }
-terminus link::remote_source() const { return 
pn_link_remote_source(pn_object()); }
-terminus link::remote_target() const { return 
pn_link_remote_target(pn_object()); }
-
 std::string link::name() const { return 
std::string(pn_link_name(pn_object()));}
 
 container& link::container() const {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/node_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/node_options.cpp 
b/proton-c/bindings/cpp/src/node_options.cpp
new file mode 100644
index 0000000..45aa154
--- /dev/null
+++ b/proton-c/bindings/cpp/src/node_options.cpp
@@ -0,0 +1,177 @@
+/*
+ *
+ * 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 "proton/source_options.hpp"
+#include "proton/source.hpp"
+#include "proton/target_options.hpp"
+#include "proton/target.hpp"
+
+namespace proton {
+
+template <class T> struct option {
+    T value;
+    bool set;
+
+    option() : value(), set(false) {}
+    option& operator=(const T& x) { value = x;  set = true; return *this; }
+    void update(const option<T>& x) { if (x.set) *this = x.value; }
+};
+
+namespace internal {
+class noderef {
+    // friend class to handle private access on terminus.  TODO: change to 
newer single friend mechanism.
+  public:
+    static void address(terminus &t, const std::string &s) { t.address(s); }
+    static void dynamic(terminus &t, bool b) { t.dynamic(b); }
+    static void durability_mode(terminus &t, enum durability_mode m) { 
t.durability_mode(m); }
+    static void expiry_policy(terminus &t, enum expiry_policy p) { 
t.expiry_policy(p); }
+    static void timeout(terminus &t, duration d) { t.timeout(d); }
+};
+}
+
+namespace {
+
+// Options common to sources and targets
+
+using internal::noderef;
+
+void node_address(internal::terminus &t, option<std::string> &addr, 
option<bool> &dynamic) {
+    if (dynamic.set && dynamic.value) {
+        noderef::dynamic(t, true);
+        // Ignore any addr value for dynamic.
+        return;
+    }
+    if (addr.set) {
+        noderef::address(t, addr.value);
+    }
+}
+
+void node_durability(internal::terminus &t, option<enum durability_mode> 
&mode) {
+    if (mode.set) noderef::durability_mode(t, mode.value);
+}
+
+void node_expiry(internal::terminus &t, option<enum expiry_policy> &policy, 
option<duration> &d) {
+    if (policy.set) noderef::expiry_policy(t, policy.value);
+    if (d.set) noderef::timeout(t, d.value);
+}
+
+}
+
+
+class source_options::impl {
+  public:
+    option<std::string> address;
+    option<bool> dynamic;
+    option<enum durability_mode> durability_mode;
+    option<duration> timeout;
+    option<enum expiry_policy> expiry_policy;
+    option<enum distribution_mode> distribution_mode;
+
+    void apply(source& s) {
+        node_address(s, address, dynamic);
+        node_durability(s, durability_mode);
+        node_expiry(s, expiry_policy, timeout);
+        if (distribution_mode.set) 
s.distribution_mode(distribution_mode.value);
+    }
+
+    void update(const impl& x) {
+        address.update(x.address);
+        dynamic.update(x.dynamic);
+        durability_mode.update(x.durability_mode);
+        timeout.update(x.timeout);
+        expiry_policy.update(x.expiry_policy);
+        distribution_mode.update(x.distribution_mode);
+    }
+
+};
+
+source_options::source_options() : impl_(new impl()) {}
+source_options::source_options(const source_options& x) : impl_(new impl()) {
+    *this = x;
+}
+source_options::~source_options() {}
+
+source_options& source_options::operator=(const source_options& x) {
+    *impl_ = *x.impl_;
+    return *this;
+}
+
+void source_options::update(const source_options& x) { 
impl_->update(*x.impl_); }
+
+source_options& source_options::address(const std::string &addr) { 
impl_->address = addr; return *this; }
+source_options& source_options::dynamic(bool b) { impl_->dynamic = b; return 
*this; }
+source_options& source_options::durability_mode(enum durability_mode m) { 
impl_->durability_mode = m; return *this; }
+source_options& source_options::timeout(duration d) { impl_->timeout = d; 
return *this; }
+source_options& source_options::expiry_policy(enum expiry_policy m) { 
impl_->expiry_policy = m; return *this; }
+source_options& source_options::distribution_mode(enum distribution_mode m) { 
impl_->distribution_mode = m; return *this; }
+
+void source_options::apply(source& s) const { impl_->apply(s); }
+
+// TARGET
+
+class target_options::impl {
+  public:
+    option<std::string> address;
+    option<bool> dynamic;
+    option<enum durability_mode> durability_mode;
+    option<duration> timeout;
+    option<enum expiry_policy> expiry_policy;
+
+    void apply(target& t) {
+        node_address(t, address, dynamic);
+        node_durability(t, durability_mode);
+        node_expiry(t, expiry_policy, timeout);
+    }
+
+    void update(const impl& x) {
+        address.update(x.address);
+        dynamic.update(x.dynamic);
+        durability_mode.update(x.durability_mode);
+        timeout.update(x.timeout);
+        expiry_policy.update(x.expiry_policy);
+    }
+
+};
+
+target_options::target_options() : impl_(new impl()) {}
+target_options::target_options(const target_options& x) : impl_(new impl()) {
+    *this = x;
+}
+target_options::~target_options() {}
+
+target_options& target_options::operator=(const target_options& x) {
+    *impl_ = *x.impl_;
+    return *this;
+}
+
+void target_options::update(const target_options& x) { 
impl_->update(*x.impl_); }
+
+target_options& target_options::address(const std::string &addr) { 
impl_->address = addr; return *this; }
+target_options& target_options::dynamic(bool b) { impl_->dynamic = b; return 
*this; }
+target_options& target_options::durability_mode(enum durability_mode m) { 
impl_->durability_mode = m; return *this; }
+target_options& target_options::timeout(duration d) { impl_->timeout = d; 
return *this; }
+target_options& target_options::expiry_policy(enum expiry_policy m) { 
impl_->expiry_policy = m; return *this; }
+
+void target_options::apply(target& s) const { impl_->apply(s); }
+
+
+
+} // namespace proton

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/receiver.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/receiver.cpp 
b/proton-c/bindings/cpp/src/receiver.cpp
index 2ebb9e5..2e7643c 100644
--- a/proton-c/bindings/cpp/src/receiver.cpp
+++ b/proton-c/bindings/cpp/src/receiver.cpp
@@ -34,6 +34,14 @@ void receiver::open(const receiver_options &opts) {
     attach();
 }
 
+class source receiver::source() const {
+    return proton::source(*this);
+}
+
+class target receiver::target() const {
+    return proton::target(*this);
+}
+
 
 receiver_iterator receiver_iterator::operator++() {
     if (!!obj_) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/receiver_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/receiver_options.cpp 
b/proton-c/bindings/cpp/src/receiver_options.cpp
index 6b06dc9..5abb5f6 100644
--- a/proton-c/bindings/cpp/src/receiver_options.cpp
+++ b/proton-c/bindings/cpp/src/receiver_options.cpp
@@ -23,11 +23,15 @@
 #include "proton/receiver.hpp"
 #include "proton/receiver_options.hpp"
 #include "proton/handler.hpp"
+#include "proton/settings.hpp"
+#include "proton/source_options.hpp"
+#include "proton/target_options.hpp"
 
 #include "msg.hpp"
 #include "messaging_adapter.hpp"
 #include "contexts.hpp"
 
+#include "proton/link.h"
 
 namespace proton {
 
@@ -48,7 +52,9 @@ class receiver_options::impl {
     option<bool> auto_settle;
     option<int> credit_window;
     option<bool> dynamic_address;
-    option<enum terminus::distribution_mode> distribution_mode;
+    option<source_options> source;
+    option<target_options> target;
+
 
     void apply(receiver& r) {
         if (r.uninitialized()) {
@@ -71,15 +77,20 @@ class receiver_options::impl {
                 else
                     r.detach_handler();
             }
-            if (dynamic_address.set) {
-                terminus t = r.local_source();
-                t.dynamic(dynamic_address.value);
-            }
 
             if (auto_settle.set) r.context().auto_settle = auto_settle.value;
             if (auto_accept.set) r.context().auto_accept = auto_accept.value;
             if (credit_window.set) r.context().credit_window = 
credit_window.value;
-            if (distribution_mode.set) 
r.local_source().distribution_mode(distribution_mode.value);
+
+            internal::terminus local_src = pn_link_source(r.pn_object());
+            if (source.set) {
+                proton::source local_s(pn_link_source(r.pn_object()));
+                source.value.apply(local_s);
+            }
+            if (target.set) {
+                proton::target local_t(pn_link_target(r.pn_object()));
+                target.value.apply(local_t);
+            }
         }
     }
 
@@ -90,7 +101,8 @@ class receiver_options::impl {
         auto_settle.update(x.auto_settle);
         credit_window.update(x.credit_window);
         dynamic_address.update(x.dynamic_address);
-        distribution_mode.update(x.distribution_mode);
+        source.update(x.source);
+        target.update(x.target);
     }
 
 };
@@ -113,8 +125,8 @@ receiver_options& receiver_options::delivery_mode(enum 
delivery_mode m) {impl_->
 receiver_options& receiver_options::auto_accept(bool b) {impl_->auto_accept = 
b; return *this; }
 receiver_options& receiver_options::auto_settle(bool b) {impl_->auto_settle = 
b; return *this; }
 receiver_options& receiver_options::credit_window(int w) {impl_->credit_window 
= w; return *this; }
-receiver_options& receiver_options::dynamic_address(bool b) 
{impl_->dynamic_address = b; return *this; }
-receiver_options& receiver_options::browsing(bool b) { 
impl_->distribution_mode = (b ? terminus::COPY : terminus::MOVE); return *this; 
}
+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; }
 
 void receiver_options::apply(receiver& r) const { impl_->apply(r); }
 proton_handler* receiver_options::handler() const { return 
impl_->handler.value; }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/sender.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/sender.cpp 
b/proton-c/bindings/cpp/src/sender.cpp
index 6e55f8f..7ad88cd 100644
--- a/proton-c/bindings/cpp/src/sender.cpp
+++ b/proton-c/bindings/cpp/src/sender.cpp
@@ -34,6 +34,14 @@ void sender::open(const sender_options &opts) {
     attach();
 }
 
+class source sender::source() const {
+    return proton::source(*this);
+}
+
+class target sender::target() const {
+    return proton::target(*this);
+}
+
 namespace {
 // TODO: revisit if thread safety required
 uint64_t tag_counter = 0;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/sender_options.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/sender_options.cpp 
b/proton-c/bindings/cpp/src/sender_options.cpp
index 59b5947..a759d47 100644
--- a/proton-c/bindings/cpp/src/sender_options.cpp
+++ b/proton-c/bindings/cpp/src/sender_options.cpp
@@ -23,6 +23,8 @@
 #include "proton/sender.hpp"
 #include "proton/sender_options.hpp"
 #include "proton/handler.hpp"
+#include "proton/source_options.hpp"
+#include "proton/target_options.hpp"
 
 #include "msg.hpp"
 #include "messaging_adapter.hpp"
@@ -45,6 +47,8 @@ class sender_options::impl {
     option<proton_handler*> handler;
     option<enum delivery_mode> delivery_mode;
     option<bool> auto_settle;
+    option<source_options> source;
+    option<target_options> target;
 
     void apply(sender& s) {
         if (s.uninitialized()) {
@@ -68,6 +72,14 @@ class sender_options::impl {
                     s.detach_handler();
             }
             if (auto_settle.set) s.context().auto_settle = auto_settle.value;
+            if (source.set) {
+                proton::source local_src(pn_link_source(s.pn_object()));
+                source.value.apply(local_src);
+            }
+            if (target.set) {
+                proton::target local_src(pn_link_target(s.pn_object()));
+                target.value.apply(local_src);
+            }
         }
     }
 
@@ -75,6 +87,8 @@ class sender_options::impl {
         handler.update(x.handler);
         delivery_mode.update(x.delivery_mode);
         auto_settle.update(x.auto_settle);
+        source.update(x.source);
+        target.update(x.target);
     }
 
 };
@@ -95,6 +109,8 @@ void sender_options::update(const sender_options& x) { 
impl_->update(*x.impl_);
 sender_options& sender_options::handler(class handler *h) { impl_->handler = 
h->messaging_adapter_.get(); return *this; }
 sender_options& sender_options::delivery_mode(enum delivery_mode m) 
{impl_->delivery_mode = m; return *this; }
 sender_options& sender_options::auto_settle(bool b) {impl_->auto_settle = b; 
return *this; }
+sender_options& sender_options::source(source_options &s) {impl_->source = s; 
return *this; }
+sender_options& sender_options::target(target_options &s) {impl_->target = s; 
return *this; }
 
 void sender_options::apply(sender& s) const { impl_->apply(s); }
 proton_handler* sender_options::handler() const { return impl_->handler.value; 
}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/session.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/session.cpp 
b/proton-c/bindings/cpp/src/session.cpp
index d78d60c..6e34ec6 100644
--- a/proton-c/bindings/cpp/src/session.cpp
+++ b/proton-c/bindings/cpp/src/session.cpp
@@ -56,16 +56,18 @@ std::string next_link_name(const connection& c) {
 }
 
 sender session::open_sender(const std::string &addr, const sender_options &so) 
{
-    sender snd = pn_sender(pn_object(), next_link_name(connection()).c_str());
-    snd.local_target().address(addr);
+    pn_link_t *lnk = pn_sender(pn_object(), 
next_link_name(connection()).c_str());
+    pn_terminus_set_address(pn_link_target(lnk), addr.c_str());
+    sender snd(lnk);
     snd.open(so);
     return snd;
 }
 
 receiver session::open_receiver(const std::string &addr, const 
receiver_options &ro)
 {
-    receiver rcv = pn_receiver(pn_object(), 
next_link_name(connection()).c_str());
-    rcv.local_source().address(addr);
+    pn_link_t *lnk = pn_receiver(pn_object(), 
next_link_name(connection()).c_str());
+    pn_terminus_set_address(pn_link_source(lnk), addr.c_str());
+    receiver rcv(lnk);
     rcv.open(ro);
     return rcv;
 }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/source.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/source.cpp 
b/proton-c/bindings/cpp/src/source.cpp
new file mode 100644
index 0000000..f840f63
--- /dev/null
+++ b/proton-c/bindings/cpp/src/source.cpp
@@ -0,0 +1,43 @@
+/*
+ *
+ * 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 "proton/source.hpp"
+#include "proton/sender.hpp"
+#include "proton/receiver.hpp"
+
+namespace proton {
+
+// Set parent_ non-null when the local terminus is authoritative and may need 
to be looked up.
+source::source(pn_terminus_t *t) : terminus(t) {}
+
+source::source(const sender& snd) : 
terminus(pn_link_remote_source(snd.pn_object())) { parent_ = snd.pn_object(); }
+
+source::source(const receiver& rcv) : 
terminus(pn_link_remote_source(rcv.pn_object())) {}
+
+std::string source::address() const {
+    pn_terminus_t *authoritative = object_;
+    if (parent_ && pn_terminus_is_dynamic(object_))
+        authoritative = pn_link_source(parent_);
+    return std::string(pn_terminus_get_address(authoritative));
+}
+
+
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/proton-c/bindings/cpp/src/target.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/target.cpp 
b/proton-c/bindings/cpp/src/target.cpp
new file mode 100644
index 0000000..db0126e
--- /dev/null
+++ b/proton-c/bindings/cpp/src/target.cpp
@@ -0,0 +1,40 @@
+/*
+ *
+ * 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 "proton/target.hpp"
+#include "proton/sender.hpp"
+#include "proton/receiver.hpp"
+
+namespace proton {
+
+// Set parent_ non-null when the local terminus is authoritative and may need 
to be looked up.
+target::target(pn_terminus_t *t) : terminus(t) {}
+target::target(const sender& snd) : 
terminus(pn_link_remote_target(snd.pn_object())) {}
+target::target(const receiver& rcv) : 
terminus(pn_link_remote_target(rcv.pn_object())) { parent_ = rcv.pn_object(); }
+
+std::string target::address() const {
+    pn_terminus_t *authoritative = object_;
+    if (parent_ && pn_terminus_is_dynamic(object_))
+        authoritative = pn_link_target(parent_);
+    return std::string(pn_terminus_get_address(authoritative));
+}
+
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a40b77be/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 f705d3a..582bfcd 100644
--- a/proton-c/bindings/cpp/src/terminus.cpp
+++ b/proton-c/bindings/cpp/src/terminus.cpp
@@ -22,21 +22,16 @@
 #include "proton/link.hpp"
 #include "proton/link.h"
 
+#include <limits>
+
 namespace proton {
+namespace internal {
 
 terminus::terminus(pn_terminus_t* t) :
-    object_(t), properties_(pn_terminus_properties(t)), 
filter_(pn_terminus_filter(t))
+    object_(t), properties_(pn_terminus_properties(t)), 
filter_(pn_terminus_filter(t)), parent_(0)
 {}
 
-enum terminus::type terminus::type() const {
-    return (enum type)pn_terminus_get_type(object_);
-}
-
-void terminus::type(enum type type0) {
-    pn_terminus_set_type(object_, pn_terminus_type_t(type0));
-}
-
-enum terminus::expiry_policy terminus::expiry_policy() const {
+enum expiry_policy terminus::expiry_policy() const {
     return (enum expiry_policy)pn_terminus_get_expiry_policy(object_);
 }
 
@@ -44,15 +39,27 @@ void terminus::expiry_policy(enum expiry_policy policy) {
     pn_terminus_set_expiry_policy(object_, pn_expiry_policy_t(policy));
 }
 
-uint32_t terminus::timeout() const {
-    return pn_terminus_get_timeout(object_);
+duration terminus::timeout() const {
+    return duration::SECOND * pn_terminus_get_timeout(object_);
 }
 
-void terminus::timeout(uint32_t seconds) {
+void terminus::timeout(duration d) {
+    uint32_t seconds = 0;
+    if (d == duration::FOREVER)
+        seconds = std::numeric_limits<uint32_t>::max();
+    else if (d != duration::IMMEDIATE) {
+        uint64_t x = d.milliseconds();
+        if ((std::numeric_limits<uint64_t>::max() - x) <= 500)
+            seconds = std::numeric_limits<uint32_t>::max();
+        else {
+            x = (x + 500) / 1000;
+            seconds = x < std::numeric_limits<uint32_t>::max() ? x : 
std::numeric_limits<uint32_t>::max();
+        }
+    }
     pn_terminus_set_timeout(object_, seconds);
 }
 
-enum terminus::distribution_mode terminus::distribution_mode() const {
+enum distribution_mode terminus::distribution_mode() const {
     return (enum distribution_mode)pn_terminus_get_distribution_mode(object_);
 }
 
@@ -60,11 +67,11 @@ void terminus::distribution_mode(enum distribution_mode 
mode) {
     pn_terminus_set_distribution_mode(object_, pn_distribution_mode_t(mode));
 }
 
-enum terminus::durability terminus::durability() {
-    return (enum durability) pn_terminus_get_durability(object_);
+enum durability_mode terminus::durability_mode() {
+    return (enum durability_mode) pn_terminus_get_durability(object_);
 }
 
-void terminus::durability(enum durability d) {
+void terminus::durability_mode(enum durability_mode d) {
     pn_terminus_set_durability(object_, (pn_durability_t) d);
 }
 
@@ -92,4 +99,5 @@ const value& terminus::filter() const { return filter_; }
 value& terminus::node_properties() { return properties_; }
 const value& terminus::node_properties() const { return properties_; }
 
-}
+
+}}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to