Merge "Update Java API doc links to reflect fluorine"
[docs.git] / docs / developer-guide / controller.rst
index 6d656aac3a698309078bc5a057ac46d3f865ff11..fd3d02900d1b3770a6ce0b6f22755b6afc63a235 100644 (file)
@@ -1,3 +1,5 @@
+.. _controller-dev-guide:
+
 Controller
 ==========
 
@@ -26,12 +28,12 @@ The OpenDaylight Controller relies on the following technologies:
 The OpenDaylight Controller provides following model-driven subsystems
 as a foundation for Java applications:
 
--  **`Config Subsystem <#_config_subsystem>`__** - an activation,
+-  :ref:`config_subsystem` - an activation,
    dependency-injection and configuration framework, which allows
    two-phase commits of configuration and dependency-injection, and
    allows for run-time rewiring.
 
--  **`MD-SAL <#_md_sal_overview>`__** - messaging and data storage
+-  :ref:`MD-SAL <mdsal_dev_guide>` - messaging and data storage
    functionality for data, notifications and RPCs modeled by application
    developers. MD-SAL uses YANG as the modeling for both interface and
    data definitions, and provides a messaging and data-centric runtime
@@ -52,6 +54,8 @@ data using following model-driven protocols:
    manipulate YANG modeled data and invoke YANG modeled RPCs, using XML
    or JSON as payload format.
 
+.. _mdsal_dev_guide:
+
 MD-SAL Overview
 ---------------
 
@@ -181,8 +185,8 @@ MD-SAL **Data Broker** provides transactional access to conceptual
     this is state of controller, applications and also external systems
     (network devices).
 
-**Transactions** provide **`stable and isolated
-view <#_transaction_isolation>`__** from other currently running
+**Transactions** provide :ref:`stable and isolated
+view <transaction_isolation>` from other currently running
 transactions. The state of running transaction and underlying data tree
 is not affected by other concurrently running transactions.
 
@@ -233,8 +237,8 @@ for the conceptual data trees.
    using ``put``, ``merge`` and/or ``delete``.
 
 3. application finishes transaction using
-   ```submit()`` <#_submitting_transaction>`__, which seals transaction
-   and submits it to be processed.
+   ``submit()``, which :ref:`seals transaction
+   and submits <submitting_transaction>` it to be processed.
 
 4. application observes the result of the transaction commit using
    either blocking or asynchronous calls.
@@ -245,12 +249,12 @@ it’s state and underlying data tree are not affected by other
 concurrently running transactions.
 
 Write transactions are **isolated** from other concurrent write
-transactions. All **`writes are local <#_transaction_local_state>`__**
+transactions. All :ref:`writes are local <transaction_local_state>`
 to the transaction and represents only a **proposal of state change**
 for data tree and **are not visible** to any other concurrently running
 transactions (including read-only transactions).
 
-The transaction **`commit may fail <#_commit_failure_scenarios>`__** due
+The transaction :ref:`commit may fail <commit_failure_scenarios>` due
 to failing verification of data or concurrent transaction modifying and
 affected data in an incompatible way.
 
@@ -286,6 +290,8 @@ delete
 
     Removes a whole subtree from a specified path.
 
+.. _submitting_transaction:
+
 Submitting transaction
 ^^^^^^^^^^^^^^^^^^^^^^
 
@@ -311,12 +317,12 @@ Application may listen on commit state asynchronously using
 
 .. code:: java
 
