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