2 Robert Varga <rovarga@cisco.com>
3 :rfc6020: https://tools.ietf.org/html/rfc6020
4 :mdsal-apidoc: https://nexus.opendaylight.org/content/sites/site/org.opendaylight.mdsal/boron/apidocs/org/opendaylight/mdsal/dom/api/
13 The instatiated logical tree representing configuration or operational state
14 data of modeled problem domain (e.g controller, network)
17 Component acting on data, after this data are introduced into particular
18 subtree(s) of Data Tree.
20 Data Tree Identifier::
21 A unique identifier for a particular subtree of Data Tree. It is composed of
22 the logical data store type and the instance identifier of the root node.
23 It is represented by `DOMDataTreeIdentifier`.
26 Component responsible for providing data for particular subtree(s) of Data Tree.
29 Component responsible for providing storage or access to particular subtree
33 Longest-prefix mapping between Data Tree Identifiers and Data Tree Shards
34 responsible for providing access to data subtree.
39 === Data Tree is a Namespace
40 The concept of a data tree comes from {rfc6020}[RFC6020]. It is is vaguely split
41 into two instances, configuration and operational. The implicit assumption is that
42 *config implies oper*, e.g. any configuration data is also valid operational data.
43 Further interactions between the two are left undefined and YANG language is not
44 strictly extensible in the number and semantics of these instances, leaving
45 a lot to implementation details. An outline of use, consistent with current
46 MD-SAL design, is outlined in
47 https://tools.ietf.org/html/draft-kwatsen-netmod-opstate[draft-kwatsen-netmod-opstate].
49 OpenDaylight MD-SAL design makes no inherent assumptions about config/oper
50 relationship, treating them as separate entities and making them fully
51 addressable (via `DOMDataTreeIdentifier`). It is up to MD-SAL plugins (e.g. protocol
52 plugins, applications) to maintain this relationship. This reflects
53 the asynchronous nature of applying configuration and also the fact that
54 intended configuration data may be subject to translation (such as template
55 configuration instantiation).
57 Each of configuration and operational spaces are instances of the Conceptual Data Tree.
58 Any data item in the conceptual data tree is addressed via `YangInstanceIdentifier`,
59 which is a hierarchical. content-based, unique identifier. All applications
60 identify data using these identifiers to MD-SAL services, which are expect
61 to perform proper namespace management such that logical operation connectivity
64 === Identifiers versus Locators
65 It is important to note that when we talk about Identifiers and Locators,
67 https://en.wikipedia.org/wiki/Uniform_Resource_Identifier[URIs and URLs],
68 but rather URNs and URLs as strictly separate entities. MD-SAL plugins do not
69 have access to locators and it is the job of MD-SAL services to provide location
72 Exact details on how a particular MD-SAL service achieves location independence
73 is currently left up to the implementation, which leads to the problem of having
74 MD-SAL service cooperate, such as storing data in different backends (in-memory,
75 SQL, NoSQL, etc.) and providing unified access to all available data. Note that
76 data availability is subject to capabilities of the storage engine and its
77 operational state, which leads to the design decision that `YangInstanceIdentifier`
78 needs to be performed in two steps:
80 . a longest-prefix match is performed to locate the storage backend instance for
82 . masked path elements are resolved by the storage backend.
85 A process similar to the first step is performed today by the Distributed Data Store
86 implementation to split data into Shards. The concept of a shard as currently
87 implemented is limited to specifying namespaces and does not allow pluggable
90 In the context of the conceptual data tree, the Shard concept is generalized
91 as the shorthad equivalent of a storage backend instance. Shards can be attached
92 at any (even wildcard) `YangInstanceIdentifier`. This contract is exposed via
93 the `DOMShardedDataTree`, which is an MD-SAL SPI class implementing
94 an `YangInstanceIdentifier` -> `Shard` registry service. This is an omnipresent
95 MD-SAL service, Shard Registry, whose visibility scope is a single
96 OpenDaylight instance (e.g. a cluster member). *Shard Layout* is used to refer
97 to the mapping information contained in this service.
99 === Federation, Replication and High Availability
101 Support for various multi-node scenarios is a concern outside of core MD-SAL.
102 If a particular scenario requires the shard layout to be replicated (either
103 fully or partially), it is up to the Shard providers to maintain an omnipresent
104 service on each node, which in turn is responsible for dynamically registering
105 `DOMDataTreeShard` instances with Shard Registry.
107 Since the Shard Layout is strictly local to a particular OpenDaylight instance,
108 an OpenDaylight cluster is geared towards being asymmetric with each node
109 serving its own view of the data. This allows each node to project its local
110 operational details, as well as partitioning of the data set being worked on
111 based on workload and node availability. Partial symmetry of the conceptual
112 data tree can still be maintained to the extent that a particular deployment
118 ==== Data Tree Listener
120 Data Tree Listener is data consumer, e.g. process wanting to act on data
121 after it has been introduced to the conceptual data tree.
123 Data Tree Listener implements {mdsal-apidoc}DOMDataTreeListener.html[DOMDataTreeListener]
124 interface and registers itself using {mdsal-apidoc}DOMDataTreeService.html[DOMDataTreeService].
126 Data Tree Listener may register for multiple subtrees and each time it is invoked
127 it will be provided with current state of all subtrees, it is listening for.
130 // FIXME: Consider linking / inlining interface
132 .DOMDataTreeListener interface signature
135 public interface DOMDataTreeListener extends EventListener {
137 void onDataTreeChanged(Collection<DataTreeCandidate> changes, // (1)
138 Map<DOMDataTreeIdentifier, NormalizedNode<?, ?>> subtrees);
140 void onDataTreeFailed(Collection<DOMDataTreeListeningException> causes); // (2)
143 <1> Invoked when subscribed data tree changed. `changes` contains collection
144 of changes, `subtrees` contains current state of all subtrees to which
145 listener is registered.
146 <2> Invoked when a subtree listening failure occurs. This can be triggered,
147 for example, when a connection to external subtree source is broken.
150 ==== Data Tree Producer
152 Data Tree Producer represents source of data in system.
153 Producer implementations are not required to implement specific interface, but
154 uses a {mdsal-apidoc}DOMDataTreeProducer.html[DOMDataTreeProducer] instance
155 to publish data (modify conceptual data tree).
157 Data Tree Producer is exclusively bound to subtree(s) of Conceptual Data Tree,
158 which prevents other producers to modify same subtree.
160 * Failed Data Tree Producer still holds namespace claim (exclusive lock of subtree)
163 {mdsal-apidoc}DOMDataTreeProducer.html[DOMDataTreeProducer] Represents Data producer context
165 * allows transactions to be submitted to the subtrees specified at creation time
166 * at any given time there may be a single transaction open.
167 * once a transaction is submitted, it will proceed to be committed asynchronously.
171 // FIXME: Consider linking / inlining interface
173 .DOMDataTreeProducer interface signature
176 public interface DOMDataTreeProducer extends DOMDataTreeProducerFactory, AutoCloseable {
177 DOMDataWriteTransaction createTransaction(boolean isolated); // (1)
178 DOMDataTreeProducer createProducer(Collection<DOMDataTreeIdentifier> subtrees); // (2)
181 <1> Allocates new transaction, all transactions previously allocated must have
182 been either submitted or canceled. Setting `isolated` to `true` disables
183 state compression for this transaction.
184 <2> Creates sub-producer for provided `subtrees`, parent producer loses the
185 ability to access the specified paths until the resulting (child) producer
191 - *Data Tree Shard* is always bound to either `OPERATIONAL`, or `CONFIG` space, never combined.
193 - *Data Tree Shards* may be nested, parent shard must be aware of sub-shards and
194 has to execute every request in the context of a self-consistent view
195 of sub-shards liveness. Data requests passing through it need to be multiplexed
196 with sub-shard creation/deletion.
198 - *Shard Layout* is local to OpenDaylight instance.
200 - *Shard Layout* is modified by agents (registering / unregistering Data Tree Shards)
201 in order to make Data Tree Shard and underlaying data available to local instance
204 ==== Registering Shard
206 NOTE: Namespace in this context means Data Tree Identifier prefix
208 . *Claim namespace* - Agent registering shard must prove that it has sufficient
209 rights to modify subtree where shard is going to be attached.
210 Namespace claim is realized by having Data Tree Producer instance which is
211 bound to same subtree as shard, and producer must not have any open child
212 producers and should not have any outstanding transactions.
214 . *Create shard instance* - Once namespace is claimed, agent creates
216 . *Attach shard* - Agent registers created shard instance along with providing
217 Data Tree Producer instance to verify namespace claim. Shard is verified if it
218 is able to cooperate with parent shard and then it is attached to parent shard
220 . *Remove namespace claim* (optional) - If shard is providing storage for applications,
221 agent should close Data Tree Producer instance in order to make subtree available
224 IMPORTANT: Step 1, 2 and 3 may fail and recovery strategy depends
225 on step which failed and failure reason.
227 // FIXME: Describe possible failures and recovery scenarios