-    Futures.addCallback( writeTx.submit(), new FutureCallback<Void>() { 
-            public void onSuccess( Void result ) { 
+    Futures.addCallback( writeTx.submit(), new FutureCallback<Void>() {
+            public void onSuccess( Void result ) {
                 LOG.debug("Transaction committed successfully.");
             }
 
-            public void onFailure( Throwable t ) { 
+            public void onFailure( Throwable t ) {
                 LOG.error("Commit failed.",e);
             }
         });
@@ -337,8 +343,8 @@ If application need to block till commit is finished it may use
 .. code:: java
 
     try {
-        writeTx.submit().checkedGet(); 
-    } catch (TransactionCommitFailedException e) { 
+        writeTx.submit().checkedGet();
+    } catch (TransactionCommitFailedException e) {
         LOG.error("Commit failed.",e);
     }
 
@@ -348,6 +354,8 @@ If application need to block till commit is finished it may use
 
 -  Catches ``TransactionCommitFailedException`` and logs it.
 
+.. _transaction_local_state:
+
 Transaction local state
 ^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -362,13 +370,13 @@ Let assume initial state of data tree for ``PATH`` is ``A``.
 
 .. code:: java
 
-    ReadWriteTransaction rwTx = broker.newReadWriteTransaction(); 
+    ReadWriteTransaction rwTx = broker.newReadWriteTransaction();
 
-    rwRx.read(OPERATIONAL,PATH).get(); 
-    rwRx.put(OPERATIONAL,PATH,B); 
-    rwRx.read(OPERATIONAL,PATH).get(); 
-    rwRx.put(OPERATIONAL,PATH,C); 
-    rwRx.read(OPERATIONAL,PATH).get(); 
+    rwRx.read(OPERATIONAL,PATH).get();
+    rwRx.put(OPERATIONAL,PATH,B);
+    rwRx.read(OPERATIONAL,PATH).get();
+    rwRx.put(OPERATIONAL,PATH,C);
+    rwRx.read(OPERATIONAL,PATH).get();
 
 -  Allocates new ``ReadWriteTransaction``.
 
@@ -384,6 +392,8 @@ Let assume initial state of data tree for ``PATH`` is ``A``.
 -  Read will return value ``C`` for ``PATH``, since previous write
    occurred in same transaction.
 
+.. _transaction_isolation:
+
 Transaction isolation
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -395,16 +405,16 @@ Lets assume initial state of data tree for ``PATH`` is ``A``.
 
 .. code:: java
 
-    ReadOnlyTransaction txRead = broker.newReadOnlyTransaction(); 
-    ReadWriteTransaction txWrite = broker.newReadWriteTransaction(); 
+    ReadOnlyTransaction txRead = broker.newReadOnlyTransaction();
+    ReadWriteTransaction txWrite = broker.newReadWriteTransaction();
 
-    txRead.read(OPERATIONAL,PATH).get(); 
-    txWrite.put(OPERATIONAL,PATH,B); 
-    txWrite.read(OPERATIONAL,PATH).get(); 
-    txWrite.submit().get(); 
-    txRead.read(OPERATIONAL,PATH).get(); 
-    txAfterCommit = broker.newReadOnlyTransaction(); 
-    txAfterCommit.read(OPERATIONAL,PATH).get(); 
+    txRead.read(OPERATIONAL,PATH).get();
+    txWrite.put(OPERATIONAL,PATH,B);
+    txWrite.read(OPERATIONAL,PATH).get();
+    txWrite.submit().get();
+    txRead.read(OPERATIONAL,PATH).get();
+    txAfterCommit = broker.newReadOnlyTransaction();
+    txAfterCommit.read(OPERATIONAL,PATH).get();
 
 -  Allocates read only transaction, which is based on data tree which
    contains value ``A`` for ``PATH``.
@@ -442,6 +452,8 @@ Lets assume initial state of data tree for ``PATH`` is ``A``.
     ``Futures#addCallback(ListenableFuture, FutureCallback)`` to listen
     asynchronously for result.
 
+.. _commit_failure_scenarios:
+
 Commit failure scenarios
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -455,7 +467,7 @@ Optimistic Lock Failure
     It is the responsibility of the caller to create a new transaction
     and submit the same modification again in order to update data tree.
 
-        **Warning**
+    .. warning::
 
         ``OptimisticLockFailedException`` usually exposes **multiple
         writers** to the same data subtree, which may conflict on same
@@ -486,11 +498,11 @@ same initial state of data tree and proposes conflicting modifications.
     WriteTransaction txA = broker.newWriteTransaction();
     WriteTransaction txB = broker.newWriteTransaction();
 
-    txA.put(CONFIGURATION, PATH, A);    
-    txB.put(CONFIGURATION, PATH, B);     
+    txA.put(CONFIGURATION, PATH, A);
+    txB.put(CONFIGURATION, PATH, B);
 
-    CheckedFuture<?,?> futureA = txA.submit(); 
-    CheckedFuture<?,?> futureB = txB.submit(); 
+    CheckedFuture<?,?> futureA = txA.submit();
+    CheckedFuture<?,?> futureB = txB.submit();
 
 -  Updates ``PATH`` to value ``A`` using ``txA``
 
@@ -708,7 +720,7 @@ be routed.
 Declaring a routing context type
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-.. code:: yang
+.. code::
 
     identity node-context {
         description "Identity used to mark node context";
@@ -725,7 +737,7 @@ In order to define possible values of **context instances** for routed
 RPCs, we need to model that set accordingly using ``context-instance``
 extension from the ``yang-ext`` model.
 
-.. code:: yang
+.. code::
 
     import yang-ext { prefix ext; }
 
@@ -770,7 +782,7 @@ reference**.
 This is achieved using YANG extension ``context-reference`` from
 ``yang-ext`` model on leaf, which will be used for RPC routing.
 
-.. code:: yang
+.. code::
 
     rpc example-routed-rpc  {
         input {
@@ -841,11 +853,22 @@ Line 112: We register salFlowService1 as implementation for nodeOne.
 The salFlowService1 will be executed only for RPCs which contains
 Instance Identifier for foo:node:1.
 
+RPCs and cluster
+^^^^^^^^^^^^^^^^
+
+In case there is is only a single provider of an RPC in the cluster
+the RPC registration is propagated to other nodes via Gossip protocol
+and the RPC calls from other nodes are correctly routed to the
+provider. Since the registrations are not expected to change rapidly
+there is a latency of about 1 second until the registration is reflected
+on the remote nodes.
+
+
 OpenDaylight Controller MD-SAL: RESTCONF
 ----------------------------------------
 
-RESCONF operations overview
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+RESTCONF operations overview
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 | RESTCONF allows access to datastores in the controller.
 | There are two datastores:
@@ -1386,7 +1409,7 @@ provide three parameters to this RPC:
    -  SUBTREE: changes anywhere in the subtree starting at the node will
       be reported
 
-The RPC to create the stream can be invoked via RESCONF like this:
+The RPC to create the stream can be invoked via RESTCONF like this:
 
 -  URI:
    http://{odlAddress}:{odlPort}/restconf/operations/sal-remote:create-data-change-event-subscription
@@ -1413,7 +1436,7 @@ The response should look something like this:
 
     {
         "output": {
-            "stream-name": "toaster:toaster/toaster:toasterStatus/datastore=CONFIGURATION/scope=SUBTREE"
+            "stream-name": "data-change-event-subscription/toaster:toaster/toaster:toasterStatus/datastore=CONFIGURATION/scope=SUBTREE"
         }
     }
 
@@ -1436,10 +1459,25 @@ response from *create-data-change-event-subscription* RPC from the
 previous step.
 
 -  URI:
-   http://{odlAddress}:{odlPort}/restconf/streams/stream/toaster:toaster/datastore=CONFIGURATION/scope=SUBTREE
+   http://{odlAddress}:{odlPort}/restconf/streams/stream/data-change-event-subscription/toaster:toaster/datastore=CONFIGURATION/scope=SUBTREE
 
 -  OPERATION: GET
 
+The subscription call may be modified with the following query parameters defined in the RESTCONF RFC:
+
+-  `filter <https://tools.ietf.org/html/draft-ietf-netconf-restconf-05#section-4.8.6>`__
+
+-  `start-time <https://tools.ietf.org/html/draft-ietf-netconf-restconf-05#section-4.8.7>`__
+
+-  `end-time <https://tools.ietf.org/html/draft-ietf-netconf-restconf-05#section-4.8.8>`__
+
+In addition, the following ODL extension query parameter is supported:
+
+:odl-leaf-nodes-only:
+  If this parameter is set to "true", create and update notifications will only
+  contain the leaf nodes modified instead of the entire subscription subtree.
+  This can help in reducing the size of the notifications.
+
 The expected response status is 200 OK and response body should be
 empty. You will get your WebSocket location from **Location** header of
 response. For example in our particular toaster example location header
@@ -1640,6 +1678,8 @@ RESTCONF.
     WebSocket client
     applications <https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications>`__
 
+.. _config_subsystem:
+
 Config Subsystem
 ----------------
 
@@ -1865,4 +1905,3 @@ It can be acquired from, for example, environment variables. After the
 creation of a default instance, it acts as a regular instance and fully
 participates in the configuration subsystem (It can be reconfigured or
 deleted in following transactions.).
-