Merge "Add ocpplugin release notes"
[docs.git] / docs / developer-guide / controller.rst
1 Controller
2 ==========
3
4 Overview
5 --------
6
7 OpenDaylight Controller is Java-based, model-driven controller using
8 YANG as its modeling language for various aspects of the system and
9 applications and with its components serves as a base platform for other
10 OpenDaylight applications.
11
12 The OpenDaylight Controller relies on the following technologies:
13
14 -  **OSGI** - This framework is the back-end of OpenDaylight as it
15    allows dynamically loading of bundles and packages JAR files, and
16    binding bundles together for exchanging information.
17
18 -  **Karaf** - Application container built on top of OSGI, which
19    simplifies operational aspects of packaging and installing
20    applications.
21
22 -  **YANG** - a data modeling language used to model configuration and
23    state data manipulated by the applications, remote procedure calls,
24    and notifications.
25
26 The OpenDaylight Controller provides following model-driven subsystems
27 as a foundation for Java applications:
28
29 -  **`Config Subsystem <#_config_subsystem>`__** - an activation,
30    dependency-injection and configuration framework, which allows
31    two-phase commits of configuration and dependency-injection, and
32    allows for run-time rewiring.
33
34 -  **`MD-SAL <#_md_sal_overview>`__** - messaging and data storage
35    functionality for data, notifications and RPCs modeled by application
36    developers. MD-SAL uses YANG as the modeling for both interface and
37    data definitions, and provides a messaging and data-centric runtime
38    for such services based on YANG modeling.
39
40 -  **MD-SAL Clustering** - enables cluster support for core MD-SAL
41    functionality and provides location-transparent accesss to
42    YANG-modeled data.
43
44 The OpenDaylight Controller supports external access to applications and
45 data using following model-driven protocols:
46
47 -  **NETCONF** - XML-based RPC protocol, which provides abilities for
48    client to invoke YANG-modeled RPCs, receive notifications and to
49    read, modify and manipulate YANG modeled data.
50
51 -  **RESTCONF** - HTTP-based protocol, which provides REST-like APIs to
52    manipulate YANG modeled data and invoke YANG modeled RPCs, using XML
53    or JSON as payload format.
54
55 .. _mdsal_dev_guide:
56
57 MD-SAL Overview
58 ---------------
59
60 The Model-Driven Service Adaptation Layer (MD-SAL) is message-bus
61 inspired extensible middleware component that provides messaging and
62 data storage functionality based on data and interface models defined by
63 application developers (i.e. user-defined models).
64
65 The MD-SAL:
66
67 -  Defines a **common-layer, concepts, data model building blocks and
68    messaging patterns** and provides infrastructure / framework for
69    applications and inter-application communication.
70
71 -  Provide common support for user-defined transport and payload
72    formats, including payload serialization and adaptation (e.g. binary,
73    XML or JSON).
74
75 The MD-SAL uses **YANG** as the modeling language for both interface and
76 data definitions, and provides a messaging and data-centric runtime for
77 such services based on YANG modeling.
78
79 | The MD-SAL provides two different API types (flavours):
80
81 -  **MD-SAL Binding:** MD-SAL APIs which extensively uses APIs and
82    classes generated from YANG models, which provides compile-time
83    safety.
84
85 -  **MD-SAL DOM:** (Document Object Model) APIs which uses DOM-like
86    representation of data, which makes them more powerful, but provides
87    less compile-time safety.
88
89 .. note::
90
91     Model-driven nature of the MD-SAL and **DOM**-based APIs allows for
92     behind-the-scene API and payload type mediation and transformation
93     to facilitate seamless communication between applications - this
94     enables for other components and applications to provide connectors
95     / expose different set of APIs and derive most of its functionality
96     purely from models, which all existing code can benefit from without
97     modification. For example **RESTCONF Connector** is an application
98     built on top of MD-SAL and exposes YANG-modeled application APIs
99     transparently via HTTP and adds support for XML and JSON payload
100     type.
101
102 Basic concepts
103 ~~~~~~~~~~~~~~
104
105 Basic concepts are building blocks which are used by applications, and
106 from which MD-SAL uses to define messaging patterns and to provide
107 services and behavior based on developer-supplied YANG models.
108
109 Data Tree
110     All state-related data are modeled and represented as data tree,
111     with possibility to address any element / subtree
112
113     -  **Operational Data Tree** - Reported state of the system,
114        published by the providers using MD-SAL. Represents a feedback
115        loop for applications to observe state of the network / system.
116
117     -  **Configuration Data Tree** - Intended state of the system or
118        network, populated by consumers, which expresses their intention.
119
120 Instance Identifier
121     Unique identifier of node / subtree in data tree, which provides
122     unambiguous information, how to reference and retrieve node /
123     subtree from conceptual data trees.
124
125 Notification
126     Asynchronous transient event which may be consumed by subscribers
127     and they may act upon it
128
129 RPC
130     asynchronous request-reply message pair, when request is triggered
131     by consumer, send to the provider, which in future replies with
132     reply message.
133
134     .. note::
135
136         In MD-SAL terminology, the term *RPC* is used to define the
137         input and output for a procedure (function) that is to be
138         provided by a provider, and mediated by the MD-SAL, that means
139         it may not result in remote call.
140
141 Messaging Patterns
142 ~~~~~~~~~~~~~~~~~~
143
144 MD-SAL provides several messaging patterns using broker derived from
145 basic concepts, which are intended to transfer YANG modeled data between
146 applications to provide data-centric integration between applications
147 instead of API-centric integration.
148
149 -  **Unicast communication**
150
151    -  **Remote Procedure Calls** - unicast between consumer and
152       provider, where consumer sends **request** message to provider,
153       which asynchronously responds with **reply** message
154
155 -  **Publish / Subscribe**
156
157    -  **Notifications** - multicast transient message which is published
158       by provider and is delivered to subscribers
159
160    -  **Data Change Events** - multicast asynchronous event, which is
161       sent by data broker if there is change in conceptual data tree,
162       and is delivered to subscribers
163
164 -  **Transactional access to Data Tree**
165
166    -  Transactional **reads** from conceptual **data tree** - read-only
167       transactions with isolation from other running transactions.
168
169    -  Transactional **modification** to conceptual **data tree** - write
170       transactions with isolation from other running transactions.
171
172    -  **Transaction chaining**
173
174 MD-SAL Data Transactions
175 ------------------------
176
177 MD-SAL **Data Broker** provides transactional access to conceptual
178 **data trees** representing configuration and operational state.
179
180 .. note::
181
182     **Data tree** usually represents state of the modeled data, usually
183     this is state of controller, applications and also external systems
184     (network devices).
185
186 **Transactions** provide **`stable and isolated
187 view <#_transaction_isolation>`__** from other currently running
188 transactions. The state of running transaction and underlying data tree
189 is not affected by other concurrently running transactions.
190
191 Write-Only
192     Transaction provides only modification capabilities, but does not
193     provide read capabilities. Write-only transaction is allocated using
194     ``newWriteOnlyTransaction()``.
195
196     .. note::
197
198         This allows less state tracking for write-only transactions and
199         allows MD-SAL Clustering to optimize internal representation of
200         transaction in cluster.
201
202 Read-Write
203     Transaction provides both read and write capabilities. It is
204     allocated using ``newReadWriteTransaction()``.
205
206 Read-Only
207     Transaction provides stable read-only view based on current data
208     tree. Read-only view is not affected by any subsequent write
209     transactions. Read-only transaction is allocated using
210     ``newReadOnlyTransaction()``.
211
212     .. note::
213
214         If an application needs to observe changes itself in data tree,
215         it should use **data tree listeners** instead of read-only
216         transactions and polling data tree.
217
218 Transactions may be allocated using the **data broker** itself or using
219 **transaction chain**. In the case of **transaction chain**, the new
220 allocated transaction is not based on current state of data tree, but
221 rather on state introduced by previous transaction from the same chain,
222 even if the commit for previous transaction has not yet occurred (but
223 transaction was submitted).
224
225 Write-Only & Read-Write Transaction
226 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
227
228 Write-Only and Read-Write transactions provide modification capabilities
229 for the conceptual data trees.
230
231 1. application allocates new transactions using
232    ``newWriteOnlyTransaction()`` or ``newReadWriteTransaction()``.
233
234 2. application `modifies data tree <#_modification_of_data_tree>`__
235    using ``put``, ``merge`` and/or ``delete``.
236
237 3. application finishes transaction using
238    ```submit()`` <#_submitting_transaction>`__, which seals transaction
239    and submits it to be processed.
240
241 4. application observes the result of the transaction commit using
242    either blocking or asynchronous calls.
243
244 The **initial state** of the write transaction is a **stable snapshot**
245 of the current data tree state captured when transaction was created and
246 it’s state and underlying data tree are not affected by other
247 concurrently running transactions.
248
249 Write transactions are **isolated** from other concurrent write
250 transactions. All **`writes are local <#_transaction_local_state>`__**
251 to the transaction and represents only a **proposal of state change**
252 for data tree and **are not visible** to any other concurrently running
253 transactions (including read-only transactions).
254
255 The transaction **`commit may fail <#_commit_failure_scenarios>`__** due
256 to failing verification of data or concurrent transaction modifying and
257 affected data in an incompatible way.
258
259 Modification of Data Tree
260 ^^^^^^^^^^^^^^^^^^^^^^^^^
261
262 Write-only and read-write transaction provides following methods to
263 modify data tree:
264
265 put
266     .. code:: java
267
268         <T> void put(LogicalDatastoreType store, InstanceIdentifier<T> path, T data);
269
270     Stores a piece of data at a specified path. This acts as an **add /
271     replace** operation, which is to say that whole subtree will be
272     replaced by the specified data.
273
274 merge
275     .. code:: java
276
277         <T> void merge(LogicalDatastoreType store, InstanceIdentifier<T> path, T data);
278
279     Merges a piece of data with the existing data at a specified path.
280     Any **pre-existing data** which are not explicitly overwritten
281     **will be preserved**. This means that if you store a container, its
282     child subtrees will be merged.
283
284 delete
285     .. code:: java
286
287         void delete(LogicalDatastoreType store, InstanceIdentifier<?> path);
288
289     Removes a whole subtree from a specified path.
290
291 Submitting transaction
292 ^^^^^^^^^^^^^^^^^^^^^^
293
294 Transaction is submitted to be processed and committed using following
295 method:
296
297 .. code:: java
298
299     CheckedFuture<Void,TransactionCommitFailedException> submit();
300
301 Applications publish the changes proposed in the transaction by calling
302 ``submit()`` on the transaction. This **seals the transaction**
303 (preventing any further writes using this transaction) and submits it to
304 be processed and applied to global conceptual data tree. The
305 ``submit()`` method does not block, but rather returns
306 ``ListenableFuture``, which will complete successfully once processing
307 of transaction is finished and changes are applied to data tree. If
308 **commit** of data failed, the future will fail with
309 ``TransactionFailedException``.
310
311 Application may listen on commit state asynchronously using
312 ``ListenableFuture``.
313
314 .. code:: java
315
316     Futures.addCallback( writeTx.submit(), new FutureCallback<Void>() {
317             public void onSuccess( Void result ) {
318                 LOG.debug("Transaction committed successfully.");
319             }
320
321             public void onFailure( Throwable t ) {
322                 LOG.error("Commit failed.",e);
323             }
324         });
325
326 -  Submits ``writeTx`` and registers application provided
327    ``FutureCallback`` on returned future.
328
329 -  Invoked when future completed successfully - transaction ``writeTx``
330    was successfully committed to data tree.
331
332 -  Invoked when future failed - commit of transaction ``writeTx``
333    failed. Supplied exception provides additional details and cause of
334    failure.
335
336 If application need to block till commit is finished it may use
337 ``checkedGet()`` to wait till commit is finished.
338
339 .. code:: java
340
341     try {
342         writeTx.submit().checkedGet();
343     } catch (TransactionCommitFailedException e) {
344         LOG.error("Commit failed.",e);
345     }
346
347 -  Submits ``writeTx`` and blocks till commit of ``writeTx`` is
348    finished. If commit fails ``TransactionCommitFailedException`` will
349    be thrown.
350
351 -  Catches ``TransactionCommitFailedException`` and logs it.
352
353 Transaction local state
354 ^^^^^^^^^^^^^^^^^^^^^^^
355
356 Read-Write transactions maintain transaction-local state, which renders
357 all modifications as if they happened, but this is only local to
358 transaction.
359
360 Reads from the transaction returns data as if the previous modifications
361 in transaction already happened.
362
363 Let assume initial state of data tree for ``PATH`` is ``A``.
364
365 .. code:: java
366
367     ReadWriteTransaction rwTx = broker.newReadWriteTransaction();
368
369     rwRx.read(OPERATIONAL,PATH).get();
370     rwRx.put(OPERATIONAL,PATH,B);
371     rwRx.read(OPERATIONAL,PATH).get();
372     rwRx.put(OPERATIONAL,PATH,C);
373     rwRx.read(OPERATIONAL,PATH).get();
374
375 -  Allocates new ``ReadWriteTransaction``.
376
377 -  Read from ``rwTx`` will return value ``A`` for ``PATH``.
378
379 -  Writes value ``B`` to ``PATH`` using ``rwTx``.
380
381 -  Read will return value ``B`` for ``PATH``, since previous write
382    occurred in same transaction.
383
384 -  Writes value ``C`` to ``PATH`` using ``rwTx``.
385
386 -  Read will return value ``C`` for ``PATH``, since previous write
387    occurred in same transaction.
388
389 Transaction isolation
390 ~~~~~~~~~~~~~~~~~~~~~
391
392 Running (not submitted) transactions are isolated from each other and
393 changes done in one transaction are not observable in other currently
394 running transaction.
395
396 Lets assume initial state of data tree for ``PATH`` is ``A``.
397
398 .. code:: java
399
400     ReadOnlyTransaction txRead = broker.newReadOnlyTransaction();
401     ReadWriteTransaction txWrite = broker.newReadWriteTransaction();
402
403     txRead.read(OPERATIONAL,PATH).get();
404     txWrite.put(OPERATIONAL,PATH,B);
405     txWrite.read(OPERATIONAL,PATH).get();
406     txWrite.submit().get();
407     txRead.read(OPERATIONAL,PATH).get();
408     txAfterCommit = broker.newReadOnlyTransaction();
409     txAfterCommit.read(OPERATIONAL,PATH).get();
410
411 -  Allocates read only transaction, which is based on data tree which
412    contains value ``A`` for ``PATH``.
413
414 -  Allocates read write transaction, which is based on data tree which
415    contains value ``A`` for ``PATH``.
416
417 -  Read from read-only transaction returns value ``A`` for ``PATH``.
418
419 -  Data tree is updated using read-write transaction, ``PATH`` contains
420    ``B``. Change is not public and only local to transaction.
421
422 -  Read from read-write transaction returns value ``B`` for ``PATH``.
423
424 -  Submits changes in read-write transaction to be committed to data
425    tree. Once commit will finish, changes will be published and ``PATH``
426    will be updated for value ``B``. Previously allocated transactions
427    are not affected by this change.
428
429 -  Read from previously allocated read-only transaction still returns
430    value ``A`` for ``PATH``, since it provides stable and isolated view.
431
432 -  Allocates new read-only transaction, which is based on data tree,
433    which contains value ``B`` for ``PATH``.
434
435 -  Read from new read-only transaction return value ``B`` for ``PATH``
436    since read-write transaction was committed.
437
438 .. note::
439
440     Examples contain blocking calls on future only to illustrate that
441     action happened after other asynchronous action. The use of the
442     blocking call ``ListenableFuture#get()`` is discouraged for most
443     use-cases and you should use
444     ``Futures#addCallback(ListenableFuture, FutureCallback)`` to listen
445     asynchronously for result.
446
447 Commit failure scenarios
448 ~~~~~~~~~~~~~~~~~~~~~~~~
449
450 A transaction commit may fail because of following reasons:
451
452 Optimistic Lock Failure
453     Another transaction finished earlier and **modified the same node in
454     a non-compatible way**. The commit (and the returned future) will
455     fail with an ``OptimisticLockFailedException``.
456
457     It is the responsibility of the caller to create a new transaction
458     and submit the same modification again in order to update data tree.
459
460     .. warning::
461
462         ``OptimisticLockFailedException`` usually exposes **multiple
463         writers** to the same data subtree, which may conflict on same
464         resources.
465
466         In most cases, retrying may result in a probability of success.
467
468         There are scenarios, albeit unusual, where any number of retries
469         will not succeed. Therefore it is strongly recommended to limit
470         the number of retries (2 or 3) to avoid an endless loop.
471
472 Data Validation
473     The data change introduced by this transaction **did not pass
474     validation** by commit handlers or data was incorrectly structured.
475     The returned future will fail with a
476     ``DataValidationFailedException``. User **should not retry** to
477     create new transaction with same data, since it probably will fail
478     again.
479
480 Example conflict of two transactions
481 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
482
483 This example illustrates two concurrent transactions, which derived from
484 same initial state of data tree and proposes conflicting modifications.
485
486 .. code:: java
487
488     WriteTransaction txA = broker.newWriteTransaction();
489     WriteTransaction txB = broker.newWriteTransaction();
490
491     txA.put(CONFIGURATION, PATH, A);
492     txB.put(CONFIGURATION, PATH, B);
493
494     CheckedFuture<?,?> futureA = txA.submit();
495     CheckedFuture<?,?> futureB = txB.submit();
496
497 -  Updates ``PATH`` to value ``A`` using ``txA``
498
499 -  Updates ``PATH`` to value ``B`` using ``txB``
500
501 -  Seals & submits ``txA``. The commit will be processed asynchronously
502    and data tree will be updated to contain value ``A`` for ``PATH``.
503    The returned ‘ListenableFuture’ will complete successfully once state
504    is applied to data tree.
505
506 -  Seals & submits ``txB``. Commit of ``txB`` will fail, because
507    previous transaction also modified path in a concurrent way. The
508    state introduced by ``txB`` will not be applied. The returned
509    ``ListenableFuture`` will fail with ``OptimisticLockFailedException``
510    exception, which indicates that concurrent transaction prevented the
511    submitted transaction from being applied.
512
513 Example asynchronous retry-loop
514 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
515
516 .. code:: java
517
518     private void doWrite( final int tries ) {
519         WriteTransaction writeTx = dataBroker.newWriteOnlyTransaction();
520
521         MyDataObject data = ...;
522         InstanceIdentifier<MyDataObject> path = ...;
523         writeTx.put( LogicalDatastoreType.OPERATIONAL, path, data );
524
525         Futures.addCallback( writeTx.submit(), new FutureCallback<Void>() {
526             public void onSuccess( Void result ) {
527                 // succeeded
528             }
529
530             public void onFailure( Throwable t ) {
531                 if( t instanceof OptimisticLockFailedException && (( tries - 1 ) > 0)) {
532                     doWrite( tries - 1 );
533                 }
534             }
535           });
536     }
537     ...
538     doWrite( 2 );
539
540 Concurrent change compatibility
541 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
542
543 There are several sets of changes which could be considered incompatible
544 between two transactions which are derived from same initial state.
545 Rules for conflict detection applies recursively for each subtree level.
546
547 Following table shows state changes and failures between two concurrent
548 transactions, which are based on same initial state, ``tx1`` is
549 submitted before ``tx2``.
550
551 INFO: Following tables stores numeric values and shows data using
552 ``toString()`` to simplify examples.
553
554 +--------------------+--------------------+--------------------+--------------------+
555 | Initial state      | tx1                | tx2                | Observable Result  |
556 +====================+====================+====================+====================+
557 | Empty              | ``put(A,1)``       | ``put(A,2)``       | ``tx2`` will fail, |
558 |                    |                    |                    | value of ``A`` is  |
559 |                    |                    |                    | ``1``              |
560 +--------------------+--------------------+--------------------+--------------------+
561 | Empty              | ``put(A,1)``       | ``merge(A,2)``     | value of ``A`` is  |
562 |                    |                    |                    | ``2``              |
563 +--------------------+--------------------+--------------------+--------------------+
564 | Empty              | ``merge(A,1)``     | ``put(A,2)``       | ``tx2`` will fail, |
565 |                    |                    |                    | value of ``A`` is  |
566 |                    |                    |                    | ``1``              |
567 +--------------------+--------------------+--------------------+--------------------+
568 | Empty              | ``merge(A,1)``     | ``merge(A,2)``     | ``A`` is ``2``     |
569 +--------------------+--------------------+--------------------+--------------------+
570 | A=0                | ``put(A,1)``       | ``put(A,2)``       | ``tx2`` will fail, |
571 |                    |                    |                    | ``A`` is ``1``     |
572 +--------------------+--------------------+--------------------+--------------------+
573 | A=0                | ``put(A,1)``       | ``merge(A,2)``     | ``A`` is ``2``     |
574 +--------------------+--------------------+--------------------+--------------------+
575 | A=0                | ``merge(A,1)``     | ``put(A,2)``       | ``tx2`` will fail, |
576 |                    |                    |                    | value of ``A`` is  |
577 |                    |                    |                    | ``1``              |
578 +--------------------+--------------------+--------------------+--------------------+
579 | A=0                | ``merge(A,1)``     | ``merge(A,2)``     | ``A`` is ``2``     |
580 +--------------------+--------------------+--------------------+--------------------+
581 | A=0                | ``delete(A)``      | ``put(A,2)``       | ``tx2`` will fail, |
582 |                    |                    |                    | ``A`` does not     |
583 |                    |                    |                    | exists             |
584 +--------------------+--------------------+--------------------+--------------------+
585 | A=0                | ``delete(A)``      | ``merge(A,2)``     | ``A`` is ``2``     |
586 +--------------------+--------------------+--------------------+--------------------+
587
588 Table: Concurrent change resolution for leaves and leaf-list items
589
590 +--------------------+--------------------+--------------------+--------------------+
591 | Initial state      | ``tx1``            | ``tx2``            | Result             |
592 +====================+====================+====================+====================+
593 | Empty              | put(TOP,[])        | put(TOP,[])        | ``tx2`` will fail, |
594 |                    |                    |                    | state is TOP=[]    |
595 +--------------------+--------------------+--------------------+--------------------+
596 | Empty              | put(TOP,[])        | merge(TOP,[])      | TOP=[]             |
597 +--------------------+--------------------+--------------------+--------------------+
598 | Empty              | put(TOP,[FOO=1])   | put(TOP,[BAR=1])   | ``tx2`` will fail, |
599 |                    |                    |                    | state is           |
600 |                    |                    |                    | TOP=[FOO=1]        |
601 +--------------------+--------------------+--------------------+--------------------+
602 | Empty              | put(TOP,[FOO=1])   | merge(TOP,[BAR=1]) | TOP=[FOO=1,BAR=1]  |
603 +--------------------+--------------------+--------------------+--------------------+
604 | Empty              | merge(TOP,[FOO=1]) | put(TOP,[BAR=1])   | ``tx2`` will fail, |
605 |                    |                    |                    | state is           |
606 |                    |                    |                    | TOP=[FOO=1]        |
607 +--------------------+--------------------+--------------------+--------------------+
608 | Empty              | merge(TOP,[FOO=1]) | merge(TOP,[BAR=1]) | TOP=[FOO=1,BAR=1]  |
609 +--------------------+--------------------+--------------------+--------------------+
610 | TOP=[]             | put(TOP,[FOO=1])   | put(TOP,[BAR=1])   | ``tx2`` will fail, |
611 |                    |                    |                    | state is           |
612 |                    |                    |                    | TOP=[FOO=1]        |
613 +--------------------+--------------------+--------------------+--------------------+
614 | TOP=[]             | put(TOP,[FOO=1])   | merge(TOP,[BAR=1]) | state is           |
615 |                    |                    |                    | TOP=[FOO=1,BAR=1]  |
616 +--------------------+--------------------+--------------------+--------------------+
617 | TOP=[]             | merge(TOP,[FOO=1]) | put(TOP,[BAR=1])   | ``tx2`` will fail, |
618 |                    |                    |                    | state is           |
619 |                    |                    |                    | TOP=[FOO=1]        |
620 +--------------------+--------------------+--------------------+--------------------+
621 | TOP=[]             | merge(TOP,[FOO=1]) | merge(TOP,[BAR=1]) | state is           |
622 |                    |                    |                    | TOP=[FOO=1,BAR=1]  |
623 +--------------------+--------------------+--------------------+--------------------+
624 | TOP=[]             | delete(TOP)        | put(TOP,[BAR=1])   | ``tx2`` will fail, |
625 |                    |                    |                    | state is empty     |
626 |                    |                    |                    | store              |
627 +--------------------+--------------------+--------------------+--------------------+
628 | TOP=[]             | delete(TOP)        | merge(TOP,[BAR=1]) | state is           |
629 |                    |                    |                    | TOP=[BAR=1]        |
630 +--------------------+--------------------+--------------------+--------------------+
631 | TOP=[]             | put(TOP/FOO,1)     | put(TOP/BAR,1])    | state is           |
632 |                    |                    |                    | TOP=[FOO=1,BAR=1]  |
633 +--------------------+--------------------+--------------------+--------------------+
634 | TOP=[]             | put(TOP/FOO,1)     | merge(TOP/BAR,1)   | state is           |
635 |                    |                    |                    | TOP=[FOO=1,BAR=1]  |
636 +--------------------+--------------------+--------------------+--------------------+
637 | TOP=[]             | merge(TOP/FOO,1)   | put(TOP/BAR,1)     | state is           |
638 |                    |                    |                    | TOP=[FOO=1,BAR=1]  |
639 +--------------------+--------------------+--------------------+--------------------+
640 | TOP=[]             | merge(TOP/FOO,1)   | merge(TOP/BAR,1)   | state is           |
641 |                    |                    |                    | TOP=[FOO=1,BAR=1]  |
642 +--------------------+--------------------+--------------------+--------------------+
643 | TOP=[]             | delete(TOP)        | put(TOP/BAR,1)     | ``tx2`` will fail, |
644 |                    |                    |                    | state is empty     |
645 |                    |                    |                    | store              |
646 +--------------------+--------------------+--------------------+--------------------+
647 | TOP=[]             | delete(TOP)        | merge(TOP/BAR,1]   | ``tx2`` will fail, |
648 |                    |                    |                    | state is empty     |
649 |                    |                    |                    | store              |
650 +--------------------+--------------------+--------------------+--------------------+
651 | TOP=[FOO=1]        | put(TOP/FOO,2)     | put(TOP/BAR,1)     | state is           |
652 |                    |                    |                    | TOP=[FOO=2,BAR=1]  |
653 +--------------------+--------------------+--------------------+--------------------+
654 | TOP=[FOO=1]        | put(TOP/FOO,2)     | merge(TOP/BAR,1)   | state is           |
655 |                    |                    |                    | TOP=[FOO=2,BAR=1]  |
656 +--------------------+--------------------+--------------------+--------------------+
657 | TOP=[FOO=1]        | merge(TOP/FOO,2)   | put(TOP/BAR,1)     | state is           |
658 |                    |                    |                    | TOP=[FOO=2,BAR=1]  |
659 +--------------------+--------------------+--------------------+--------------------+
660 | TOP=[FOO=1]        | merge(TOP/FOO,2)   | merge(TOP/BAR,1)   | state is           |
661 |                    |                    |                    | TOP=[FOO=2,BAR=1]  |
662 +--------------------+--------------------+--------------------+--------------------+
663 | TOP=[FOO=1]        | delete(TOP/FOO)    | put(TOP/BAR,1)     | state is           |
664 |                    |                    |                    | TOP=[BAR=1]        |
665 +--------------------+--------------------+--------------------+--------------------+
666 | TOP=[FOO=1]        | delete(TOP/FOO)    | merge(TOP/BAR,1]   | state is           |
667 |                    |                    |                    | TOP=[BAR=1]        |
668 +--------------------+--------------------+--------------------+--------------------+
669
670 Table: Concurrent change resolution for containers, lists, list items
671
672 MD-SAL RPC routing
673 ------------------
674
675 The MD-SAL provides a way to deliver Remote Procedure Calls (RPCs) to a
676 particular implementation based on content in the input as it is modeled
677 in YANG. This part of the the RPC input is referred to as a **context
678 reference**.
679
680 The MD-SAL does not dictate the name of the leaf which is used for this
681 RPC routing, but provides necessary functionality for YANG model author
682 to define their **context reference** in their model of RPCs.
683
684 MD-SAL routing behavior is modeled using following terminology and its
685 application to YANG models:
686
687 Context Type
688     Logical type of RPC routing. Context type is modeled as YANG
689     ``identity`` and is referenced in model to provide scoping
690     information.
691
692 Context Instance
693     Conceptual location in data tree, which represents context in which
694     RPC could be executed. Context instance usually represent logical
695     point to which RPC execution is attached.
696
697 Context Reference
698     Field of RPC input payload which contains Instance Identifier
699     referencing **context instance** in which the RPC should be
700     executed.
701
702 Modeling a routed RPC
703 ~~~~~~~~~~~~~~~~~~~~~
704
705 In order to define routed RPCs, the YANG model author needs to declare
706 (or reuse) a **context type**, set of possible **context instances** and
707 finally RPCs which will contain **context reference** on which they will
708 be routed.
709
710 Declaring a routing context type
711 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
712
713 .. code:: yang
714
715     identity node-context {
716         description "Identity used to mark node context";
717     }
718
719 This declares an identity named ``node-context``, which is used as
720 marker for node-based routing and is used in other places to reference
721 that routing type.
722
723 Declaring possible context instances
724 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
725
726 In order to define possible values of **context instances** for routed
727 RPCs, we need to model that set accordingly using ``context-instance``
728 extension from the ``yang-ext`` model.
729
730 .. code:: yang
731
732     import yang-ext { prefix ext; }
733
734     /** Base structure **/
735     container nodes {
736         list node {
737             key "id";
738             ext:context-instance "node-context";
739             // other node-related fields would go here
740         }
741     }
742
743 The statement ``ext:context-instance "node-context";`` marks any element
744 of the ``list node`` as a possible valid **context instance** in
745 ``node-context`` based routing.
746
747 .. note::
748
749     The existence of a **context instance** node in operational or
750     config data tree is not strongly tied to existence of RPC
751     implementation.
752
753     For most routed RPC models, there is relationship between the data
754     present in operational data tree and RPC implementation
755     availability, but this is not enforced by MD-SAL. This provides some
756     flexibility for YANG model writers to better specify their routing
757     model and requirements for implementations. Details when RPC
758     implementations are available should be documented in YANG model.
759
760     If user invokes RPC with a **context instance** that has no
761     registered implementation, the RPC invocation will fail with the
762     exception ``DOMRpcImplementationNotAvailableException``.
763
764 Declaring a routed RPC
765 ^^^^^^^^^^^^^^^^^^^^^^
766
767 To declare RPC to be routed based on ``node-context`` we need to add
768 leaf of ``instance-identifier`` type (or type derived from
769 ``instance-identifier``) to the RPC and mark it as **context
770 reference**.
771
772 This is achieved using YANG extension ``context-reference`` from
773 ``yang-ext`` model on leaf, which will be used for RPC routing.
774
775 .. code:: yang
776
777     rpc example-routed-rpc  {
778         input {
779             leaf node {
780                 ext:context-reference "node-context";
781                 type "instance-identifier";
782             }
783             // other input to the RPC would go here
784         }
785     }
786
787 The statement ``ext:context-reference "node-context"`` marks
788 ``leaf node`` as **context reference** of type ``node-context``. The
789 value of this leaf, will be used by the MD-SAL to select the particular
790 RPC implementation that registered itself as the implementation of the
791 RPC for particular **context instance**.
792
793 Using routed RPCs
794 ~~~~~~~~~~~~~~~~~
795
796 From a user perspective (e.g. invoking RPCs) there is no difference
797 between routed and non-routed RPCs. Routing information is just an
798 additional leaf in RPC which must be populated.
799
800 Implementing a routed RPC
801 ~~~~~~~~~~~~~~~~~~~~~~~~~
802
803 Implementation
804
805 Registering implementations
806 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
807
808 Implementations of a routed RPC (e.g., southbound plugins) will specify
809 an instance-identifier for the **context reference** (in this case a
810 node) for which they want to provide an implementation during
811 registration. Consumers, e.g., those calling the RPC are required to
812 specify that instance-identifier (in this case the identifier of a node)
813 when invoking RPC.
814
815 Simple code which showcases that for add-flow via Binding-Aware APIs
816 (`RoutedServiceTest.java <https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blob;f=opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/RoutedServiceTest.java;h=d49d6f0e25e271e43c8550feb5eef63d96301184;hb=HEAD>`__
817 ):
818
819 .. code:: java
820
821      61  @Override
822      62  public void onSessionInitiated(ProviderContext session) {
823      63      assertNotNull(session);
824      64      firstReg = session.addRoutedRpcImplementation(SalFlowService.class, salFlowService1);
825      65  }
826
827 Line 64: We are registering salFlowService1 as implementation of
828 SalFlowService RPC
829
830 .. code:: java
831
832     107  NodeRef nodeOne = createNodeRef("foo:node:1");
833     109  /**
834     110   * Provider 1 registers path of node 1
835     111   */
836     112  firstReg.registerPath(NodeContext.class, nodeOne);
837
838 Line 107: We are creating NodeRef (encapsulation of InstanceIdentifier)
839 for "foo:node:1".
840
841 Line 112: We register salFlowService1 as implementation for nodeOne.
842
843 The salFlowService1 will be executed only for RPCs which contains
844 Instance Identifier for foo:node:1.
845
846 OpenDaylight Controller MD-SAL: RESTCONF
847 ----------------------------------------
848
849 RESCONF operations overview
850 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
851
852 | RESTCONF allows access to datastores in the controller.
853 | There are two datastores:
854
855 -  Config: Contains data inserted via controller
856
857 -  Operational: Contains other data
858
859 .. note::
860
861     | Each request must start with the URI /restconf.
862     | RESTCONF listens on port 8080 for HTTP requests.
863
864 RESTCONF supports **OPTIONS**, **GET**, **PUT**, **POST**, and
865 **DELETE** operations. Request and response data can either be in the
866 XML or JSON format. XML structures according to yang are defined at:
867 `XML-YANG <http://tools.ietf.org/html/rfc6020>`__. JSON structures are
868 defined at:
869 `JSON-YANG <http://tools.ietf.org/html/draft-lhotka-netmod-yang-json-02>`__.
870 Data in the request must have a correctly set **Content-Type** field in
871 the http header with the allowed value of the media type. The media type
872 of the requested data has to be set in the **Accept** field. Get the
873 media types for each resource by calling the OPTIONS operation. Most of
874 the paths of the pathsRestconf endpoints use `Instance
875 Identifier <https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Concepts#Instance_Identifier>`__.
876 ``<identifier>`` is used in the explanation of the operations.
877
878 | **<identifier>**
879
880 -  It must start with <moduleName>:<nodeName> where <moduleName> is a
881    name of the module and <nodeName> is the name of a node in the
882    module. It is sufficient to just use <nodeName> after
883    <moduleName>:<nodeName>. Each <nodeName> has to be separated by /.
884
885 -  <nodeName> can represent a data node which is a list or container
886    yang built-in type. If the data node is a list, there must be defined
887    keys of the list behind the data node name for example,
888    <nodeName>/<valueOfKey1>/<valueOfKey2>.
889
890 -  | The format <moduleName>:<nodeName> has to be used in this case as
891      well:
892    | Module A has node A1. Module B augments node A1 by adding node X.
893      Module C augments node A1 by adding node X. For clarity, it has to
894      be known which node is X (for example: C:X). For more details about
895      encoding, see: `RESTCONF 02 - Encoding YANG Instance Identifiers in
896      the Request
897      URI. <http://tools.ietf.org/html/draft-bierman-netconf-restconf-02#section-5.3.1>`__
898
899 Mount point
900 ~~~~~~~~~~~
901
902 | A Node can be behind a mount point. In this case, the URI has to be in
903   format <identifier>/**yang-ext:mount**/<identifier>. The first
904   <identifier> is the path to a mount point and the second <identifier>
905   is the path to a node behind the mount point. A URI can end in a mount
906   point itself by using <identifier>/**yang-ext:mount**.
907 | More information on how to actually use mountpoints is available at:
908   `OpenDaylight
909   Controller:Config:Examples:Netconf <https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:Netconf>`__.
910
911 HTTP methods
912 ~~~~~~~~~~~~
913
914 OPTIONS /restconf
915 ^^^^^^^^^^^^^^^^^
916
917 -  Returns the XML description of the resources with the required
918    request and response media types in Web Application Description
919    Language (WADL)
920
921 GET /restconf/config/<identifier>
922 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
923
924 -  Returns a data node from the Config datastore.
925
926 -  <identifier> points to a data node which must be retrieved.
927
928 GET /restconf/operational/<identifier>
929 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
930
931 -  Returns the value of the data node from the Operational datastore.
932
933 -  <identifier> points to a data node which must be retrieved.
934
935 PUT /restconf/config/<identifier>
936 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
937
938 -  Updates or creates data in the Config datastore and returns the state
939    about success.
940
941 -  <identifier> points to a data node which must be stored.
942
943 | **Example:**
944
945 ::
946
947     PUT http://<controllerIP>:8080/restconf/config/module1:foo/bar
948     Content-Type: applicaton/xml
949     <bar>
950       …
951     </bar>
952
953 | **Example with mount point:**
954
955 ::
956
957     PUT http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo/bar
958     Content-Type: applicaton/xml
959     <bar>
960       …
961     </bar>
962
963 POST /restconf/config
964 ^^^^^^^^^^^^^^^^^^^^^
965
966 -  Creates the data if it does not exist
967
968 | For example:
969
970 ::
971
972     POST URL: http://localhost:8080/restconf/config/
973     content-type: application/yang.data+json
974     JSON payload:
975
976        {
977          "toaster:toaster" :
978          {
979            "toaster:toasterManufacturer" : "General Electric",
980            "toaster:toasterModelNumber" : "123",
981            "toaster:toasterStatus" : "up"
982          }
983       }
984
985 POST /restconf/config/<identifier>
986 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
987
988 -  Creates the data if it does not exist in the Config datastore, and
989    returns the state about success.
990
991 -  <identifier> points to a data node where data must be stored.
992
993 -  The root element of data must have the namespace (data are in XML) or
994    module name (data are in JSON.)
995
996 | **Example:**
997
998 ::
999
1000     POST http://<controllerIP>:8080/restconf/config/module1:foo
1001     Content-Type: applicaton/xml/
1002     <bar xmlns=“module1namespace”>
1003       …
1004     </bar>
1005
1006 **Example with mount point:**
1007
1008 ::
1009
1010     http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo
1011     Content-Type: applicaton/xml
1012     <bar xmlns=“module2namespace”>
1013       …
1014     </bar>
1015
1016 POST /restconf/operations/<moduleName>:<rpcName>
1017 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1018
1019 -  Invokes RPC.
1020
1021 -  <moduleName>:<rpcName> - <moduleName> is the name of the module and
1022    <rpcName> is the name of the RPC in this module.
1023
1024 -  The Root element of the data sent to RPC must have the name “input”.
1025
1026 -  The result can be the status code or the retrieved data having the
1027    root element “output”.
1028
1029 | **Example:**
1030
1031 ::
1032
1033     POST http://<controllerIP>:8080/restconf/operations/module1:fooRpc
1034     Content-Type: applicaton/xml
1035     Accept: applicaton/xml
1036     <input>
1037       …
1038     </input>
1039
1040     The answer from the server could be:
1041     <output>
1042       …
1043     </output>
1044
1045 | **An example using a JSON payload:**
1046
1047 ::
1048
1049     POST http://localhost:8080/restconf/operations/toaster:make-toast
1050     Content-Type: application/yang.data+json
1051     {
1052       "input" :
1053       {
1054          "toaster:toasterDoneness" : "10",
1055          "toaster:toasterToastType":"wheat-bread"
1056       }
1057     }
1058
1059 .. note::
1060
1061     Even though this is a default for the toasterToastType value in the
1062     yang, you still need to define it.
1063
1064 DELETE /restconf/config/<identifier>
1065 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1066
1067 -  Removes the data node in the Config datastore and returns the state
1068    about success.
1069
1070 -  <identifier> points to a data node which must be removed.
1071
1072 More information is available in the `RESTCONF
1073 RFC <http://tools.ietf.org/html/draft-bierman-netconf-restconf-02>`__.
1074
1075 How RESTCONF works
1076 ~~~~~~~~~~~~~~~~~~
1077
1078 | RESTCONF uses these base classes:
1079
1080 InstanceIdentifier
1081     Represents the path in the data tree
1082
1083 ConsumerSession
1084     Used for invoking RPCs
1085
1086 DataBrokerService
1087     Offers manipulation with transactions and reading data from the
1088     datastores
1089
1090 SchemaContext
1091     Holds information about yang modules
1092
1093 MountService
1094     Returns MountInstance based on the InstanceIdentifier pointing to a
1095     mount point
1096
1097 MountInstace
1098     Contains the SchemaContext behind the mount point
1099
1100 DataSchemaNode
1101     Provides information about the schema node
1102
1103 SimpleNode
1104     Possesses the same name as the schema node, and contains the value
1105     representing the data node value
1106
1107 CompositeNode
1108     Can contain CompositeNode-s and SimpleNode-s
1109
1110 GET in action
1111 ~~~~~~~~~~~~~
1112
1113 Figure 1 shows the GET operation with URI restconf/config/M:N where M is
1114 the module name, and N is the node name.
1115
1116 .. figure:: ./images/Get.png
1117    :alt: Get
1118
1119    Get
1120
1121 1. The requested URI is translated into the InstanceIdentifier which
1122    points to the data node. During this translation, the DataSchemaNode
1123    that conforms to the data node is obtained. If the data node is
1124    behind the mount point, the MountInstance is obtained as well.
1125
1126 2. RESTCONF asks for the value of the data node from DataBrokerService
1127    based on InstanceIdentifier.
1128
1129 3. DataBrokerService returns CompositeNode as data.
1130
1131 4. StructuredDataToXmlProvider or StructuredDataToJsonProvider is called
1132    based on the **Accept** field from the http request. These two
1133    providers can transform CompositeNode regarding DataSchemaNode to an
1134    XML or JSON document.
1135
1136 5. XML or JSON is returned as the answer on the request from the client.
1137
1138 PUT in action
1139 ~~~~~~~~~~~~~
1140
1141 Figure 2 shows the PUT operation with the URI restconf/config/M:N where
1142 M is the module name, and N is the node name. Data is sent in the
1143 request either in the XML or JSON format.
1144
1145 .. figure:: ./images/Put.png
1146    :alt: Put
1147
1148    Put
1149
1150 1. Input data is sent to JsonToCompositeNodeProvider or
1151    XmlToCompositeNodeProvider. The correct provider is selected based on
1152    the Content-Type field from the http request. These two providers can
1153    transform input data to CompositeNode. However, this CompositeNode
1154    does not contain enough information for transactions.
1155
1156 2. The requested URI is translated into InstanceIdentifier which points
1157    to the data node. DataSchemaNode conforming to the data node is
1158    obtained during this translation. If the data node is behind the
1159    mount point, the MountInstance is obtained as well.
1160
1161 3. CompositeNode can be normalized by adding additional information from
1162    DataSchemaNode.
1163
1164 4. RESTCONF begins the transaction, and puts CompositeNode with
1165    InstanceIdentifier into it. The response on the request from the
1166    client is the status code which depends on the result from the
1167    transaction.
1168
1169 Something practical
1170 ~~~~~~~~~~~~~~~~~~~
1171
1172 1. Create a new flow on the switch openflow:1 in table 2.
1173
1174 | **HTTP request**
1175
1176 ::
1177
1178     Operation: POST
1179     URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2
1180     Content-Type: application/xml
1181
1182 ::
1183
1184     <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1185     <flow
1186         xmlns="urn:opendaylight:flow:inventory">
1187         <strict>false</strict>
1188         <instructions>
1189             <instruction>
1190                 <order>1</order>
1191                 <apply-actions>
1192                     <action>
1193                       <order>1</order>
1194                         <flood-all-action/>
1195                     </action>
1196                 </apply-actions>
1197             </instruction>
1198         </instructions>
1199         <table_id>2</table_id>
1200         <id>111</id>
1201         <cookie_mask>10</cookie_mask>
1202         <out_port>10</out_port>
1203         <installHw>false</installHw>
1204         <out_group>2</out_group>
1205         <match>
1206             <ethernet-match>
1207                 <ethernet-type>
1208                     <type>2048</type>
1209                 </ethernet-type>
1210             </ethernet-match>
1211             <ipv4-destination>10.0.0.1/24</ipv4-destination>
1212         </match>
1213         <hard-timeout>0</hard-timeout>
1214         <cookie>10</cookie>
1215         <idle-timeout>0</idle-timeout>
1216         <flow-name>FooXf22</flow-name>
1217         <priority>2</priority>
1218         <barrier>false</barrier>
1219     </flow>
1220
1221 | **HTTP response**
1222
1223 ::
1224
1225     Status: 204 No Content
1226
1227 1. Change *strict* to *true* in the previous flow.
1228
1229 | **HTTP request**
1230
1231 ::
1232
1233     Operation: PUT
1234     URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
1235     Content-Type: application/xml
1236
1237 ::
1238
1239     <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1240     <flow
1241         xmlns="urn:opendaylight:flow:inventory">
1242         <strict>true</strict>
1243         <instructions>
1244             <instruction>
1245                 <order>1</order>
1246                 <apply-actions>
1247                     <action>
1248                       <order>1</order>
1249                         <flood-all-action/>
1250                     </action>
1251                 </apply-actions>
1252             </instruction>
1253         </instructions>
1254         <table_id>2</table_id>
1255         <id>111</id>
1256         <cookie_mask>10</cookie_mask>
1257         <out_port>10</out_port>
1258         <installHw>false</installHw>
1259         <out_group>2</out_group>
1260         <match>
1261             <ethernet-match>
1262                 <ethernet-type>
1263                     <type>2048</type>
1264                 </ethernet-type>
1265             </ethernet-match>
1266             <ipv4-destination>10.0.0.1/24</ipv4-destination>
1267         </match>
1268         <hard-timeout>0</hard-timeout>
1269         <cookie>10</cookie>
1270         <idle-timeout>0</idle-timeout>
1271         <flow-name>FooXf22</flow-name>
1272         <priority>2</priority>
1273         <barrier>false</barrier>
1274     </flow>
1275
1276 | **HTTP response**
1277
1278 ::
1279
1280     Status: 200 OK
1281
1282 1. Show flow: check that *strict* is *true*.
1283
1284 | **HTTP request**
1285
1286 ::
1287
1288     Operation: GET
1289     URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
1290     Accept: application/xml
1291
1292 | **HTTP response**
1293
1294 ::
1295
1296     Status: 200 OK
1297
1298 ::
1299
1300     <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1301     <flow
1302         xmlns="urn:opendaylight:flow:inventory">
1303         <strict>true</strict>
1304         <instructions>
1305             <instruction>
1306                 <order>1</order>
1307                 <apply-actions>
1308                     <action>
1309                       <order>1</order>
1310                         <flood-all-action/>
1311                     </action>
1312                 </apply-actions>
1313             </instruction>
1314         </instructions>
1315         <table_id>2</table_id>
1316         <id>111</id>
1317         <cookie_mask>10</cookie_mask>
1318         <out_port>10</out_port>
1319         <installHw>false</installHw>
1320         <out_group>2</out_group>
1321         <match>
1322             <ethernet-match>
1323                 <ethernet-type>
1324                     <type>2048</type>
1325                 </ethernet-type>
1326             </ethernet-match>
1327             <ipv4-destination>10.0.0.1/24</ipv4-destination>
1328         </match>
1329         <hard-timeout>0</hard-timeout>
1330         <cookie>10</cookie>
1331         <idle-timeout>0</idle-timeout>
1332         <flow-name>FooXf22</flow-name>
1333         <priority>2</priority>
1334         <barrier>false</barrier>
1335     </flow>
1336
1337 1. Delete the flow created.
1338
1339 | **HTTP request**
1340
1341 ::
1342
1343     Operation: DELETE
1344     URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
1345
1346 | **HTTP response**
1347
1348 ::
1349
1350     Status: 200 OK
1351
1352 Websocket change event notification subscription tutorial
1353 ---------------------------------------------------------
1354
1355 Subscribing to data change notifications makes it possible to obtain
1356 notifications about data manipulation (insert, change, delete) which are
1357 done on any specified **path** of any specified **datastore** with
1358 specific **scope**. In following examples *{odlAddress}* is address of
1359 server where ODL is running and *{odlPort}* is port on which
1360 OpenDaylight is running.
1361
1362 Websocket notifications subscription process
1363 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1364
1365 In this section we will learn what steps need to be taken in order to
1366 successfully subscribe to data change event notifications.
1367
1368 Create stream
1369 ^^^^^^^^^^^^^
1370
1371 In order to use event notifications you first need to call RPC that
1372 creates notification stream that you can later listen to. You need to
1373 provide three parameters to this RPC:
1374
1375 -  **path**: data store path that you plan to listen to. You can
1376    register listener on containers, lists and leaves.
1377
1378 -  **datastore**: data store type. *OPERATIONAL* or *CONFIGURATION*.
1379
1380 -  **scope**: Represents scope of data change. Possible options are:
1381
1382    -  BASE: only changes directly to the data tree node specified in the
1383       path will be reported
1384
1385    -  ONE: changes to the node and to direct child nodes will be
1386       reported
1387
1388    -  SUBTREE: changes anywhere in the subtree starting at the node will
1389       be reported
1390
1391 The RPC to create the stream can be invoked via RESCONF like this:
1392
1393 -  URI:
1394    http://{odlAddress}:{odlPort}/restconf/operations/sal-remote:create-data-change-event-subscription
1395
1396 -  HEADER: Content-Type=application/json
1397
1398 -  OPERATION: POST
1399
1400 -  DATA:
1401
1402    .. code:: json
1403
1404        {
1405            "input": {
1406                "path": "/toaster:toaster/toaster:toasterStatus",
1407                "sal-remote-augment:datastore": "OPERATIONAL",
1408                "sal-remote-augment:scope": "ONE"
1409            }
1410        }
1411
1412 The response should look something like this:
1413
1414 .. code:: json
1415
1416     {
1417         "output": {
1418             "stream-name": "data-change-event-subscription/toaster:toaster/toaster:toasterStatus/datastore=CONFIGURATION/scope=SUBTREE"
1419         }
1420     }
1421
1422 **stream-name** is important because you will need to use it when you
1423 subscribe to the stream in the next step.
1424
1425 .. note::
1426
1427     Internally, this will create a new listener for *stream-name* if it
1428     did not already exist.
1429
1430 Subscribe to stream
1431 ^^^^^^^^^^^^^^^^^^^
1432
1433 In order to subscribe to stream and obtain WebSocket location you need
1434 to call *GET* on your stream path. The URI should generally be
1435 http://{odlAddress}:{odlPort}/restconf/streams/stream/{streamName},
1436 where *{streamName}* is the *stream-name* parameter contained in
1437 response from *create-data-change-event-subscription* RPC from the
1438 previous step.
1439
1440 -  URI:
1441    http://{odlAddress}:{odlPort}/restconf/streams/stream/data-change-event-subscription/toaster:toaster/datastore=CONFIGURATION/scope=SUBTREE
1442
1443 -  OPERATION: GET
1444
1445 The subscription call may be modified with the following query parameters defined in the RESTCONF RFC:
1446
1447 -  `filter <https://tools.ietf.org/html/draft-ietf-netconf-restconf-05#section-4.8.6>`__
1448
1449 -  `start-time <https://tools.ietf.org/html/draft-ietf-netconf-restconf-05#section-4.8.7>`__
1450
1451 -  `end-time <https://tools.ietf.org/html/draft-ietf-netconf-restconf-05#section-4.8.8>`__
1452
1453 In addition, the following ODL extension query parameter is supported:
1454
1455 :odl-leaf-nodes-only:
1456   If this parameter is set to "true", create and update notifications will only
1457   contain the leaf nodes modified instead of the entire subscription subtree.
1458   This can help in reducing the size of the notifications.
1459
1460 The expected response status is 200 OK and response body should be
1461 empty. You will get your WebSocket location from **Location** header of
1462 response. For example in our particular toaster example location header
1463 would have this value:
1464 *ws://{odlAddress}:8185/toaster:toaster/datastore=CONFIGURATION/scope=SUBTREE*
1465
1466 .. note::
1467
1468     During this phase there is an internal check for to see if a
1469     listener for the *stream-name* from the URI exists. If not, new a
1470     new listener is registered with the DOM data broker.
1471
1472 Receive notifications
1473 ^^^^^^^^^^^^^^^^^^^^^
1474
1475 You should now have a data change notification stream created and have
1476 location of a WebSocket. You can use this WebSocket to listen to data
1477 change notifications. To listen to notifications you can use a
1478 JavaScript client or if you are using chrome browser you can use the
1479 `Simple WebSocket
1480 Client <https://chrome.google.com/webstore/detail/simple-websocket-client/pfdhoblngboilpfeibdedpjgfnlcodoo>`__.
1481
1482 Also, for testing purposes, there is simple Java application named
1483 WebSocketClient. The application is placed in the
1484 *-sal-rest-connector-classes.class* project. It accepts a WebSocket URI
1485 as and input parameter. After starting the utility (WebSocketClient
1486 class directly in Eclipse/InteliJ Idea) received notifications should be
1487 displayed in console.
1488
1489 Notifications are always in XML format and look like this:
1490
1491 .. code:: xml
1492
1493     <notification xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
1494         <eventTime>2014-09-11T09:58:23+02:00</eventTime>
1495         <data-changed-notification xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote">
1496             <data-change-event>
1497                 <path xmlns:meae="http://netconfcentral.org/ns/toaster">/meae:toaster</path>
1498                 <operation>updated</operation>
1499                 <data>
1500                    <!-- updated data -->
1501                 </data>
1502             </data-change-event>
1503         </data-changed-notification>
1504     </notification>
1505
1506 Example use case
1507 ~~~~~~~~~~~~~~~~
1508
1509 The typical use case is listening to data change events to update web
1510 page data in real-time. In this tutorial we will be using toaster as the
1511 base.
1512
1513 When you call *make-toast* RPC, it sets *toasterStatus* to "down" to
1514 reflect that the toaster is busy making toast. When it finishes,
1515 *toasterStatus* is set to "up" again. We will listen to this toaster
1516 status changes in data store and will reflect it on our web page in
1517 real-time thanks to WebSocket data change notification.
1518
1519 Simple javascript client implementation
1520 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1521
1522 We will create simple JavaScript web application that will listen
1523 updates on *toasterStatus* leaf and update some element of our web page
1524 according to new toaster status state.
1525
1526 Create stream
1527 ^^^^^^^^^^^^^
1528
1529 First you need to create stream that you are planing to subscribe to.
1530 This can be achieved by invoking "create-data-change-event-subscription"
1531 RPC on RESTCONF via AJAX request. You need to provide data store
1532 **path** that you plan to listen on, **data store type** and **scope**.
1533 If the request is successful you can extract the **stream-name** from
1534 the response and use that to subscribe to the newly created stream. The
1535 *{username}* and *{password}* fields represent your credentials that you
1536 use to connect to OpenDaylight via RESTCONF:
1537
1538 .. note::
1539
1540     The default user name and password are "admin".
1541
1542 .. code:: javascript
1543
1544     function createStream() {
1545         $.ajax(
1546             {
1547                 url: 'http://{odlAddress}:{odlPort}/restconf/operations/sal-remote:create-data-change-event-subscription',
1548                 type: 'POST',
1549                 headers: {
1550                   'Authorization': 'Basic ' + btoa('{username}:{password}'),
1551                   'Content-Type': 'application/json'
1552                 },
1553                 data: JSON.stringify(
1554                     {
1555                         'input': {
1556                             'path': '/toaster:toaster/toaster:toasterStatus',
1557                             'sal-remote-augment:datastore': 'OPERATIONAL',
1558                             'sal-remote-augment:scope': 'ONE'
1559                         }
1560                     }
1561                 )
1562             }).done(function (data) {
1563                 // this function will be called when ajax call is executed successfully
1564                 subscribeToStream(data.output['stream-name']);
1565             }).fail(function (data) {
1566                 // this function will be called when ajax call fails
1567                 console.log("Create stream call unsuccessful");
1568             })
1569     }
1570
1571 Subscribe to stream
1572 ^^^^^^^^^^^^^^^^^^^
1573
1574 The Next step is to subscribe to the stream. To subscribe to the stream
1575 you need to call *GET* on
1576 *http://{odlAddress}:{odlPort}/restconf/streams/stream/{stream-name}*.
1577 If the call is successful, you get WebSocket address for this stream in
1578 **Location** parameter inside response header. You can get response
1579 header by calling *getResponseHeader(\ *Location*)* on HttpRequest
1580 object inside *done()* function call:
1581
1582 .. code:: javascript
1583
1584     function subscribeToStream(streamName) {
1585         $.ajax(
1586             {
1587                 url: 'http://{odlAddress}:{odlPort}/restconf/streams/stream/' + streamName;
1588                 type: 'GET',
1589                 headers: {
1590                   'Authorization': 'Basic ' + btoa('{username}:{password}'),
1591                 }
1592             }
1593         ).done(function (data, textStatus, httpReq) {
1594             // we need function that has http request object parameter in order to access response headers.
1595             listenToNotifications(httpReq.getResponseHeader('Location'));
1596         }).fail(function (data) {
1597             console.log("Subscribe to stream call unsuccessful");
1598         });
1599     }
1600
1601 Receive notifications
1602 ^^^^^^^^^^^^^^^^^^^^^
1603
1604 Once you got WebSocket server location you can now connect to it and
1605 start receiving data change events. You need to define functions that
1606 will handle events on WebSocket. In order to process incoming events
1607 from OpenDaylight you need to provide a function that will handle
1608 *onmessage* events. The function must have one parameter that represents
1609 the received event object. The event data will be stored in
1610 *event.data*. The data will be in an XML format that you can then easily
1611 parse using jQuery.
1612
1613 .. code:: javascript
1614
1615     function listenToNotifications(socketLocation) {
1616         try {
1617             var notificatinSocket = new WebSocket(socketLocation);
1618
1619             notificatinSocket.onmessage = function (event) {
1620                 // we process our received event here
1621                 console.log('Received toaster data change event.');
1622                 $($.parseXML(event.data)).find('data-change-event').each(
1623                     function (index) {
1624                         var operation = $(this).find('operation').text();
1625                         if (operation == 'updated') {
1626                             // toaster status was updated so we call function that gets the value of toasterStatus leaf
1627                             updateToasterStatus();
1628                             return false;
1629                         }
1630                     }
1631                 );
1632             }
1633             notificatinSocket.onerror = function (error) {
1634                 console.log("Socket error: " + error);
1635             }
1636             notificatinSocket.onopen = function (event) {
1637                 console.log("Socket connection opened.");
1638             }
1639             notificatinSocket.onclose = function (event) {
1640                 console.log("Socket connection closed.");
1641             }
1642             // if there is a problem on socket creation we get exception (i.e. when socket address is incorrect)
1643         } catch(e) {
1644             alert("Error when creating WebSocket" + e );
1645         }
1646     }
1647
1648 The *updateToasterStatus()* function represents function that calls
1649 *GET* on the path that was modified and sets toaster status in some web
1650 page element according to received data. After the WebSocket connection
1651 has been established you can test events by calling make-toast RPC via
1652 RESTCONF.
1653
1654 .. note::
1655
1656     for more information about WebSockets in JavaScript visit `Writing
1657     WebSocket client
1658     applications <https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications>`__
1659
1660 Config Subsystem
1661 ----------------
1662
1663 Overview
1664 ~~~~~~~~
1665
1666 The Controller configuration operation has three stages:
1667
1668 -  First, a Proposed configuration is created. Its target is to replace
1669    the old configuration.
1670
1671 -  Second, the Proposed configuration is validated, and then committed.
1672    If it passes validation successfully, the Proposed configuration
1673    state will be changed to Validated.
1674
1675 -  Finally, a Validated configuration can be Committed, and the affected
1676    modules can be reconfigured.
1677
1678 In fact, each configuration operation is wrapped in a transaction. Once
1679 a transaction is created, it can be configured, that is to say, a user
1680 can abort the transaction during this stage. After the transaction
1681 configuration is done, it is committed to the validation stage. In this
1682 stage, the validation procedures are invoked. If one or more validations
1683 fail, the transaction can be reconfigured. Upon success, the second
1684 phase commit is invoked. If this commit is successful, the transaction
1685 enters the last stage, committed. After that, the desired modules are
1686 reconfigured. If the second phase commit fails, it means that the
1687 transaction is unhealthy - basically, a new configuration instance
1688 creation failed, and the application can be in an inconsistent state.
1689
1690 .. figure:: ./images/configuration.jpg
1691    :alt: Configuration states
1692
1693    Configuration states
1694
1695 .. figure:: ./images/Transaction.jpg
1696    :alt: Transaction states
1697
1698    Transaction states
1699
1700 Validation
1701 ~~~~~~~~~~
1702
1703 To secure the consistency and safety of the new configuration and to
1704 avoid conflicts, the configuration validation process is necessary.
1705 Usually, validation checks the input parameters of a new configuration,
1706 and mostly verifies module-specific relationships. The validation
1707 procedure results in a decision on whether the proposed configuration is
1708 healthy.
1709
1710 Dependency resolver
1711 ~~~~~~~~~~~~~~~~~~~
1712
1713 Since there can be dependencies between modules, a change in a module
1714 configuration can affect the state of other modules. Therefore, we need
1715 to verify whether dependencies on other modules can be resolved. The
1716 Dependency Resolver acts in a manner similar to dependency injectors.
1717 Basically, a dependency tree is built.
1718
1719 APIs and SPIs
1720 ~~~~~~~~~~~~~
1721
1722 This section describes configuration system APIs and SPIs.
1723
1724 SPIs
1725 ^^^^
1726
1727 **Module** org.opendaylight.controller.config.spi. Module is the common
1728 interface for all modules: every module must implement it. The module is
1729 designated to hold configuration attributes, validate them, and create
1730 instances of service based on the attributes. This instance must
1731 implement the AutoCloseable interface, owing to resources clean up. If
1732 the module was created from an already running instance, it contains an
1733 old instance of the module. A module can implement multiple services. If
1734 the module depends on other modules, setters need to be annotated with
1735 @RequireInterface.
1736
1737 **Module creation**
1738
1739 1. The module needs to be configured, set with all required attributes.
1740
1741 2. The module is then moved to the commit stage for validation. If the
1742    validation fails, the module attributes can be reconfigured.
1743    Otherwise, a new instance is either created, or an old instance is
1744    reconfigured. A module instance is identified by ModuleIdentifier,
1745    consisting of the factory name and instance name.
1746
1747 | **ModuleFactory** org.opendaylight.controller.config.spi. The
1748   ModuleFactory interface must be implemented by each module factory.
1749 | A module factory can create a new module instance in two ways:
1750
1751 -  From an existing module instance
1752
1753 -  | An entirely new instance
1754    | ModuleFactory can also return default modules, useful for
1755      populating registry with already existing configurations. A module
1756      factory implementation must have a globally unique name.
1757
1758 APIs
1759 ^^^^
1760
1761 +--------------------------------------+--------------------------------------+
1762 | ConfigRegistry                       | Represents functionality provided by |
1763 |                                      | a configuration transaction (create, |
1764 |                                      | destroy module, validate, or abort   |
1765 |                                      | transaction).                        |
1766 +--------------------------------------+--------------------------------------+
1767 | ConfigTransactionController          | Represents functionality for         |
1768 |                                      | manipulating with configuration      |
1769 |                                      | transactions (begin, commit config). |
1770 +--------------------------------------+--------------------------------------+
1771 | RuntimeBeanRegistratorAwareConfiBean | The module implementing this         |
1772 |                                      | interface will receive               |
1773 |                                      | RuntimeBeanRegistrator before        |
1774 |                                      | getInstance is invoked.              |
1775 +--------------------------------------+--------------------------------------+
1776
1777 Runtime APIs
1778 ^^^^^^^^^^^^
1779
1780 +--------------------------------------+--------------------------------------+
1781 | RuntimeBean                          | Common interface for all runtime     |
1782 |                                      | beans                                |
1783 +--------------------------------------+--------------------------------------+
1784 | RootRuntimeBeanRegistrator           | Represents functionality for root    |
1785 |                                      | runtime bean registration, which     |
1786 |                                      | subsequently allows hierarchical     |
1787 |                                      | registrations                        |
1788 +--------------------------------------+--------------------------------------+
1789 | HierarchicalRuntimeBeanRegistration  | Represents functionality for runtime |
1790 |                                      | bean registration and                |
1791 |                                      | unreregistration from hierarchy      |
1792 +--------------------------------------+--------------------------------------+
1793
1794 JMX APIs
1795 ^^^^^^^^
1796
1797 | JMX API is purposed as a transition between the Client API and the JMX
1798   platform.
1799
1800 +--------------------------------------+--------------------------------------+
1801 | ConfigTransactionControllerMXBean    | Extends ConfigTransactionController, |
1802 |                                      | executed by Jolokia clients on       |
1803 |                                      | configuration transaction.           |
1804 +--------------------------------------+--------------------------------------+
1805 | ConfigRegistryMXBean                 | Represents entry point of            |
1806 |                                      | configuration management for         |
1807 |                                      | MXBeans.                             |
1808 +--------------------------------------+--------------------------------------+
1809 | Object names                         | Object Name is the pattern used in   |
1810 |                                      | JMX to locate JMX beans. It consists |
1811 |                                      | of domain and key properties (at     |
1812 |                                      | least one key-value pair). Domain is |
1813 |                                      | defined as                           |
1814 |                                      | "org.opendaylight.controller". The   |
1815 |                                      | only mandatory property is "type".   |
1816 +--------------------------------------+--------------------------------------+
1817
1818 Use case scenarios
1819 ^^^^^^^^^^^^^^^^^^
1820
1821 | A few samples of successful and unsuccessful transaction scenarios
1822   follow:
1823
1824 **Successful commit scenario**
1825
1826 1.  The user creates a transaction calling creteTransaction() method on
1827     ConfigRegistry.
1828
1829 2.  ConfigRegisty creates a transaction controller, and registers the
1830     transaction as a new bean.
1831
1832 3.  Runtime configurations are copied to the transaction. The user can
1833     create modules and set their attributes.
1834
1835 4.  The configuration transaction is to be committed.
1836
1837 5.  The validation process is performed.
1838
1839 6.  After successful validation, the second phase commit begins.
1840
1841 7.  Modules proposed to be destroyed are destroyed, and their service
1842     instances are closed.
1843
1844 8.  Runtime beans are set to registrator.
1845
1846 9.  The transaction controller invokes the method getInstance on each
1847     module.
1848
1849 10. The transaction is committed, and resources are either closed or
1850     released.
1851
1852 | **Validation failure scenario**
1853 | The transaction is the same as the previous case until the validation
1854   process.
1855
1856 1. If validation fails, (that is to day, illegal input attributes values
1857    or dependency resolver failure), the validationException is thrown
1858    and exposed to the user.
1859
1860 2. The user can decide to reconfigure the transaction and commit again,
1861    or abort the current transaction.
1862
1863 3. On aborted transactions, TransactionController and JMXRegistrator are
1864    properly closed.
1865
1866 4. Unregistration event is sent to ConfigRegistry.
1867
1868 Default module instances
1869 ^^^^^^^^^^^^^^^^^^^^^^^^
1870
1871 The configuration subsystem provides a way for modules to create default
1872 instances. A default instance is an instance of a module, that is
1873 created at the module bundle start-up (module becomes visible for
1874 configuration subsystem, for example, its bundle is activated in the
1875 OSGi environment). By default, no default instances are produced.
1876
1877 The default instance does not differ from instances created later in the
1878 module life-cycle. The only difference is that the configuration for the
1879 default instance cannot be provided by the configuration subsystem. The
1880 module has to acquire the configuration for these instances on its own.
1881 It can be acquired from, for example, environment variables. After the
1882 creation of a default instance, it acts as a regular instance and fully
1883 participates in the configuration subsystem (It can be reconfigured or
1884 deleted in following transactions.).
1885