moving developers-guide to developer-guide for consistency
[docs.git] / manuals / developer-guide / src / main / asciidoc / controller.adoc
1 == Controller
2
3 === OpenDaylight Controller: MD-SAL Developers' Guide
4
5 Model-Driven SAL (MD-SAL) is a set of infrastructure services aimed at providing common and generic support to application and plugin developers. 
6
7 MD-SAL currently provides infrastructure services for the following: 
8
9 * Data Services 
10 * RPC or Service routing 
11 * Notification subscription and publish services 
12
13 This model-driven infrastructure allows developers to develop applications and plugins against an API type of their choice (Java generated APIs, DOM APIs, REST APIs). The infrastructure automatically provides the other API types. 
14 The modelling language of choice for MD-SAL is YANG, which is an IETF standard, for modelling network element configuration. The YANGTools project and its development tools provide support for YANG.
15
16
17 === API types
18
19 MD-SAL provides three API types: + 
20
21 * Java generated APIs for consumers and producers 
22 * DOM APIs: Mostly used by infrastucture components and usuful for XML-driven plugin and application types 
23 * REST APIs: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf[Restconf] that is available to consumer type applications and provides access to RPC and data stores 
24
25
26 === Basic YANG concepts and their rendition in APIs
27
28 The following are the basic concepts in YANG modeling: +
29
30 * Remote Procedure (RPCs): In MD-SAL, RPCs are used for any call or invocation that crosses the plugin or module boundaries. RPCs are triggered by consumers, and usually have return values.
31 * Notifications: Asynchronous events, published by components for listeners.
32 * Configuration and Operational Data tree: The well-defined (by model) tree structure that represents the operational state of components and systems.
33 ** Instance Identifier: The path that uniquely identifies the sub-tree in the configuration or operational space. Most of the addressing of data is done by Instance Identifier.
34
35 ==== RPC
36 In YANG, Remote Procedure Calls (RPCs) are used to model any procedure call implemented by a Provider (Server), which exposes functionality to Consumers (Clients).
37
38 In MD-SAL terminology, the term 'RPC' is used to define the input and output for a procedure (function) that is to be provided by a Provider, and adapted by the MD-SAL.
39
40 In the context of the MD-SAL, there are three types of RPCs (RPC services): +
41
42 * Global: One service instance (implementation) per controller container or mount point
43 * Routed: Multiple service instances (implementations) per controller container or mount point
44
45 ==== Global service 
46
47 * There is only one instance of a Global Service per controller instance. (Note that a controller instance can consist of a cluster of controller nodes.)
48
49 *Routing* +
50
51 * Binding-Aware MD-SAL (sal-binding)
52 ** **Rpc Type**: Identified by a generated RpcService class and a name of a method invoked on that interface
53 * Binding-Independent MD-SAL (sal-dom)
54 ** **Rpc Type**: Identified by a QName
55
56 ==== Routed service ====
57
58 * There can be multiple instances (implementations) of a service per controller instance 
59 * Can be used for southbound plugins or for horizontal scaling (load-balancing) of northbound plugins (services) 
60
61 *Routing* +
62
63 Routing is done based on the contents of a message, for example, 'Node Reference'. The field in a message that is used for routing is specified in a YANG model by using the routing-reference statement from the yang-ext model. + 
64
65 * Binding Aware MD-SAL (sal-binding)
66 * RPC Type: Identified by an RpcService subclass and the name of the method invoked on that interface
67 * Instance Identifier: In a data tree, identifies the element instance that will be used as the route target. 
68 The used class is: +
69 ----
70 org.opendaylight.yang.binding.InstanceIdentifier
71 ----       
72
73 The Instance Identifier is learned from the message payload and from the model. +
74
75 * Binding Independent MD-SAL (sal-dom)
76 * RPC Type: Identified by a QName
77
78 * Instance Identifier: In a data tree, identifies the element instance that will be used as the route target. The used class is: +
79 ----
80 org.opendaylight.yang.data.api.InstanceIdentifier
81 ----
82 RPCs in various API types: +
83
84 * Java Generated APIs: For each model there is *Service interface. See https://wiki.opendaylight.org/view/YANG_Tools:YANG_to_Java_Mapping#Rpc[YANG Tools: Yang to Java mapping-RPC]  to understand how YANG statements maps to Service interface.
85 ** Providers expose their implementation of *Service by registering their implementation to RpcProviderRegistry.
86 ** Consumers get the *Service implementation from RpcConsumerRegistry. If the implementer uses a different API type, MD-SAL automatically translates data in the background.
87 * DOM APIs: RPCs are identified by QName.
88 ** Providers expose their implementation of RPC identified by QName registering their RpcImplementation to RpcProvisionRegistry.
89 ** Consumers get the *Service implementation from RpcConsumerRegistry. If the implementer uses different API type, MD-SAL automatically translates data in the background.
90 * REST APIs: RPCs are identified by the model name and their name.
91 * Consumers invoke RPCs by invoking POST operation to /restconf/operations/model-name:rpc-name.
92
93 ==== Notification 
94 In YANG, Notifications represent asynchronous events, published by providers for listeners.
95
96 RPCs in various API types: +
97
98 * Java Generated APIs: For each model, there is *Listener interface and transfer object for each notification. See https://wiki.opendaylight.org/view/YANG_Tools:YANG_to_Java_Mapping#Notification[YANG Tools: Yang to Java mapping-Notification] to understand how YANG statements map to the Notifications interface.
99 ** Providers publish notifications by invoking the publish method on NotificationPublishService.
100 ** To receive notifications, consumers register their implementation of *Listener to NotificationBrokerService. If the notification publisher uses a different API type, MD-SAL automatically translates data in the background.
101 * DOM APIs: Notifications are represented only by XML Payload.
102 ** Providers publish notifications by invoking the publish method on NotificationPublishService.
103 ** To receive notifications, consumers register their implementation of *Listener to NotificationBrokerService. If the notification publisher uses a different API type, MD-SAL automatically translates data in the background.
104 * REST APIs: Notifications are currently not supported.
105
106 ==== Instance Identifier
107
108 The Instance Identifier is the unique identifier of an element (location) in the yang data tree: basically, it is the *path* to the node that uniquely identifies all the parent nodes of the node. The unique identification of list elements requires the specification of key values as well.
109
110 MD-SAL currently provides three different APIs to access data in the common data store: +
111
112 * Binding APIs (Java generated DTOs)
113 * DOM APIs
114 * https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf[OpenDaylight Controller:MD-SAL Restconf APIs]
115  
116 *Example* +
117
118 Consider the following simple YANG model for inventory: +
119 ----
120 module inventory {
121     namespace "urn:opendaylight:inventory";
122     prefix inv;
123     revision "2013-06-07";
124     container nodes {
125         list node {
126             key "id";
127             leaf "id" {
128                 type "string";
129             }
130         }
131     }
132 }
133 ----
134 *An example having one instance of node with the name _foo_* +
135
136 Let us assume that we want to create an instance identifier for the node foo in the following bindings or formats: +
137
138
139 *  **YANG / XML / XPath version**
140 ----
141 /inv:nodes/inv:node[id="foo"]
142 ----
143 * **Binding-Aware version (generated APIs)**
144 ----
145 import org.opendaylight.yang.gen.urn.opendaylight.inventory.rev130607.Nodes;
146 import org.opendaylight.yang.gen.urn.opendaylight.inventory.rev130607.nodes.Node;
147 import org.opendaylight.yang.gen.urn.opendaylight.inventory.rev130607.nodes.NodeKey;
148
149 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
150
151 InstanceIdentifier<Node> identifier = InstanceIdentifier.builder(Nodes.class).child(Node.class,new NodeKey("foo")).toInstance();
152 ----
153 NOTE: The last call, _toInstance()_ does not return an instance of the node, but the Java version of Instance identifier which uniquely identifies the node *foo*.
154
155 * **HTTP Restconf APIs** +
156 ----
157 http://localhost:8080/restconf/config/inventory:nodes/node/foo
158 ----
159 NOTE: We assume that HTTP APIs are exposed on localhost, port 8080.
160
161 * **Binding Independent version (yang-data-api)**
162 ----
163 import org.opendaylight.yang.common.QName;
164 import org.opendaylight.yang.data.api.InstanceIdentifier;
165
166 QName nodes = QName.create("urn:opendaylight:inventory","2013-06-07","nodes");
167 QName node = QName.create(nodes,"nodes");
168 QName idName = QName.create(nodes,"id");
169 InstanceIdentifier = InstanceIdentifier.builder()
170     .node(nodes)
171     .nodeWithKey(node,idName,"foo")
172     .toInstance();
173 ----
174 NOTE: The last call, _toInstance()_ does not return an instance of node, but the Java version of Instance identifier which uniquely identifies the node *foo*.
175
176 === MD-SAL: Plugin types
177 MD-SAL has four component-types that differ in complexity, expose different models, and use different subsets of the MD-SAL functionality.
178
179 * Southbound Protocol Plugin: Responsible for handling multiple sessions to the southbound network devices and providing common abstracted interface to access various type of functionality provided by these network devices
180 * Manager-type application: Responsible for managing the state and the configuration of a particular functionality which is exposed by southbound protocol plugins
181 * Protocol Library: Responsible for handling serialization or de-serialization between the wire protocol format and the Java form of the protocol 
182 * Connector Plugin: Responsible for connecting consumers (and providers) to Model-driven SAL (and other components) by means of different wire protocol or set of APIs
183
184 ==== Southbound protocol plugin
185
186 The responsibilities of the Southbound Protocol plugin include the following :
187
188 * Handling multiple sessions to southbound network devices
189 * Providing a common abstracted interface to access various type of functionality provided by the network devices
190
191 The Southbound Protocol Plugin should be stateless. The only preserved state (which is still transient) is the list of connected devices or sessions. Models mostly use RPCs and Notifications to describe plugin functionality
192 Example plugins: Openflow Southbound Plugin, Netconf Southbound Plugin, BGP Southbound Plugin, and PCEP Southbound Plugin.
193
194 ==== Manager-type application
195
196 The responsibilities of the Manager-type applications include the following:
197
198 * Providing configuration-like functionality to set or modify the behaviour of network elements or southbound plugins
199 * Coordinating flows and provide higher logic on top of stateless southbound plugins
200
201 Manager-type Applications preserve state. Models mostly use Configuration Data and Runtime Data to describe component functionality.
202
203 === Protocol library
204 The OpenFlow Protocol Library is a component in OpenDaylight, that mediates communication between the OpenDaylight controller and the hardware devices supporting the OpenFlow protocol. The primary goal of the library is to provide user (or upper layers of OpenDaylight) communication channel, that can be used for managing network hardware devices. 
205
206 === MD-SAL: Southbound plugin development guide 
207 The southbound controller plugin is a functional component. 
208
209 The plugin: +
210
211 * Provides an abstraction of network devices functionality
212 * Normalizes their APIs to common contracts
213 * Handles session and connections to them
214
215 The plugin development process generally moves through the following phases: +
216
217 . Definition of YANG models (API contracts): For Model-Driven SAL, the API contracts are defined by YANG models and the Java interfaces generated for these models. A developers opts for one of the following: +
218 ** Selects from existing models
219 ** Creates new models 
220 ** Augments (extends) existing models
221 [start=2]
222 . Code Generation: The Java Interfaces, implementation of Transfer Objects, and mapping to Binding-Independent form is generated for the plugin. This phase requires the proper configuration of the Maven build and YANG Maven Tools.
223 . Implementation of plugin: The actual implementation of the plugin functionality and plugin components.
224
225 NOTE: The order of steps is not definitive, and it is up to the developer to find the most suitable workflow. For additional information, see <<_best_practices>>.
226
227 === Definition of YANG models
228
229 In this phase, the developer selects from existing models (provided by controller or other plugins), writes new models, or augments existing ones. A partial list of available models could be found at:
230 https://wiki.opendaylight.org/view/YANG_Tools:Available_Models[YANG Tools:Available Models].
231
232 The mapping of YANG to Java is documented at: https://wiki.opendaylight.org/view/Yang_Tools:YANG_to_Java_Mapping[Yang Tools:YANG to Java Mapping.] This mapping provides an overview of how YANG is mapped to Java.
233
234 Multiple approaches to model the functionality of the southbound plugin are available: +
235
236 * Using RPCs and Notifications
237 * Using Configuration Data Description
238 * Using Runtime Data Description
239 * Combining approaches
240
241 === RPCs
242
243 RPCs can model the functionality invoked by consumers (applications) that use the southbound plugin. Although RPCs can model any functionality, they are usually used to model functionality that cannot be abstracted as configuration data, for example, PacketOut, or initiating a new session to a device (controller-to-device session).
244
245 RPCs are modeled with an RPC statement in the following form: +
246 +rpc foo {}+ +
247 This statement is mapped to method. +
248
249 *RPC input* +
250 To define RPC input, use an input statement inside RPC. The structure of the input is defined with the same statements as the structure of notifications, configuration, and so on.
251 ----
252  rpc foo {
253     input {
254        ...
255     }
256  }
257 ----
258 *RPC output* +
259 To define the RPC output (structure of result), use the RPC output statement. +
260 ----
261  rpc foo {
262    output {
263       ...
264    }
265  }
266 ----
267 *Notifications* +
268 Use notifications to model events originating in a network device or southbound plugin which is exposed to consumers to listen.
269
270
271 A notification statement defines a notification:
272 ----
273    notification foo {
274       ...
275    }
276 ----
277 *Configuration data* +
278
279 Configuration data is good for the following purposes: +
280
281 * Model or provide CRUD access to the state of protocol plugin and/or network devices 
282 * Model any functionality which could be exposed as a configuration to the consumers or applications
283
284 Configuration data in YANG is defined by using the config substatement with a true argument. For example: +
285 ----
286   container foo {
287      config true;
288      ...
289   }
290 ----
291 *Runtime (read-only) data* +
292 Runtime (read-only) data is good to model or provide read access to the state of the protocol plugin and networtk devices, or network devices. This type of data is good to model statistics or any state data, which cannot be modified by the consumers (applications), but needs exposure (for example, learned topology, or list of connected switches).
293
294 Runtime data in YANG is defined by using config subsatement with a false argument:
295 ----
296   container foo {
297      config false;
298   }
299 ----
300 *Structural elements* +
301 The structure of RPCs, notifications, configuration data, and runtime data is modelled using structural elements (data schema nodes). Structural elements define the actual structure of XML, DataDOM documents, and Java APIs for accessing or storing these elements. The most commonly used structural elements are: +
302
303 * Container
304 * List
305 * Leaf
306 * Leaf-list
307 * Choice
308
309 === Augmentations +
310 Augmentations are used to extend existing models by providing additional structural elements and semantics. Augmentation cannot change the mandatory status of nodes in the original model, or introduce any new mandatory statements.
311
312 === Best practices
313
314 * YANG models must be located under the src/main/yang folder in your project.
315 * Design your models so that they are reusable and extendible by third-parties.
316 * Always try to reuse existing models and types provided by these models. See https://wiki.opendaylight.org/view/YANG_Tools:Available_Models[YANG Tools:Available Models] or others if there is no model which provides you with data structures and types you need.
317
318 *Code generation* +
319 To configure your project for code generation, your build system needs to use Maven. For the configuration of java API generation, see https://wiki.opendaylight.org/view/Yang_Tools:Maven_Plugin_Guide[Yang Tools:Maven Plugin Guide].
320
321 *Artefacts generated at compile time* +
322 The following artefacts are generated at compile time: +
323
324 * Service interfaces
325 * Transfer object interfaces
326 * Builders for transfer objects and immutable versions of transfer objects
327
328 === Implementation +
329 This step uses generated artefacts to implement the intended functionality of the southbound plugin. +
330
331 *Provider implementation* +
332 To expose functionality through binding-awareness, the MD-SAL plugin needs to be compiled against these APIs, and must at least implement the BindingAwareProvider interface.
333 The provider uses APIs which are available in the SAL-binding-api Maven artifact. To use this dependency, insert the following dependency into your pom.xml:
334 ----
335 <dependency>
336        <groupId>org.opendaylight.controller</groupId>
337        <artifactId>sal-binding-api</artifactId>
338        <version>1.0-SNAPSHOT</version>
339    </dependency>
340 ----
341
342 *BindingAwareProvider implementation* +
343 A BindingAwareProvider interface requires the implementation of four methods, and registering an instance with BindingAwareBroker. Use AbstractBindingAwareProvider to simplify the implementation.
344
345 * void onSessionInitialized(ConsumerContext ctx): This callback is called when Binding-Aware Provider is initialized and ConsumerContext is injected into it. ConsumerContext serves to access all functionality which the plugin is to consume from other controller components.
346 * void onSessionInitialized(ProviderContext ctx): This callback is called when Binding-Aware Provider is initialized and ProviderContext is injected into it. ProviderContext serves to access all functionality which the plugin could use to provide its functionality to controller components.
347 * Collection<? extends RpcService> getImplementations(): Shorthand registration of an already instantiated implementations of global RPC services. Automated registration is currently not supported.
348 * public Collection<? extends ProviderFunctionality> getFunctionality(): Shorthand registration of an already instantiated implementations of ProviderFunctionality. Automated registration is currently not supported.
349 NOTE: You also need to set your implementation of AbstractBindingAwareProvider set as Bundle Activator for MD-SAL to properly load it.
350
351 === Notifications 
352 To publish events, request an instance of NotificationProviderService from ProviderContext. Use the following:
353 ----
354    ExampleNotification notification = (new ExampleNotificationBuilder()).build();
355    NotificationProviderService notificationProvider = providerContext.getSALService(NotificationProviderService.class);
356    notificationProvider.notify(notification);
357 ----
358 *RPC implementations* +
359 To implement the functionality exposed as RPCs, implement the generated RpcService interface. Register the implementation within ProviderContext included in the provider.
360
361 If the generated RpcInterface is FooService, and the implementation is FooServiceImpl:
362 ----
363    @Override
364    public void onSessionInitiated(ProviderContext context) {
365        context.addRpcImplementation(FooService.class, new FooServiceImpl());
366    }
367 ----
368 === Best practices
369
370 RPC Service interface contract requires you to return http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html[Future object] (to make it obvious that call may be asynchronous), but it is not specified how this Future is implemented. Consider using existing implementations provided by JDK or Google Guava. Implement your own Future only if necessary.
371
372 Consider using http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/util/concurrent/SettableFuture.html[SettableFuture] if you intend not to use http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html[FutureTask] or submit http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html[Callables] to http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html[ExecutorService].
373
374 IMPORTANT: Do not implement transfer object interfaces unless necessary. Choose already generated builders and immutable versions. If you want to implement transfer objects, ensure that instances exposed outside the plugin are immutable.
375
376 === OpenDaylight Controller: MD-SAL FAQs
377
378 *Q-1: What is the overall MD-SAL architecture?*
379
380 * **What is the overall architecture, components, and functionality?** 
381 * **Who supplies which components, and how are the components plumbed?**
382
383 *A-1:* The overall Model-Driven SAL (MD-SAL) architecture did not really change from the API-Driven SAL (AD-SAL). As with the AD-SAL, plugins can be data providers, or data consumers, or both (although the AD-SAL did not explicitly name them as such). Just like the AD-SAL, the MD-SAL connects data consumers to appropriate data providers and (optionally) facilitates data adaptation between them. 
384
385 Now, in the AD-SAL, the SAL APIs request routing between consumers and providers, and data adaptations are all statically defined at compile or build time. In the MD-SAL, the SAL APIs and request routing between consumers and providers are defined from models, and data adaptations are provided by 'internal' adaptation plugins. The API code is generated from models when a plugin is compiled. When the plugin OSGI bundle is loaded into the controller, the API code is loaded into the controller along with the rest of the plugin containing the model.
386
387 .AD-SAL and MD-SAL
388 image::MD-SAL.png[]
389
390 The AD-SAL provides request routing (selects an SB plugin based on service type) and optionally provides service adaptation, if an NB (Service, abstract) API is different from its corresponding SB (protocol) API. For example, in the above figure, the AD-SAL routes requests from NB-Plugin 1 to SB Plugins 1 and 2. Note that the plugin SB and NB APIs in this example are essentially the same (although both of them need to be defined). Request routing is based on plugin type: the SAL knows which node instance is served by which plugin. When an NB Plugin requests an operation on a given node, the request is routed to the appropriate plugin which then routes the request to the appropriate node. The AD-SAL can also provide service abstractions and adaptations. For example, in the above figure, NB Plugin 2 is using an abstract API to access the services provided by SB Plugins 1 and 2. The translation between the SB Plugin API and the abstract NB API is done in the Abstraction module in the AD-SAL.
391
392 The MD-SAL provides request routing and the infrastructure to support service adaptation. However, it does not provide service adaptation itself: service adaptation is provided by plugins. From the point of view of MD-SAL, the Adaptation Plugin is a regular plugin. It provides data to the SAL, and consumes data from the SAL through APIs generated from models. An Adaptation Plugin basically performs model-to-model translations between two APIs. Request Routing in the MD-SAL is done on both protocol type and node instances, since node instance data is exported from the plugin into the SAL (the model data contains routing information). 
393
394 The simplest MD-SAL APIs generated from models (RPCs and Notifications, both supported in the yang modeling language) are functionally equivalent to AD-SAL function call APIs. Additionally, the MD-SAL can store data for models defined by plugins. Provider and consumer plugins can exchange data through the MD-SAL storage. Data in the MD-SAL is accessed through getter and setter APIs generated from models. Note that this is in contrast to the AD-SAL, which is stateless.
395
396 Note that in the above figure, both NB AD-SAL Plugins provide REST APIs to controller client applications.
397
398 The functionality provided by the MD-SAL is basically to facilitate the plumbing between providers and consumers. A provider or a consumer can register itself with the MD-SAL. A consumer can find a provider that it is interested in. A provider can generate notifications; a consumer can receive notifications and issue RPCs to get data from providers. A provider can insert data into SAL storage; a consumer can read data from SAL storage. 
399
400 Note that the structure of SAL APIs is different in the MD-SAL from that in the AD-SAL. The AD-SAL typically has both NB and SB APIs even for functions or services that are mapped 1:1 between SB Plugins and NB Plugins. For example, in the current AD-SAL implementation of the OpenFlow Plugin and applications, the NB SAL APIs used by OF applications are mapped 1:1 onto SB OF Plugin APIs. The MD-SAL allows both the NB plugins and SB plugins to use the same API generated from a model. One plugin becomes an API (service) provider; the other becomes an API (service) Consumer. This eliminates the need to define two different APIs and to provide three different implementations even for cases where APIs are mapped to each other 1:1. The MD SAL provides instance-based request routing between multiple provider plugins. 
401
402 *Q-2: What functionality does the MD-SAL assume? For example, does the SAL assume that the network model is a part of the SAL?*
403
404 *A-2:* The MD-SAL does not assume any model. All models are provided by plugins. The MD-SAL only provides the infrastructure and the plumbing for the plugins.
405
406
407 *Q-3: What is the "day in the life" of an MD-SAL plugin?*
408
409
410 *A-3:* All plugins (protocol, application, adaptation, and others) have the same lifecycle. The life of a plugin has two distinct phases: design and operation. + 
411 During the design phase, the plugin designer performs the following actions:  +
412
413 * The designer decides which data will be consumed by the plugin, and imports the SAL APIs generated from the API provider’s models. Note that the topology model is just one possible data type that may be consumed by a plugin. The list of currently available data models and their APIs can be found in YANG_Tools:Available_Models. 
414 * The designer decides which data and how it will be provided by the plugin, and designs the data model for the provided data. The data model (expressed in yang) is then run through the https://wiki.opendaylight.org/view/YANG_Tools:Available_Models[YANG Tools], which generate the SAL APIs for the model. 
415 * The implementations for the generated consumer and provider APIs, along with other plugin features and functionality, are developed. The resulting code is packaged in a “plugin” OSGI bundle. Note that a developer may package the code of a subsystem in multiple plugins or applications that may communicate with each other through the SAL. 
416 * The generated APIs and a set of helper classes are also built and packaged in an “API” OSGI bundle. 
417
418 The plugin development process is shown in the following figure. +
419
420 .Plugin development process
421 image::plugin-dev-process.png[]
422
423 When the OSGI bundle of a plugin is loaded into the controller and activated, the operation phase begins. The plugin operation is probably best explained with a few examples describing the operation of the OF Protocol plugin and OF applications, such as the Flow Programmer Service, the ARP Handler, or the Topology Manager. The following figure shows a scenario where a “Flow Deleted” notification from a switch arrives at the controller.
424
425 .Flow deleted at controller
426 image::flow-deleted-at-controller.png[]
427
428 The scenario is as follows: +
429
430 . The Flow Programmer Service registers with the MD SAL for the `Flow Deleted' notification. This is done when the Controller and its plugins or applications are started. 
431 . A `Flow Deleted' OF packet arrives at the controller. The OF Library receives the packet on the TCP/TLS connection to the sending switch, and passes it to the OF Plugin. 
432 . The OF Plugin parses the packet, and uses the parsed data to create a `Flow Deleted' SAL notification. The notification is actually an immutable `Flow Deleted' Data Transfer Object (DTO) that is created or populated by means of methods from the model-generated OF Plugin API. 
433 . The OF Plugin sends the `Flow Deleted' SAL notification (containing the notification DTO) into the SAL. The SAL routes the notification to registered consumers, in this case, the Flow Programmer Service. 
434 . The Flow Programmer Service receives the notification containing the notification DTO. 
435 . The Flow Programmer Service uses methods from the API of the model-generated OF Plugin to get data from the immutable notification DTO received in Step 5. The processing is the same as in the AD-SAL. 
436
437 Note that other packet-in scenarios, where a switch punts a packet to the controller, such as an ARP or an LLDP packet, are similar. Interested applications register for the respective notifications. The OF plugin generates the notification from received OF packets, and sends them to the SAL. The SAL routes the notifications to the registered recipients. +
438 The following figure shows a scenario where an external application adds a flow by means of the NB REST API of the controller. 
439
440 .External app adds flow
441 image::md-sal-faqs-add_flow.png[]
442
443 The scenario is as follows: +
444
445 . Registrations are performed when the Controller and its plugins or applications are started. 
446
447 .. The Flow Programmer Service registers with the MD SAL for Flow configuration data notifications.
448 .. The OF Plugin registers (among others) the ‘AddFlow’ RPC implementation with the SAL. 
449 Note that the RPC is defined in the OF Plugin model, and the API is generated during build time. + 
450 [start=2]
451 . A client application requests a flow add through the REST API of the Controller. (Note that in the AD-SAL, there is a dedicated NB REST API on top of the Flow Programming Service. The MD-SAL provides a common infrastructure where data and functions defined in models can be accessed by means of a common REST API. For more information, see http://datatracker.ietf.org/doc/draft-bierman-netconf-restconf/). The client application provides all parameters for the flow in the REST call. 
452 . Data from the ‘Add Flow’ request is deserialized, and a new flow is created in the Flow Service configuration data tree. (Note that in this example the configuration and operational data trees are separated; this may be different for other services). Note also that the REST call returns success to the caller as soon as the flow data is written to the configuration data tree. 
453 . Since the Flow Programmer Service is registered to receive notifications for data changes in the Flow Service data tree, the MD-SAL generates a ‘data changed’ notification to the Flow Programmer Service. 
454 . The Flow Programmer Service reads the newly added flow, and performs a flow add operation (which is basically the same as in the AD-SAL). 
455 . At some point during the flow addition operation, the Flow Programmer Service needs to tell the OF Plugin to add the flow in the appropriate switch. The Flow Programmer Service uses the OF Plugin generated API to create the RPC input parameter DTO for the “AddFlow” RPC of the OF Plugin. 
456 . The Flow Programmer Service gets the service instance (actually, a proxy), and invokes the “AddFlow” RPC on the service. The MD-SAL will route the request to the appropriate OF Plugin (which implements the requested RPC). 
457 . The `AddFlow' RPC request is routed to the OF Plugin, and the implementation method of the “AddFlow” RPC is invoked. 
458 . The `AddFlow' RPC implementation uses the OF Plugin API to read values from the DTO of the RPC input parameter. (Note that the implementation will use the getter methods of the DTO generated from the yang model of the RPC to read the values from the received DTO.) 
459 . The `AddFlow' RPC is further processed (pretty much the same as in the AD-SAL) and at some point, the corresponding flowmod is sent to the corresponding switch. 
460
461 *Q-4: Is there a document that describes how code is generated from the models for the MD-SAL?*
462
463 *A-4:* https://wiki.opendaylight.org/view/YANG_Tools:YANG_to_Java_Mapping[Yangtools] documents the Yang to Java generation, including examples of how the yang constructs are mapped into Java classes. You can write unit tests against the generated code. You will have to write implementations of the generated RPC interfaces. The generated code is just Java, and it debugs just like Java. 
464
465 If you want to play with generating Java from Yang there is a maven archetype to help you get going: https://wiki.opendaylight.org/view/Maven_Archetypes:odl-model-project[Maven Archetypes: ODL Model Project]. +
466 Or, you can try creating a project in Eclipse as explained at: http://sdntutorials.com/yang-to-java-conversion-how-to-create-maven-project-in-eclipse/[YANG to Java conversion: How to create Maven project in Eclipse]. 
467
468 *Q-5: The code generation tools mention 'producers' and consumers'. How are these related to 'southbound' and 'northbound SAL plugins?*
469
470 *A-5:* The difference between southbound and northbound plugins is that the southbound plugins talk protocols to network nodes, and northbound plugins talk application APIs to the controller applications. As far as the SAL is concerned, there is really no north or south. The SAL is basically a data exchange and adaptation mechanism between plugins. The plugin SAL roles (consumer or producer) are defined with respect to the data being moved around or stored by the SAL. A producer implements an API, and provides the data of the API: a consumer uses the API, and consumes the data of the API. +
471 While 'northbound' and 'southbound' provide a network engineer's view of the SAL, 'consumer' and 'producer' provide a software engineer's view of the SAL, and is shown in the following figure: 
472
473 .SAL consumer and producer view
474
475 image::mdsal-sal-sw-eng.png[]
476
477 *Q-6: Where can I find models that have already been defined in OpenDaylight?*
478
479 *A-6:* The list of models that have been defined for the SAL and in various plugins can be found in https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Model_Reference[MD-SAL Model Reference].
480
481 *Q-7: How do I migrate my existing plugins and services to MD-SAL?*
482
483 *A-7:* The migration guide can be found in the https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Application_Migration_Guide[MD-SAL Application Migration Guide].
484
485 *Q-8: Where can I find SAL example code?*
486
487 *A-8:* The toaster sample provides a simple yet complete example of a model, a service provider (toaster), and a service consumer. It provides the model of a programmable toaster, a sample consumer application that uses MD-SAL APIs; a sample southbound plugin (a service provider) that implements toaster; and a unit test suite. 
488
489 The toaster example is in _controller.git_ under _opendaylight/md-sal/samples_.
490
491 *Q-9: Where is the REST API code for the example?*
492
493 *A-9:* The REST APIs are derived from models. You do not have to write any code for it. The controller will implement the http://datatracker.ietf.org/doc/draft-bierman-netconf-restconf/[RESTCONF protocol] which defines access to yang-formatted data through REST. Basically, all you need to do is define your service in a model, and expose that model to the SAL. REST access to your modeled data will then be provided by the SAL infrastructure. However, if you want to, you can create your own REST API (for example, to be compliant with an existing API). 
494
495 *Q-10: How can one use RESTCONF to access the MD-SAL datastore?*
496
497 *A-10:* For information on accessing the MD-SAL datastore, see https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Restconf[MD-SAL Restconf].
498  
499 === OpenDaylight Controller Configuration: Java Code Generator
500
501 ==== YANG to Java code generator
502
503 The Java code for the configuration system is generated by the yang-maven-plugin and the yang-jmx-generator-plugin. 
504 The input Yang module files are converted to java files by the definition of the module and the specified templates. the generated java code can represent interfaces, classes, or abstract classes used for configuration. 
505
506 === Service interfaces generating
507
508 Service interfaces (SI) are generated from YANG "service-types". Each SI must be defined as "identity" with a "base" statement set to "config:service-type", or another SI. This is because a service must have a globally unique name.
509  Each SI must be annotated with @ServiceInterfaceAnnotation, and must extend AbstractServiceInterface. 
510
511 *Sample YANG module representing service interface* +
512  
513 ----
514 module config-test {
515     yang-version 1;
516     namespace "urn:opendaylight:params:xml:ns:yang:controller:test";
517     prefix "test";
518  
519     import config { prefix config; revision-date 2013-04-05; }
520  
521     description
522         "Testing API";
523  
524     revision "2013-06-13" {
525         description
526             "Initial revision";
527     }
528  
529     identity testing {
530         description
531             "Test api";
532  
533         base "config:service-type";
534         config:java-class "java.lang.AutoCloseable";
535     }
536 }
537 ----
538 The "description" node of identity is generated as javadoc in the service interface. +
539 The "config:java-class" is generated as *ServiceInterfaceAnnotation*. It specifies java classes or interfaces in the "osgiRegistrationTypes" parameter. The module implementing this service interface must instantiate a java object that can be cast to any of the java types defined in "osgiRegistrationTypes".
540
541 *Generated java source file: AutoCloseableServiceInterface* +
542 ----
543 package %prefix%.test;
544  
545 /**
546 * Test api
547 */
548 @org.opendaylight.controller.config.api.annotations.Description(value = "Test api")
549 @org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation(value = "testing", osgiRegistrationType = java.lang.AutoCloseable.class)
550 public interface AutoCloseableServiceInterface extends org.opendaylight.controller.config.api.annotations.AbstractServiceInterface
551 {
552  
553 }
554 ---- 
555
556 ==== Module stubs generating
557
558 Modules are constructed during configuration transaction. A module implements the ModuleMXBean interface. The ModuleMXBean interface represents getters and setters for attributes that will be exposed to the configuration registry by means of JMX. Attributes can either be simple types, or composite types.
559
560 Each ModuleMXBean must be defined in yang as "identity" with the base statement set to "config:module-type". Not only are ModuleMXBeans generated, but also ModuleFactory and Module stubs. Both are first generated as abstract classes with almost full functionality. Then their implementations, which are allowed to be modified by users, are generated, but only once. 
561
562 === Runtime beans generating
563
564 Runtime JMX beans are purposed to be the auditors: they capture data about running module instances. A module can have zero or more runtime beans. Runtime beans are hierarchically ordered, and each must be uniquely identified. 
565  A runtime bean is defined as a configuration augment of a module, from which interface RuntimeMXBean, RuntimeRegistrator, and RuntimeRegistretion are generated. Augment definition contains arguments representing the data of a module that must be watched. 
566
567 ==== RPCs
568
569 Method calls in yang must be specified as top level elements. The context, where an RPC operation exits, must be defined in the RPC definition itself, and in the runtime bean that provides method implementation.
570
571 === OpenDaylight Controller MD-SAL: Restconf
572
573 ==== Restconf operations overview
574
575 Restconf allows access to datastores in the controller. +
576 There are two datastores: +
577
578 * Config: Contains data inserted via controller 
579 * Operational: Contains other data 
580
581 NOTE: Each request must start with the URI /restconf. + 
582 Restconf listens on port 8080 for HTTP requests.
583
584 Restconf supports *OPTIONS*, *GET*, *PUT*, *POST*, and *DELETE* operations. Request and response data can either be in the XML or JSON format. XML structures according to yang are defined at: http://tools.ietf.org/html/rfc6020[XML-YANG]. JSON structures are defined at: http://tools.ietf.org/html/draft-lhotka-netmod-yang-json-02[JSON-YANG]. Data in the request must have a correctly set *Content-Type* field in the http header with the allowed value of the media type. The media type of the requested data has to be set in the *Accept* field. Get the media types for each resource by calling the OPTIONS operation. 
585 Most of the paths of the pathsRestconf endpoints use https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Concepts#Instance_Identifier[Instance Identifier]. +<identifier>+ is used in the explanation of the operations. 
586
587 *<identifier>* +
588
589 * It must start with <moduleName>:<nodeName> where <moduleName> is a name of the module and <nodeName> is the name of a node in the module. It is sufficient to just use <nodeName> after <moduleName>:<nodeName>. Each <nodeName> has to be separated by /. 
590 * <nodeName> can represent a data node which is a list or container yang built-in type. If the data node is a list, there must be defined keys of the list behind the data node name for example, <nodeName>/<valueOfKey1>/<valueOfKey2>. 
591 * The format <moduleName>:<nodeName> has to be used in this case as well: + 
592 Module A has node A1. Module B augments node A1 by adding node X. Module C augments node A1 by adding node X. For clarity, it has to be known which node is X (for example: C:X). 
593 For more details about encoding, see: http://tools.ietf.org/html/draft-bierman-netconf-restconf-02#section-5.3.1[Restconf 02 - Encoding YANG Instance Identifiers in the Request URI.] 
594
595 === Mount point
596 A Node can be behind a mount point. In this case, the URI has to be in format <identifier>/*yang-ext:mount*/<identifier>. The first <identifier> is the path to a mount point and the second <identifier> is the path to a node behind the mount point. A URI can end in a mount point itself by using <identifier>/*yang-ext:mount*. +
597 More information on how to actually use mountpoints is available at: https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:Netconf[ OpenDaylight Controller:Config:Examples:Netconf].
598
599 ==== HTTP methods
600
601 ===== OPTIONS /restconf +
602  
603 * Returns the XML description of the resources with the required request and response media types in Web Application Description Language (WADL) 
604
605 ===== GET /restconf/config/<identifier> +
606
607 * Returns a data node from the Config datastore. 
608 * <identifier> points to a data node which must be retrieved. 
609
610 ===== GET /restconf/operational/<identifier> +
611
612 * Returns the value of the data node from the Operational datastore. 
613 * <identifier> points to a data node which must be retrieved. 
614
615 ===== PUT /restconf/config/<identifier>
616
617 * Updates or creates data in the Config datastore and returns the state about success. 
618 * <identifier> points to a data node which must be stored.
619
620 *Example:* +
621 ---- 
622 PUT http://<controllerIP>:8080/restconf/config/module1:foo/bar
623 Content-Type: applicaton/xml
624 <bar>
625   …
626 </bar>
627 ----
628 *Example with mount point:* +
629 ---- 
630 PUT http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo/bar
631 Content-Type: applicaton/xml
632 <bar>
633   …
634 </bar>
635 ----
636 ===== POST /restconf/config
637 * Creates the data if it does not exist 
638
639 For example: +
640 ----
641 POST URL: http://localhost:8080/restconf/config/
642 content-type: application/yang.data+json
643 JSON payload:
644
645    {
646      "toaster:toaster" :
647      {
648        "toaster:toasterManufacturer" : "General Electric",
649        "toaster:toasterModelNumber" : "123",
650        "toaster:toasterStatus" : "up"
651      }
652   }
653 ----
654 ===== POST /restconf/config/<identifier>
655
656 * Creates the data if it does not exist in the Config datastore, and returns the state about success. 
657 * <identifier> points to a data node where data must be stored. 
658 * The root element of data must have the namespace (data are in XML) or module name (data are in JSON.) 
659
660 *Example:* +
661 ----
662 POST http://<controllerIP>:8080/restconf/config/module1:foo
663 Content-Type: applicaton/xml/
664 <bar xmlns=“module1namespace”>
665   …
666 </bar>
667 ----
668 *Example with mount point:*
669 ---- 
670 http://<controllerIP>:8080/restconf/config/module1:foo1/foo2/yang-ext:mount/module2:foo
671 Content-Type: applicaton/xml
672 <bar xmlns=“module2namespace”>
673   …
674 </bar>
675 ----
676 ===== POST /restconf/operations/<moduleName>:<rpcName>
677  
678 * Invokes RPC. 
679 * <moduleName>:<rpcName> - <moduleName> is the name of the module and <rpcName> is the name of the RPC in this module. 
680 * The Root element of the data sent to RPC must have the name “input”. 
681 * The result can be the status code or the retrieved data having the root element “output”. 
682
683 *Example:* +
684 ---- 
685 POST http://<controllerIP>:8080/restconf/operations/module1:fooRpc
686 Content-Type: applicaton/xml
687 Accept: applicaton/xml
688 <input>
689   …
690 </input>
691
692 The answer from the server could be:
693 <output>
694   …
695 </output>
696 ----
697 *An example using a JSON payload:* +
698 ----
699 POST http://localhost:8080/restconf/operations/toaster:make-toast
700 Content-Type: application/yang.data+json
701 {
702   "input" :
703   {
704      "toaster:toasterDoneness" : "10",
705      "toaster:toasterToastType":"wheat-bread" 
706   }
707 }
708 ----
709
710 NOTE: Even though this is a default for the toasterToastType value in the yang, you still need to define it. 
711
712 ===== DELETE /restconf/config/<identifier>
713
714 * Removes the data node in the Config datastore and returns the state about success. 
715 * <identifier> points to a data node which must be removed. 
716
717 More information is available in the http://tools.ietf.org/html/draft-bierman-netconf-restconf-02[Restconf RFC].
718
719 ==== How Restconf works
720 Restconf uses these base classes: +
721
722 InstanceIdentifier:: Represents the path in the data tree 
723 ConsumerSession:: Used for invoking RPCs 
724 DataBrokerService:: Offers manipulation with transactions and reading data from the datastores 
725 SchemaContext:: Holds information about yang modules 
726 MountService:: Returns MountInstance based on the InstanceIdentifier pointing to a mount point 
727 MountInstace:: Contains the SchemaContext behind the mount point 
728 DataSchemaNode:: Provides information about the schema node 
729 SimpleNode:: Possesses the same name as the schema node, and contains the value representing the data node value 
730 CompositeNode:: Can contain CompositeNode-s and SimpleNode-s 
731
732 ==== GET in action
733 Figure 1 shows the GET operation with URI restconf/config/M:N where M is the module name, and N is the node name.
734
735
736 .Get
737 image::Get.png[width=500]
738
739 . The requested URI is translated into the InstanceIdentifier which points to the data node. During this translation, the DataSchemaNode that conforms to the data node is obtained. If the data node is behind the mount point, the MountInstance is obtained as well. 
740 . Restconf asks for the value of the data node from DataBrokerService based on InstanceIdentifier. 
741 . DataBrokerService returns CompositeNode as data. 
742 . StructuredDataToXmlProvider or StructuredDataToJsonProvider is called based on the *Accept* field from the http request. These two providers can transform CompositeNode regarding DataSchemaNode to an XML or JSON document. 
743 . XML or JSON is returned as the answer on the request from the client. 
744
745 ==== PUT in action
746
747 Figure 2 shows the PUT operation with the URI restconf/config/M:N where M is the module name, and N is the node name. Data is sent in the request either in the XML or JSON format.
748
749 .Put
750
751 image::Put.png[width=500] 
752
753 . Input data is sent to JsonToCompositeNodeProvider or XmlToCompositeNodeProvider. The correct provider is selected based on the Content-Type field from the http request. These two providers can transform input data to CompositeNode. However, this CompositeNode does not contain enough information for transactions. 
754 . The requested URI is translated into InstanceIdentifier which points to the data node. DataSchemaNode conforming to the data node is obtained during this translation. If the data node is behind the mount point, the MountInstance is obtained as well. 
755 . CompositeNode can be normalized by adding additional information from DataSchemaNode. 
756 . Restconf begins the transaction, and puts CompositeNode with InstanceIdentifier into it. The response on the request from the client is the status code which depends on the result from the transaction. 
757
758 === Something practical
759
760 . Create a new flow on the switch openflow:1 in table 2. 
761
762 *HTTP request* +
763 ----
764 Operation: POST
765 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2
766 Content-Type: application/xml
767 ----
768 ----
769 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
770 <flow 
771     xmlns="urn:opendaylight:flow:inventory">
772     <strict>false</strict>
773     <instructions>
774         <instruction>
775                 <order>1</order>
776             <apply-actions>
777                 <action>
778                   <order>1</order>
779                     <flood-all-action/>
780                 </action>
781             </apply-actions>
782         </instruction>
783     </instructions>
784     <table_id>2</table_id>
785     <id>111</id>
786     <cookie_mask>10</cookie_mask>
787     <out_port>10</out_port>
788     <installHw>false</installHw>
789     <out_group>2</out_group>
790     <match>
791         <ethernet-match>
792             <ethernet-type>
793                 <type>2048</type>
794             </ethernet-type>
795         </ethernet-match>
796         <ipv4-destination>10.0.0.1/24</ipv4-destination>
797     </match>
798     <hard-timeout>0</hard-timeout>
799     <cookie>10</cookie>
800     <idle-timeout>0</idle-timeout>
801     <flow-name>FooXf22</flow-name>
802     <priority>2</priority>
803     <barrier>false</barrier>
804 </flow>
805 ---- 
806 *HTTP response* +
807 ---- 
808 Status: 204 No Content
809 ----
810 [start=2]
811 . Change _strict_ to _true_ in the previous flow.
812
813 *HTTP request* +
814 ----
815 Operation: PUT
816 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
817 Content-Type: application/xml
818 ----
819 ----
820 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
821 <flow 
822     xmlns="urn:opendaylight:flow:inventory">
823     <strict>true</strict>
824     <instructions>
825         <instruction>
826                 <order>1</order>
827             <apply-actions>
828                 <action>
829                   <order>1</order>
830                     <flood-all-action/>
831                 </action>
832             </apply-actions>
833         </instruction>
834     </instructions>
835     <table_id>2</table_id>
836     <id>111</id>
837     <cookie_mask>10</cookie_mask>
838     <out_port>10</out_port>
839     <installHw>false</installHw>
840     <out_group>2</out_group>
841     <match>
842         <ethernet-match>
843             <ethernet-type>
844                 <type>2048</type>
845             </ethernet-type>
846         </ethernet-match>
847         <ipv4-destination>10.0.0.1/24</ipv4-destination>
848     </match>
849     <hard-timeout>0</hard-timeout>
850     <cookie>10</cookie>
851     <idle-timeout>0</idle-timeout>
852     <flow-name>FooXf22</flow-name>
853     <priority>2</priority>
854     <barrier>false</barrier>
855 </flow>
856 ----
857 *HTTP response* + 
858 ----
859 Status: 200 OK
860 ----
861 [start=3]
862 . Show flow: check that _strict_ is _true_.
863
864 *HTTP request* + 
865 ----
866 Operation: GET
867 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
868 Accept: application/xml
869 ----
870 *HTTP response* + 
871 ----
872 Status: 200 OK
873 ----
874
875 ----
876 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
877 <flow 
878     xmlns="urn:opendaylight:flow:inventory">
879     <strict>true</strict>
880     <instructions>
881         <instruction>
882                 <order>1</order>
883             <apply-actions>
884                 <action>
885                   <order>1</order>
886                     <flood-all-action/>
887                 </action>
888             </apply-actions>
889         </instruction>
890     </instructions>
891     <table_id>2</table_id>
892     <id>111</id>
893     <cookie_mask>10</cookie_mask>
894     <out_port>10</out_port>
895     <installHw>false</installHw>
896     <out_group>2</out_group>
897     <match>
898         <ethernet-match>
899             <ethernet-type>
900                 <type>2048</type>
901             </ethernet-type>
902         </ethernet-match>
903         <ipv4-destination>10.0.0.1/24</ipv4-destination>
904     </match>
905     <hard-timeout>0</hard-timeout>
906     <cookie>10</cookie>
907     <idle-timeout>0</idle-timeout>
908     <flow-name>FooXf22</flow-name>
909     <priority>2</priority>
910     <barrier>false</barrier>
911 </flow>
912 ----
913 [start=4]
914 . Delete the flow created.
915
916 *HTTP request* +
917 ----
918 Operation: DELETE
919 URI: http://192.168.11.1:8080/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/2/flow/111
920 ----
921 *HTTP response* + 
922 ----
923 Status: 200 OK
924 ----
925 === OpenDaylight Controller: Configuration
926 The Controller configuration operation has three stages:
927
928 * First, a Proposed configuration is created. Its target is to replace the old configuration. 
929 * Second, the Proposed configuration is validated, and then committed. If it passes validation successfully, the Proposed configuration state will be changed to Validated. 
930 * Finally, a Validated configuration can be Committed, and the affected modules can be reconfigured.
931
932 In fact, each configuration operation is wrapped in a transaction. Once a transaction is created, it can be configured, that is to say, a user can abort the transaction during this stage. After the transaction configuration is done, it is committed to the validation stage. In this stage, the validation procedures are invoked.
933  If one or more validations fail, the transaction can be reconfigured. Upon success, the second phase commit is invoked. 
934  If this commit is successful, the transaction enters the last stage, committed. After that, the desired modules are reconfigured. If the second phase commit fails, it means that the transaction is unhealthy - basically, a new configuration instance creation failed, and the application can be in an inconsistent state.
935  
936 .Configuration states 
937 image::configuration.jpg[width=500]
938  
939 .Transaction states
940 image::Transaction.jpg[width=500]
941
942 ==== Validation
943 To secure the consistency and safety of the new configuration and to avoid conflicts, the configuration validation process is necessary. 
944 Usually, validation checks the input parameters of a new configuration, and mostly verifies module-specific relationships. 
945 The validation procedure results in a decision on whether the proposed configuration is healthy.
946
947 ==== Dependency resolver
948 Since there can be dependencies between modules, a change in a module configuration can affect the state of other modules. Therefore, we need to verify whether dependencies on other modules can be resolved. 
949 The Dependency Resolver acts in a manner similar to dependency injectors. Basically, a dependency tree is built.
950
951 === APIs and SPIs
952 This section describes configuration system APIs and SPIs.
953
954
955 ==== SPIs
956 *Module* org.opendaylight.controller.config.spi. Module is the common interface for all modules: every module must implement it. The module is designated to hold configuration attributes, validate them, and create instances of service based on the attributes. 
957 This instance must implement the AutoCloseable interface, owing to resources clean up. If the module was created from an already running instance, it contains an old instance of the module. A module can implement multiple services. If the module depends on other modules, setters need to be annotated with @RequireInterface.
958
959 *Module creation* 
960
961 . The module needs to be configured, set with all required attributes. 
962 . The module is then moved to the commit stage for validation. If the validation fails, the module attributes can be reconfigured. Otherwise, a new instance is either created, or an old instance is reconfigured. 
963 A module instance is identified by ModuleIdentifier, consisting of the factory name and instance name.
964
965 *ModuleFactory* org.opendaylight.controller.config.spi. The ModuleFactory interface must be implemented by each module factory. +
966 A module factory can create a new module instance in two ways: +
967
968 * From an existing module instance
969 * An entirely new instance + 
970 ModuleFactory can also return default modules, useful for populating registry with already existing configurations. 
971 A module factory implementation must have a globally unique name.
972
973 ==== APIs
974
975 |===
976 | ConfigRegistry | Represents functionality provided by a configuration transaction (create, destroy module, validate, or abort transaction).
977 | ConfigTransactionController | Represents functionality for manipulating with configuration transactions (begin, commit config).
978 | RuntimeBeanRegistratorAwareConfiBean | The module implementing this interface will receive RuntimeBeanRegistrator before getInstance is invoked.
979 |===
980
981 ==== Runtime APIs
982
983 |===
984 | RuntimeBean | Common interface for all runtime beans
985 | RootRuntimeBeanRegistrator | Represents functionality for root runtime bean registration, which subsequently allows hierarchical registrations
986 | HierarchicalRuntimeBeanRegistration | Represents functionality for runtime bean registration and unreregistration from hierarchy
987 |===
988
989 ==== JMX APIs
990
991 JMX API is purposed as a transition between the Client API and the JMX platform. +
992
993 |===
994 | ConfigTransactionControllerMXBean | Extends ConfigTransactionController, executed by Jolokia clients on configuration transaction.
995 | ConfigRegistryMXBean | Represents entry point of configuration management for MXBeans.
996 | Object names | Object Name is the pattern used in JMX to locate JMX beans. It consists of domain and key properties (at least one key-value pair). Domain is defined as "org.opendaylight.controller". The only mandatory property is "type".
997 |===
998
999 ==== Use case scenarios
1000
1001 A few samples of successful and unsuccessful transaction scenarios follow: +
1002
1003 *Successful commit scenario*
1004
1005 . The user creates a transaction calling creteTransaction() method on ConfigRegistry.
1006 . ConfigRegisty creates a transaction controller, and registers the transaction as a new bean.
1007 . Runtime configurations are copied to the transaction. The user can create modules and set their attributes.
1008 . The configuration transaction is to be committed.
1009 . The validation process is performed.
1010 . After successful validation, the second phase commit begins.
1011 . Modules proposed to be destroyed are destroyed, and their service instances are closed.
1012 . Runtime beans are set to registrator.
1013 . The transaction controller invokes the method getInstance on each module.
1014 . The transaction is committed, and resources are either closed or released.
1015
1016 *Validation failure scenario* +
1017 The transaction is the same as the previous case until the validation process. +
1018
1019 . If validation fails, (that is to day, illegal input attributes values or dependency resolver failure), the validationException is thrown and exposed to the user.
1020 . The user can decide to reconfigure the transaction and commit again, or abort the current transaction.
1021 . On aborted transactions, TransactionController and JMXRegistrator are properly closed.
1022 . Unregistration event is sent to ConfigRegistry.
1023
1024 ==== Default module instances
1025 The configuration subsystem provides a way for modules to create default instances. A default instance is an instance of a module, that is created at the module bundle start-up (module becomes visible for 
1026 configuration subsystem, for example, its bundle is activated in the OSGi environment). By default, no default instances are produced.
1027
1028 The default instance does not differ from instances created later in the module life-cycle. The only difference is that the configuration for the default instance cannot be provided by the configuration subsystem. 
1029 The module has to acquire the configuration for these instances on its own. It can be acquired from, for example, environment variables. 
1030 After the creation of a default instance, it acts as a regular instance and fully participates in the configuration subsystem (It can be reconfigured or deleted in following transactions.).
1031
1032 === OpenDaylight Controller configuration: Initial
1033 The Initial configuration of the controller involves two methods.
1034
1035 === Initial configuration for controller
1036 The two ways of configuring the controller: +
1037
1038 * Using the https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:config.ini[config.ini] property file to pass configuration properties to the OSGi bundles besides the config subsystem. 
1039 * Using the https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Configuration:Initial#Configuration_Persister[configuration persister] to push the initial configuration for modules managed by the config subsystem.
1040
1041 ==== Using the config.ini property file
1042
1043 The config.ini property file can be used to provide a set of properties for any OSGi bundle deployed to the controller. It is usually used to configure bundles that are not managed by the config subsystem. For details, see <<_opendaylight_controller_configuration_config_ini>>.
1044
1045 ==== Using configuration persister
1046
1047 Configuration persister is a default service in the controller, and is started automatically using the OSGi Activator. Its purpose is to load the initial configuration for the config subsystem and store a snapshot for every new configuration state pushed to the config-subsystem from external clients. 
1048 For details, see <<_opendaylight_controller_configuration_persister>>.
1049
1050 === OpenDaylight Controller configuration: config.ini
1051
1052 Various parts of the system that are not under the configuration subsystem use the file config.ini. Changes to this file apply after a server restart. The tabulation of several important configuration keys and values follows: 
1053
1054 [cols="2*", width="75%"]
1055 |===
1056
1057 |Setting | Description
1058 | yangstore.blacklist=.\*controller.model.* | This regular expression (can be OR-ed using pipe character) tells netconf to exclude the yang files found in the matching bundle symbolic name from the hello message. This is helpful when dealing with a netconf client that has parsing problems.
1059 | netconf.config.persister.* settings  | See <<_opendaylight_controller_configuration_initial>>.
1060 | netconf.tcp.address=0.0.0.0 netconf.tcp.port=8383 + 
1061
1062 netconf.ssh.address=0.0.0.0 netconf.ssh.port=1830 netconf.ssh.pk.path = ./configuration/RSA.pk +
1063
1064 netconf.tcp.client.address=127.0.0.1 netconf.tcp.client.port=8383 | These settings specify the netconf server bindings. IP address 0.0.0.0 is used when all available network interfaces must be used by the netconf server. When starting the ssh server, the user must provide a private key. The actual authentication is done in the user admin module. By default, users admin:admin and netconf:netconf can be used to connect by means of ssh. Since the ssh bridge acts as a proxy, one needs to specify the netconf plaintext TCP address and port. These settings must normally be identical to those specified by netconf.tcp.* .
1065 |===
1066 === OpenDaylight Controller: Configuration Persister
1067 One way of configuring the controller is to use the configuration persister to push the initial configuration for modules managed by the config subsystem. 
1068
1069 ==== Using configuration persister
1070
1071 The configuration persister is a default service in the controller, and is started automatically using the OSGi Activator. 
1072 Its purpose: +
1073
1074 * Load the initial configuration for the config subsystem.
1075 * Store a snapshot for every new configuration state pushed to the config-subsystem from external clients. +
1076
1077 It retrieves the base configuration from the config.ini property file, and tries to load the configuration for the config subsystem.
1078 The configuration for the config subsystem is pushed as a set of edit-config netconf rpcs followed by a commit rpc since the config persister acts as a netconf client. 
1079
1080 *Configuration persister lifecycle:* +
1081
1082 . Start the config persister service at _config-persister-impl_ bundle startup. 
1083 . Retrieve the base configuration of the adapters from the config.ini property file. 
1084 . Initialize the backing storage adapters. 
1085 . Initialize the netconf client, and connect to the netconf endpoint of the config subsystem. 
1086 . Load the initial configuration snapshots from the latest storage adapter. 
1087 . Send the edit-config rpc with the initial configuration snapshots. 
1088 . Send the commit rpc. 
1089 . Listen for any of the following changes to the configuration and persist a snapshot. 
1090
1091 *Configuration Persister interactions:* +
1092
1093 .Persister
1094 image::Persister.jpg[width=500]
1095
1096 === Current configuration for controller distribution
1097
1098 The _config.ini_ property file contains the following configuration for the configuration persister: +
1099 ----
1100 netconf.config.persister.active=1,2
1101  
1102 netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.autodetect.AutodetectDirectoryStorageAdapter 
1103
1104 netconf.config.persister.1.properties.directoryStorage=configuration/initial/ 
1105
1106 netconf.config.persister.1.readonly=true 
1107
1108  
1109 netconf.config.persister.2.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.xml.XmlFileStorageAdapter 
1110
1111 netconf.config.persister.2.properties.fileStorage=configuration/current/controller.currentconfig.xml 
1112
1113 netconf.config.persister.2.properties.numberOfBackups=1 
1114 ----
1115
1116 With this configuration, the configuration persister initializes two adapters: +
1117
1118 * AutodetectDirectoryStorageAdapter to load the initial configuration files from the _configuration/initial/_ folder. These files will be pushed as the initial configuration for the config subsystem. Since this adapter is Read only, it will not store any configuration snapshot during the controller lifecycle. 
1119 * XmlFileStorageAdapter to store snapshots of the current configuration after any change in the file _configuration/current/controller.currentconfig.xml_ (Only 1 snapshot backup is kept; every new change overwrites the previous one). +
1120 The initial configuration in the controller distribution consists of 2 files in the https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Configuration:Initial#Persisted_snapshot_format[xml format]. +
1121 * configuration/initial/00-netty.xml: +
1122 ----
1123 <snapshot>
1124     <required-capabilities>
1125         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
1126         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
1127         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&amp;revision=2013-11-07</capability>
1128         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&amp;revision=2013-11-19</capability>
1129     </required-capabilities>
1130     <configuration>
1131  
1132         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
1133             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1134                 <module>
1135                     <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
1136                     <name>global-boss-group</name>
1137                 </module>
1138                 <module>
1139                     <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
1140                     <name>global-worker-group</name>
1141                 </module>
1142                 <module>
1143                     <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
1144                     <name>global-timer</name>
1145                 </module>
1146                 <module>
1147                     <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
1148                     <name>global-event-executor</name>
1149                 </module>
1150             </modules>
1151  
1152             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1153                 <service>
1154                     <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
1155                     <instance>
1156                         <name>global-boss-group</name>
1157                         <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
1158                     </instance>
1159                     <instance>
1160                         <name>global-worker-group</name>
1161                         <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
1162                     </instance>
1163                 </service>
1164                 <service>
1165                     <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
1166                     <instance>
1167                         <name>global-event-executor</name>
1168                         <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
1169                     </instance>
1170                 </service>
1171                 <service>
1172                     <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
1173                     <instance>
1174                         <name>global-timer</name>
1175                         <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
1176                     </instance>
1177                 </service>
1178             </services>
1179         </data>
1180  
1181     </configuration>
1182 </snapshot>
1183 ----
1184 This configuration snapshot instantiates netty utilities, which will be utilized by the controller components that use netty internally. + 
1185
1186 *configuration/initial/01-md-sal.xml:* +
1187 ----
1188 <snapshot>
1189  
1190     <configuration>
1191  
1192         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
1193             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1194                 <module>
1195                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
1196                     <name>yang-schema-service</name>
1197                 </module>
1198                 <module>
1199                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
1200                     <name>hash-map-data-store</name>
1201                 </module>
1202                 <module>
1203                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
1204                     <name>dom-broker</name>
1205                     <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
1206                         <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
1207                         <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
1208                         <name>hash-map-data-store</name>
1209                         <!-- <name>cluster-data-store</name> -->
1210                     </data-store>
1211                 </module>
1212                 <module>
1213                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
1214                     <name>binding-broker-impl</name>
1215                     <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
1216                         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
1217                         <name>binding-notification-broker</name>
1218                     </notification-service>
1219                     <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
1220                         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
1221                         <name>binding-data-broker</name>
1222                     </data-broker>
1223                 </module>
1224                 <module>
1225                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
1226                     <name>runtime-mapping-singleton</name>
1227                 </module>
1228                 <module>
1229                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
1230                     <name>binding-notification-broker</name>
1231                 </module>
1232                 <module>
1233                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
1234                     <name>binding-data-broker</name>
1235                     <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
1236                         <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
1237                         <name>dom-broker</name>
1238                     </dom-broker>
1239                     <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
1240                         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
1241                         <name>runtime-mapping-singleton</name>
1242                     </mapping-service>
1243                 </module>
1244  
1245             </modules>
1246  
1247             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1248                         <service>
1249                                 <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
1250                                 <instance>
1251                                         <name>yang-schema-service</name>
1252                                         <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
1253                                 </instance>
1254                         </service>
1255                         <service>
1256                                 <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
1257                                 <instance>
1258                                         <name>binding-notification-broker</name>
1259                                         <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
1260                                 </instance>
1261                         </service>
1262                         <service>
1263                                 <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
1264                                 <instance>
1265                                         <name>hash-map-data-store</name>
1266                                         <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
1267                                 </instance>
1268                         </service>
1269                         <service>
1270                                 <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
1271                                 <instance>
1272                                         <name>binding-osgi-broker</name>
1273                                         <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
1274                                 </instance>
1275                         </service>
1276                         <service>
1277                                 <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
1278                                 <instance>
1279                                         <name>binding-rpc-broker</name>
1280                                         <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
1281                                 </instance>
1282                         </service>
1283                         <service>
1284                                 <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
1285                                 <instance>
1286                                         <name>runtime-mapping-singleton</name>
1287                                         <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
1288                                 </instance>
1289                         </service>
1290                         <service>
1291                         <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
1292                                 <instance>
1293                                         <name>dom-broker</name>
1294                                         <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
1295                                 </instance>
1296                         </service>
1297                         <service>
1298                                 <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
1299                                 <instance>
1300                                         <name>binding-data-broker</name>
1301                                         <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
1302                                 </instance>
1303                         </service>
1304  
1305             </services>
1306         </data>
1307  
1308     </configuration>
1309  
1310     <required-capabilities>
1311         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
1312         <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&amp;revision=2013-04-09</capability>
1313         <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
1314         <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
1315         <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
1316         <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28</capability>
1317         <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28</capability>
1318     </required-capabilities>
1319  
1320 </snapshot>
1321 ----
1322 This configuration snapshot instantiates md-sal modules. 
1323
1324 After the controller is started, all these modules will be instantiated and configured. They can be further referenced from the new modules as dependencies, reconfigured, or even deleted. 
1325 These modules are considered to be the base configuration for the controller and the purpose of them being configured automatically is to simplify the process of controller configuration for users, since the base modules will already be ready for use.
1326
1327 === Adding custom initial configuration
1328
1329 There are multiple ways to add the custom initial confguration to the controller distribution: 
1330
1331 . Manually create the config file, and put it in the initial configuration folder. 
1332 . Reconfigure the running controller using the yuma yangcli tool. The XmlFileStorageAdapter adapter will store the current snapshot, and on the next startup of the controller (assuming it was not rebuilt since), it will load the configuration containing the changes. 
1333
1334 ==== Custom initial configuration in bgpcep distribution
1335
1336 The BGPCEP project will serve as an example for adding the custom initial configuration. The bgpcep project contains the custom initial configuration that is based on the initial configuration from the controller. It adds new modules, which depend on MD-SAL and netty modules created with the initial config files of the controller. There are multiple config files in the bgpcep project. Only the 30-programming.xml file located under the programming-parent/controller-config project will be described in this section. This file contains the configuration for an instance of the instruction-scheduler module:
1337
1338 ----
1339 <?xml version="1.0" encoding="UTF-8"?>
1340 <!-- vi: set et smarttab sw=4 tabstop=4: -->
1341 <!--
1342       Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
1343  
1344  This program and the accompanying materials are made available under the
1345  terms of the Eclipse Public License v1.0 which accompanies this distribution,
1346  and is available at http://www.eclipse.org/legal/epl-v10.html.
1347 -->
1348 <snapshot>
1349         <required-capabilities>
1350                 <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
1351                 <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
1352                 <capability>urn:opendaylight:params:xml:ns:yang:controller:programming:impl?module=config-programming-impl&amp;revision=2013-11-15</capability>
1353                 <capability>urn:opendaylight:params:xml:ns:yang:controller:programming:spi?module=config-programming-spi&amp;revision=2013-11-15</capability>
1354         </required-capabilities>
1355         <configuration>
1356  
1357                 <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
1358                         <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1359                                 <module>
1360                                         <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:programming:impl">prefix:instruction-scheduler-impl</type>
1361                                         <name>global-instruction-scheduler</name>
1362                                         <data-provider>
1363                                                 <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
1364                                                 <name>binding-data-broker</name>
1365                                         </data-provider>
1366                                         <notification-service>
1367                                                 <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
1368                                                 <name>binding-notification-broker</name>
1369                                         </notification-service>
1370                                         <rpc-registry>
1371                                                 <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
1372                                                 <name>binding-rpc-broker</name>
1373                                         </rpc-registry>
1374                                         <timer>
1375                                                 <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
1376                                                 <name>global-timer</name>
1377                                         </timer>
1378                                 </module>
1379                         </modules>
1380  
1381                         <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1382                                 <service>
1383                                         <type xmlns:pgmspi="urn:opendaylight:params:xml:ns:yang:controller:programming:spi">pgmspi:instruction-scheduler</type>
1384                                         <instance>
1385                                                 <name>global-instruction-scheduler</name>
1386                                                 <provider>/modules/module[type='instruction-scheduler-impl'][name='global-instruction-scheduler']</provider>
1387                                         </instance>
1388                                 </service>
1389                         </services>
1390                 </data>
1391  
1392         </configuration>
1393 </snapshot>
1394 ----
1395 Instruction-scheduler is instantiated as a module of type _instruction-scheduler-impl_ with the name *global-instruction-scheduler:* + 
1396 ----
1397 <module>
1398        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:programming:impl">prefix:instruction-scheduler-impl</type>
1399        <name>global-instruction-scheduler</name>
1400        ...
1401 ----
1402 There is also an alias created for this module instancfe, and the alias is *global-instruction-scheduler* of type _instruction-scheduler_: +
1403 ----
1404 ...
1405 <service>
1406         <type xmlns:pgmspi="urn:opendaylight:params:xml:ns:yang:controller:programming:spi">pgmspi:instruction-scheduler</type>
1407         <instance>
1408                 <name>global-instruction-scheduler</name>
1409                 <provider>/modules/module[type='instruction-scheduler-impl'][name='global-instruction-scheduler']</provider>
1410         </instance>
1411 </service>
1412 ...
1413 ----
1414 The type of the alias is instruction-scheduler. This type refers to a certain service that is implemented by the instruction-scheduler-impl module. With this service type, the global-instruction-scheduler instance can be injected into any other module that requires instruction-scheduler as a dependency. 
1415 One module can provide (implement) multiple services, and each of these services can be assigned an alias. This alias can be later used to reference the implementation it is pointing to. 
1416 If no alias is assigned by the user, a default alias will be assigned for each provided service. 
1417 The default alias is constructed from the name of the module instance with a prefix *ref_* and a possible suffix containing a number to resolve name clashes. 
1418 It is recommended that users provide aliases for each service of every module instance, and use these aliases for dependency injection. References to the alias global-instruction-scheduler can be found in subsequent config files in the bgpcep project for example, _32-pcep.xml_ located under the _pcep-parent/pcep-controller-config_ project. 
1419
1420 The configuration contains four dependencies on the MD-SAL and the netty modules: +
1421 ----
1422 ...
1423 <data-provider>
1424         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
1425         <name>binding-data-broker</name>
1426 </data-provider>
1427 <notification-service>
1428         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
1429         <name>binding-notification-broker</name>
1430 </notification-service>
1431 <rpc-registry>
1432         <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
1433         <name>binding-rpc-broker</name>
1434 </rpc-registry>
1435 <timer>
1436         <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
1437         <name>global-timer</name>
1438 </timer>
1439 ...
1440 ----
1441
1442 MD-SAL dependencies: +
1443
1444 * Data-provider dependency 
1445 * Notification-service dependency 
1446 * Rpc-registry dependency 
1447
1448 All MD-SAL dependencies can be found in the https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Configuration:Initial#Current_configuration_for_controller_distribution[MD-SAL initial configuration file]. For example, rpc-registry dependency points to an alias binding-rpc-broker of the type binding-rpc-registry. This alias further points to an instance of the binding-broker-impl named binding-broker-impl. 
1449 The Yang module that defines the binding-broker-impl module : https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang;a=blob[opendaylight-binding-broker-impl.yang]. 
1450
1451 *Netty dependencies:* +
1452
1453 * Timer dependency 
1454
1455 This configuration expects these dependencies to be already up and ready. It is the responsibility of the configuration subsystem to find the dependency and inject it. 
1456 If the configuration of a module points to a non-existing dependency, the configuration subsystem will produce an exception during the validation phase. 
1457 Every user-created configuration needs to point to existing dependencies. In the case of multiple initial configuration files that depend on one another, the resolution order can be ensured by the names of the files. Files are sorted by their names in ascending order. This means that every configuration file will have the visibility of modules from all previous configuration files by means of aliases.
1458
1459 NOTE: The configuration provided by initial config files can also be pushed to the controller at runtime using netconf client. The whole configuration located under the data tag needs to be inserted into the config tag in the edit-config rpc. For more information, see https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Main#Examples[Examples]. 
1460
1461 ==== Configuration Persister
1462
1463 As a part of the configuration subsystem, the purpose of the persister is to save and load a permanent copy of a configuration. The Persister interface represents basic operations over a storage - persist configuration and load last config, configuration snapshot is represented as string and set of it's capabilities. StorageAdapter represents an adapter interface to the ConfigProvider - subset of BundleContext, allowing access to the OSGi framework system properties. 
1464
1465 ===== Persister implementation
1466
1467 Configuration persister implementation is part of the Controller Netconf. PersisterAggregator class is the implementation of the Presister interface. The functionality is delegated to the storage adapters. Storage adapters are low level persisters that do the heavy lifting for this class. Instances of storage adapters can be injected directly by means of the constructor, or instantiated from a full name of its class provided in a properties file. There can be many persisters configured, and varying numbers of them can be used. 
1468
1469 *Example of presisters configuration:* +
1470 ----
1471 netconf.config.persister.active=2,3
1472  # read startup configuration
1473  netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.xml.XmlDirectoryStorageAdapter
1474  netconf.config.persister.1.properties.fileStorage=configuration/initial/
1475  
1476  netconf.config.persister.2.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter
1477  netconf.config.persister.2.readonly=true
1478  netconf.config.persister.2.properties.fileStorage=configuration/current/controller.config.1.txt
1479  
1480  netconf.config.persister.3.storageAdapterClass=org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter
1481  netconf.config.persister.3.properties.fileStorage=configuration/current/controller.config.2.txt
1482  netconf.config.persister.3.properties.numberOfBackups=3
1483 ----
1484
1485 During server startup, ConfigPersisterNotificationHandler requests the last snapshot from the underlying storages. Each storage can respond by giving a snapshot or an absent response. The PersisterAggregator#loadLastConfigs() will search for the first non-absent response from storages ordered backwards as user specified (first '3', then '2'). When a commit notification is received, '2' will be omitted because the read-only flag is set to true, so only '3' will have a chance to persist the new configuration. 
1486 If read-only was false, or not specified, both storage adapters would be called in the order specified by 'netconf.config.persister' property. 
1487
1488 === Persister Notification Handler
1489
1490 ConfigPersisterNotificationHandler class is responsible for listening for netconf notifications containing the latest committed configuration. 
1491 The listener can handle incoming notifications, or delegates the configuration saving or loading to the persister. 
1492
1493 ==== Storage Adapter implementations
1494
1495 *XML File Storage* +
1496
1497 The XmlFileStorageAdapter implementation stores configuration in an xml file.
1498
1499 *XML Directory Storage* +
1500
1501 XmlDirectoryStorageAdapter retrieves the initial configuration from a directory. If multiple xml files are present, files are ordered based on the file names and pushed in this order (for example, 00.xml, then 01.xml..) Each file defines its required capabilities, so it will be pushed when those capabilities are advertized by ODL. Writing to this persister is not supported. 
1502
1503 *No-Operation Storage* +
1504
1505 NoOpStorageAdapter serves as a dummy implementation of the storage adapter. 
1506
1507 *Obsolete storage adapters* +
1508
1509 * File Storage
1510
1511 * FileStorageAdapter implements StorageAdapter, and provides file based configuration persisting. 
1512 File path and name is stored as a property and a number of stored backups, expressing the count of the last configurations to be persisted too. 
1513 The implementation can handle persisting input configuration, and load the last configuration.
1514
1515 * Directory Storage
1516
1517 * DirectoryStorageAdapter retrieves initial configurations from a directory. If multiple files are present, snapshot and required capabilities will be merged together. See configuration later on this page for details. Writing to this persister is not supported. 
1518
1519 * Autodetect Directory Storage
1520
1521 * AutodetectDirectoryStorageAdapter retrieves initial configuration from a directory (exactly as Xml Directory Storage) but supports xml as well as plaintext format for configuration files. Xml and plaintext files can be combined in one directory. Purpose of this persister is to keep backwards compatibility for plaintext configuration files. 
1522
1523 IMPORTANT: This functionality will be removed in later releases since Plaintext File/Directory adapters are deprecated, and will be fully replaced by xml storage adapters. 
1524
1525 ===== Persisted snapshot format
1526
1527 Configuration snapshots are persisted in xml files for both file and directory adapters. They share the same format: +
1528 ----
1529 <snapshot>
1530     <required-capabilities>
1531         <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
1532         ...
1533     </required-capabilities>
1534     <configuration>
1535  
1536         <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
1537             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1538              ...    
1539             </modules>
1540  
1541             <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1542              ...    
1543             </services>
1544  
1545         </data>
1546  
1547     </configuration>
1548 </snapshot>
1549 ----
1550 The whole snapshot is encapsulated in the snapshot tag that contains two children elements: +
1551
1552 * The required-capabilities tag contains the list of yang capabilities that are required to push configurations located under the configuration tag. The config persister will not push the configuration before the netconf endpoint for the config subsystem reports all needed capabilities. Every yang model that is referenced within this xml file (as namespace for xml tag) must be referenced as a capability in this list. 
1553 * The configuration tag contains the configurations to be pushed to the config subsystem. It is wrapped in a data tag with the base netconf namespace. The whole data tag, with all its child elements, will be inserted into an edit-config rpc as config tag. For more information about the structure of configuration data, see  base yang model for the config subsystem and all the configuration yang files for the controller modules as well as those provided examples. Examples contain multiple explained edit-config rpcs that change the configuration.
1554
1555 NOTE:  XML File adapter adds additional tags to the xml format since it supports multiple snapshots per file. 
1556
1557 The xml format for xml file adapter: +
1558 ----
1559 <persisted-snapshots>
1560    <snapshots>
1561       <snapshot>
1562          <required-capabilities>
1563             <capability>urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl?module=shutdown-impl&amp;revision=2013-12-18</capability>
1564          </required-capabilities>
1565          <configuration>
1566             <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
1567                <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1568                  ....
1569                </modules>
1570                <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1571                  ...
1572                </services>
1573             </data>
1574          </configuration>
1575       </snapshot>
1576       <snapshot>
1577          <required-capabilities>
1578             <capability>urn:opendaylight:params:xml:ns:yang:controller:shutdown:impl?module=shutdown-impl&amp;revision=2013-12-18</capability>
1579          </required-capabilities>
1580          <configuration>
1581             <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
1582                <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1583                  ....
1584                </modules>
1585                <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
1586                  ...
1587                </services>
1588             </data>
1589          </configuration>
1590       </snapshot>
1591    </snapshots>
1592 </persisted-snapshots>
1593 ----
1594 === MD-SAL architecture: Clustering Notifications
1595 MD-SAL supports two kinds of messaging exchange pattern: +
1596
1597 * Request/Reply
1598 * Publish/Subscribe
1599 The RPC module implements the Request/Reply pattern. The notification module implements the Publish/Subscribe functionality. The implementation details are provided at: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Explained:Messaging_Patterns[OpenDaylight Controller:MD-SAL:Explained:Messaging Patterns].
1600 The focus now is on Publish/Subscribe implementation.An earlier implementation assumed a single VM deployment of the controller.The message exchange happens only within a VM in memory. The current requirement is to enable these notifications across nodes in the cluster.
1601
1602 Publish/Subscribe notifications are of two kinds: +
1603
1604 * Data Change events
1605 * Yang notifications
1606 In both cases, the notifications are broadcast to all "listeners". +
1607 *Requirements* +
1608 Some of the requirements: +
1609
1610 * Ability to publish notifications to any subscriber in the cluster
1611 * Subscriber ability to specify delivery policy
1612 * 1 of N: Delivery of the notification to any one of N instances of application running in the cluster
1613 * N of N: Broadcasts
1614 * Local only: Notifying events generated on the same node as the application instance
1615 * Load Balancing: Round robin, least loaded etc
1616 * Content Based or any other application specified custom logic
1617 * Publisher capability to attach properties to the message
1618 * Message priority
1619 * Delivery guarantee
1620 * Ability to plug-in external systems such as AMQP based systems
1621
1622 ==== Proposed change
1623 Based on the requirements, a change in the aPI was proposed: +
1624 ----
1625  Yang notification
1626  publish(Notification notification, MessageProperties props);
1627  registerNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener.NotificationListener listener, Selector selector);
1628  registerNotificationListener(Class notificationType, org.opendaylight.controller.sal.binding.api.NotificationListener listener, Selector selector);
1629  Data change notification
1630  registerDataChangeListener(LogicalDatastoreType store, P path, L listener, DataChangeScope triggeringScope, "Selector selector");
1631 public interface MessageProperties{
1632  public Priority priority();
1633  ...[add more properties]
1634 }
1635 public enum Priority { HIGH, NORMAL, LOW};
1636 public interface Selector {
1637  public List<InstanceLocator> select(Notification event, List<InstanceLocator> instances);
1638 }
1639 ----
1640
1641 === MD-SAL Architecture: DOM
1642 There are several issues that impede the reliability and performance of mD-SAL: + 
1643
1644 * Data structures (defined in yang-data-api) are like XML structures. Therefore, it is hard to implement an optimized datastore atop them. Instead, YANG-defined data structures must be used in the data store. YANG-defined data structures are already being used in the MD-SAL: in the Java DTOs generated by YangTools, and in other components.
1645 * The current MD-SAL data contracts do not provide enough capabilities to more accurately specify an the intent of an application and to perform optimizations to clients (for example, 'do not unnecessarily deserialize data', or 'compute only necessary change sets'). The current datastore implementation prevents atomic updates on subtrees.
1646
1647 ==== MD-SAL DOM Data Broker
1648 The current DOM Data Broker design does not include an assumption of a intelligent in-memory cache with tree-like structures that would:
1649
1650 * Be able to track dependencies
1651 * Calculate change sets 
1652 * Maintain the relationships between commit handlers, notification listeners and the actual data.
1653 This may lead to an inefficient implementation of the two-phase commit, where all state tracking during the is done by the Data Broker itself as follows: +
1654 . Calculate the affected subtrees.
1655 . Filter the commit handlers by the affected subtrees.
1656 . Filter data change listeners by the affected subtrees.
1657 . Capture the initial state for data change listeners (one read per data change listener set).
1658 . Start Request Commit of all the affected commit handlers.
1659 . Finish Commit on all the affected commit handlers.
1660 . Capture the final state for data change listeners (one read per data change listener set).
1661 . Publish the Data Change events to the affected data change listeners.
1662 The states that the current DOM Data Broke keeps and maintains are mapping of subtree paths to:  *
1663
1664 * Registered commit handlers
1665 * Registered data change listeners
1666 * Registered data readers
1667 DOM Data Broker has the following state keeping responsibilities: *
1668
1669 * Read request routing for data readers
1670 * Two phase commit coordination
1671 * Publish Data Change Events
1672 * Capture Before and After state
1673
1674 === MD-SAL: Infinispan Data Store
1675
1676 ==== Components of Infinispan Data Store
1677 Infinispan Data Store comprises the following major components: +
1678
1679 * Encoding or Decoding a Normalized Node into and from the Infinispan TreeCache
1680 * Managing transactions
1681 * Managing DataChange notifications
1682
1683 ==== Encoding or Decoding a Normalized Node into and from the Inifinispan TreeCache +
1684 A NormalizedNode represents a tree whose structure closely models the yang model of a bunch of modules. The NormalizedNode tree typically has values either placed in: +
1685
1686 * A LeafNode (corresponding to a leaf in yang) 
1687 * A LeafSetEntryNode (corresponding to a leaflist in yang) +
1688 The encoding logic walks the NormalizedNode tree looking for LeafNodes and LeafSetEntryNodes.When the logic finds a LeafNode or a LeafSetEntryNode, it records the finding in a map with the following: +
1689
1690 * Instance Identifier of the parent as the key 
1691 * The value of the leaf or leafset entry store in a map where:
1692 ** The NodeIdentifier of the leaf/leafsetentry is the key.
1693 ** The value of the leaf/leafsetentry is the value.
1694 The decoding process involves the following steps: + 
1695
1696 . Uses the interface of TreeCache to get to a certain node in the tree
1697 . Walks through the tree, and reconstructs the NormalizedNode based on the key and value in the Infinispan TreeCache
1698 . Validates the NormalizedNode against the schema
1699
1700 ==== Managing Transactions +
1701 To ensure read-write isolation level, and for other reasons, an infinispan (JTA) transaction for each datastore transaction is created. Since a single thread may be used for multiple JTA transactions, 
1702 the implementation has to ensure the suspension and resumption of the JTA transactions appropriately.
1703 However, this does not seem to have an impact on performance.
1704
1705 ==== Managing DataChange notifications +
1706 The current interface for data change notifications supports the registering of listeners for the following notifications: +
1707
1708 * Data changes at Node (consider node of a tree) level
1709 * Events for any changes that happen at *one* level (meaning immediate children) 
1710 * Any change at the subtree level
1711 The event sent to the listener requires that the following snapshots of the tree be maintained: +
1712
1713 * Before data change
1714 * After data change 
1715
1716 NOTE: This process is very expensive. It means maintaining a Normalized Node representing a snapshot of the tree. It involves converting the tree in Infinispan to NormalizeNode object tree required by the consumer at the start of each transaction.
1717
1718 *To maintain the data changes:* +
1719
1720 . At the begin of transaction, get a NormalizedNode Object tree of the current tree in ISPN TreeCache (This is mandated by the current DataChangeEvent interface.)
1721 . For each CUD operations that happens within the transaction, maintain a transaction log.
1722 . When the pre-commit of the 3PhaseCommit Transaction Interface is called, prepare data changes. This involves: +
1723 .. Comparing the transaction log items with the Snapshot Tree one taken at the beginning of the transactions
1724 .. Preparing the DataChangeEvent lists based on what level the listeners have registered
1725 . Upon a commit, send the events to the listeners in a separate executor, that is asynchronously.
1726
1727 *Suggested changes* +
1728
1729 * Remove the requirement for sending the `before transaction tree' or the `after transaction tree' within each event.
1730 * Send the changed paths of tree to the consumer, and let the consumer do the reading.
1731
1732 ==== Building the POC +
1733 To build or run the POC, you need the latest version of the following: +
1734
1735 * Yangtools
1736 * Controller
1737 * OpenFlow plugin
1738
1739 ==== To get yangtools +
1740
1741 . Get the latest yangtools sources, and then create a branch of it using the following command:
1742 : git checkout 306ffd9eea5a52556b4877debd2a79ca0573ff0c -b infinispan-data-store +
1743 . Build using the following command:
1744 : mvn clean install -DskipTests +
1745
1746 ==== To get the Controller
1747
1748 . Get the latest controller, and then create a branch using the following command:
1749 : git checkout 259b65622b8c29c49235c2210609b9f7a68826eb -b infinispan-data-store +
1750 . Apply the following gerrit. 
1751 : https://git.opendaylight.org/gerrit/#/c/5900/
1752 . Build using the following command:
1753 : mvn clean install -DskipTests +
1754 . If the build should fails, use the following commang:
1755 : cd opendaylight/md-sal/sal-ispn-datastore +
1756 . Build using the following command:
1757 +mvn clean install+
1758 . Return to the controller directory, and build using:
1759 : mvn clean install -DskipTests or resume build +
1760
1761 ==== To get the OpenFlowplugin
1762
1763 . Get the latest openflowplugin code and then create a branch using the following command:
1764 : git checkout 6affeefef4de51ce4b7de86fd9ccf51add3922f7 -b infinispan-data-store +
1765 . Build using the following command:
1766 : mvn clean install -DskipTests +
1767 . Copy the sal-ispn-datastore jar to the plugins folder.
1768
1769 ==== Running the POC +
1770 *Prerequisite* +
1771 Ensure that the 01-md-sal.xml file has been changed to use the new MD-SAL datastore. +
1772
1773 * Run the controller with the infinispan datastore. The section, <<_comparison_of_in_memory_and_infinispan_datastore>> provides information about cbench testing.
1774
1775 NOTE: If you want to see performance numbers similar to those documented, disable datachange notifications. 
1776 The only way to do that in the POC is to change the code in ReadWriteTransactionImpl. Look for the FIXME comments.
1777
1778 === State of the POC +
1779
1780 * Encoding and Decoding a Normalized Node into an Infinispan TreeCache works
1781 * Integrated with the controller
1782 * Eventing works
1783 * With Data Change events disabled, the Infinispan based datastore performs the same, or better than, the custom In-Memory Datastore. Although initially slow, with time it seems to perform more consistently than the In-Memory Datastore.,
1784 * Not fully tested
1785
1786 === Infinispan-related learnings +
1787
1788 *Below par functioning of TreeCache#removeNode API* +
1789 The Infinispan removeNode API failed to remove nodes in the tree, as was promised, correctly. This means, for example, that when a mininet topology changes, some nodes may not be removed from inventory and topology.
1790 This behaviour has not been properly evaluated, and no remedy is currently available.
1791
1792 === Datastore-related learnings +
1793
1794 *Multiple transactions can be created per thread* +
1795 This is a problem because if the backing datastore (infinispan) uses JTA transactions, only one transaction can be active per thread. 
1796 Although this does not necessarily mean the usage of one thread per transaction, it calls for the suspension of one transaction and the resumption of another.
1797 TIP::
1798 * Allow only one active transaction per thread.
1799 * Add an explicit suspend or resume method to a transaction.
1800
1801 === No clarity on the closing of Read-Only transactions +
1802 For every DataStore transaction, a JTA transaction needs to be created. This is to ensure isolation (repeatable reads). When the transaction is done, it must be committed, rolled back, or closed in some fashion. Read-only transactions may not close. This leads to JTA transactions being open until they are timed out.
1803
1804 TIP:: 
1805
1806 * A DataStore may need to do time-outs as well.
1807 * Call _close_ explicitly for read-only transactions.
1808
1809 ==== Write and Delete methods in a read-write transaction do not return a Future
1810 The Write and Delete methods on the DOMWriteTransaction return a void instead of a Future, creating the impression that these methods are synchronous. This is not necessarily true in all cases: for example, in the infinispan datastore, the write was actually done in a separate thread to support multiple transactions on a single thread.
1811 TIP: Return a ListenableFuture for both Write and Delete methods.
1812
1813 ==== Expense of creating a DataChange event +
1814 Creating a DataChange event is very expensive because it needs to pass the Original Sub tree and the Modified Sub tree. +
1815 A NormalizedNode object needs to be created to create a DataChange event. The NormalizedNode object may be a snapshot of the complete modules data to facilitate the sending of the original subtree to DataChange listeners. The prohibitive expense prevents this implementation in every transaction. This is a problem not only in the infinispan datastore but also in a distributed system. A distributed system shards data to collocate it on a different node on the cluster with applications and datachange listeners. For example, while a system may have shards collocated with the inventory application; the topology application may be a datachange listener for datachange events. In this case, the original subtree and the modified sub tree would need to be serialized in some form, and sent to the topology listener.
1816 TIP: Remove the getOriginalSubtree and getModifiedSubtree methods from the datachange listener; understand the use case for providing them; and find a cheaper alternative.
1817
1818 ==== Complications of reconstructing a Normalized Node from different data-structures +
1819 The reconstruction of a Normalized Node from a different data-structure, like a map or a key-value store, is complicated or may appear complicated.
1820 A NormalizedNode is the binding-independent equivalent of data that gets stored in the datastore. For the in-memory datastore, it is the native storage format. It is a complicated structure that basically mirrors the model as defined in yang. Understanding it and properly decoding it could be a challenge for the implemention of an alternate datastore.
1821 TIP: Create utility classes to construct a normalized node from a simple tree structure. The Old CompositeNode or the Infinispan Node for example is a much simpler structure to follow.
1822
1823 ==== Comparison of In-Memory and Infinispan Datastore
1824 Cbench was used to compare the performance of the two datastores.
1825 To prepare the controller for testing: +
1826
1827 IMPORTANT: Use the openflow plugin distribution.
1828
1829 . Remove the simple forwarding, arp handler, and md-sal statistics manager bundles.
1830 . Set the log level to ERROR. 
1831 . Run the controller with the following command: +
1832 :  ./run.sh -Xmx4G -Xms2G -XX:NewRatio=5 -XX:+UseG1GC -XX:MaxPermSize=256m 
1833 . From the osgi command prompt, use *dropAllPackets on*.
1834
1835 ==== Running cbench +
1836 For both the in-memory and infinispan datastore versions, cbench was run 11 times. The first run is ignored in both cases.
1837
1838 * Use the cbench command: +
1839 : cbench -c <controller ip> -p 6633 -m 1000 -l 10 -s 16 -M 1000
1840 This was a latency test and the arguments roughly translate to this: +
1841 : -m 1000 : use 1000 milliseconds per test -l 10 : use 10 loops per test -s 16 : fake 16 switches -M 1000 : use 1000 hosts per switch
1842  </div>
1843
1844 ==== The results for In-Memory Datastore +
1845 To test the in-memory datastore, a pre-built openflow plugin distribution from Jenkins was downloadedon and on which was enabled the new in-memory datastore. +
1846 *In-Memory Datastore Results*
1847 [options="header",width="75%"]
1848 |===
1849 | Run | Min | Max | Avg | StdDev
1850 | 1 | 365 | 1049 | 715 | 04
1851 | 2 | 799 | 1044 | 953 | 71
1852 | 3 | 762 | 949 | 855 | 59
1853 | 4 | 616 | 707 | 666 | 27
1854 | 5 | 557 | 639 | 595 | 24
1855 | 6 | 510 | 583 | 537 | 25
1856 | 7 | 455 | 535 | 489 | 22
1857 | 8 | 351 | 458 | 420 | 38
1858 | 9 | 396 | 440 | 417 | 14
1859 | 10 | 376 | 413 | 392 | 13
1860 |===
1861
1862 ==== Infinispan Datastore +
1863 The Infinispan Datastore was built of a master a month old. Since the In-Memory datastore was hardcoded at that time the in-memory datastore was swapped for the the infinispan datastore by modifying the sal-broker-impl sources.
1864
1865
1866 Listed are some steps that were either completed to isolate the changes that were being made, or to tweak performance:  +
1867
1868 * Infinispan 5.3 was used because to isolate changes to utilize tree cache to the infinispan datastore bundles. Attempting to use version 6.0 caused a problem in loading some classes from infinispan.Ideally, to use infinispan as a backing store, tweak clustering services to obtain a treecache.
1869 * Added an exists method onto the In-Memory ReadTransaction API. This was because it was found that in one place in the BA Broker was code which checked for the existence of nodes in the tree by doing a read. Reads are a little expensive on the Infinispan datastore because of the need to convert to a NormalizedNode. An exists method was added to the interface to just check for node-existence.
1870 * When a transaction was used to read data it was not being closed causing the Infinispan JTA transactions to persist. Again, a change in the broker was made to close a transaction after it was concluded so that it dis not persist and trigger a clean by the reaper.
1871
1872 *Infinispan Datastore Results*
1873 [cols="5*",^,options="header",width="75%"]
1874 |===
1875 | Run | Min | Max | Avg | StdDev
1876 | 1 | 43 | 250 | 186 | 61
1877 | 2 | 266 | 308 | 285 | 13
1878 | 3 | 300 | 350 | 325 | 12
1879 | 4 | 378 | 446 | 412 | 24
1880 | 5 | 609 | 683 | 644 | 26
1881 | 6 | 492 | 757 | 663 | 76
1882 | 7 | 794 | 838 | 816 | 11
1883 | 8 | 645 | 845 | 750 | 60
1884 | 9 | 553 | 829 | 708 | 100
1885 | 10 | 615 | 910 | 710 | 86
1886 |===
1887
1888 === OpenDaylight Controller configuration: FAQs
1889 ====  Generic questions about the configuration subsystem
1890 *There is already JMX. Why do we need another system?* 
1891
1892 Java Management Extensions (JMX) provides programmatic access to management data, defining a clear structure on the level of a single object (MBeans). It provides the mechanism to query and set information exposed from these MBeans, too. It is adequate for replacing properties, but it does not treat the JVM container for what it is: a collection of applications working in concert. When the configuration problem is taken to the level of an entire system, there are multiple issues which JMX does not solve:
1893
1894 * The need to validate that a proposed system is semantically valid before an attempt to change is made
1895 * The ability to synchronize modification multiple properties at the same time, such that both occur at the same time
1896 * The ability to express dependencies between applications
1897 * Machine-readable descriptions of layouts of configuration data
1898
1899 *Why use YANG?*
1900
1901 The problem of configuring a device has been tackled in https://ietf.org/[IETF] for many years now, initially using https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol[SNMP] (with https://en.wikipedia.org/wiki/Management_information_base[MIB] as the data definition language). While the protocol has been successful for monitoring devices, it has never gained traction as the unified way of configuring devices. The reasons for this have been https://tools.ietf.org/html/rfc3535[analyzed] and https://datatracker.ietf.org/doc/rfc6241/[NETCONF] was standardized as the successor protocol. NETCONF provides the abstractions to deal with configuration validation, and relies on http://tools.ietf.org/html/rfc6020[YANG] as its data modeling language. The configuration subsystem is designed to completely align with NETCONF such that it can be used as the native transport with minimal translation.
1902
1903 === OpenDaylight Controller configuration: Component map
1904 [cols="5,5a",^,options="header",width="75%"]
1905 |===
1906 | Component | Description
1907 | config-subsystem-core | Config subsystem core. 
1908                         Manages the configuration of the controller.
1909                         
1910 Responsibilities:
1911
1912
1913 * Scanning of bundles for ModuleFactories.
1914
1915 * Transactional management of lifecycle and dependency injection for config modules.
1916
1917 * Exposure of modules and their configuration into JMX.
1918 | netty-config| Config modules for netty related resources, for example, netty-threadgroup, netty-timer and others. 
1919
1920 Contains config module definition in the form of yang schemas + generated code binding for the config subsystem.
1921 | controller-shutdown | Controller shutdown mechanism. 
1922
1923 Brings down the whole OSGi container of the controller. 
1924
1925 Authorization required in the form of a "secret string".
1926
1927 Also contains config module definition in the form of yang schemas + generated code binding for the config subsystem. This makes it possible to invoke shutdown by means of the config-subsystem.
1928 | threadpool-config | Config modules for threading related resources, for example, threadfactories, fixed-threadpool, and others.
1929  
1930 Contains config module definition in the form of yang schemas + generated code binding for the config subsystem.
1931 | logback-config | Config modules for logging (logback) related resources, for example, loggers, appenders, and others. 
1932
1933 Contains config module definition in the form of yang schemas + generated code binding for the config subsystem.
1934 | netconf-config-dispatcher-config | Config modules for netconf-dispatcher(from netconf subsystem). 
1935
1936 Contains config module definition in the form of yang schemas + generated code binding for the config subsystem.
1937 | yang-jmx-config-generator | Maven plugin that generates the config subsystem code binding from provided yang schemas. This binding is required when the bundles want to participate in the config subsystem.
1938 | yang-jmx-config-generator-testing-modules | Testing resources for the maven plugin.
1939 | config-persister | Contains the api definition for an extensible configuration persister(database for controller configuration). 
1940
1941 The persister (re)stores the configuration for the controller. Persister implementation can be found in the netconf subsystem. 
1942
1943 The adapter bundles contain concrete implementations of storage extension. They store the config as xml files on the filesystem.
1944 | config-module-archetype | Maven archetype for "config subsystem aware" bundles. 
1945
1946 This archetype contains blueprints for yang-schemas, java classes, and other files(for example, pom.xml) required for a bundle to participate in the config subsystem. 
1947
1948 This archetype generates a bundle skeleton that can be developed into a full blown "config subsystem aware" bundle.
1949 |===
1950
1951 === OpenDaylight Controller: Netconf component map
1952
1953 [cols="2", options="header", width="75%"]
1954 |===
1955 |Component | Description 
1956
1957 | netconf-server | Implementation of the generic (extensible) netconf server over tcp/ssh. Handles the general communication over the network, and forwards the rpcs to its extensions that implement the specific netconf rpc handles (For example: get-config).
1958 | netconf-to-config-mapping | API definition for the netconf server extension with the base implementation that transforms the netconf rpcs to java calls for the config-subsystem (config-subsystem netconf extension). 
1959 | netconf-client | Netconf client basic implementation. Simple netconf client that supports netconf communication with remote netconf devices using xml format. 
1960 | netconf-monitoring | Netconf-monitoring yang schemas with the implementation of a netconf server extension that handles the netconf-monitoring related handlers (For example: adding netconf-state to get rpc) 
1961 | config-persister-impl | Extensible implementation of the config persister that persists the configuration in the form of xml,(easy to inject to edit-config rpc) and loads the initial configuration from the persisted files. The configuration is stored after every successful commit rpc. 
1962 | netconf-cli | Prototype of a netconf cli. 
1963 |=== 
1964
1965 === OpenDaylight Controller Configuration: Examples sample project
1966 *Sample maven project* +
1967
1968 In this example, we will create a maven project that provides two modules, each implementing one service. We will design a simple configuration, as well as runtime data for each module using yang. 
1969 A sample maven project called config-demo was created. This project contains two Java interfaces: Foo and Bar. Each interface has one default implementation per interface, FooImpl and BarImpl. Bar is the producer in our example and produces integers when the method getNextEvent() is called. Foo is the consumer, and its implementation depends on a Bar instance. Both implementations require some configuration that is injected by means of constructors. 
1970
1971 * Bar.java: 
1972 ----
1973 package org.opendaylight.controller.config.demo;
1974  
1975 public interface Bar {
1976  
1977     int getNextEvent();
1978  
1979 }
1980 ----
1981 * BarImpl.java:
1982 ----
1983 package org.opendaylight.controller.config.demo;
1984  
1985 public class BarImpl implements Bar {
1986  
1987     private final int l1, l2;
1988     private final boolean b;
1989  
1990     public BarImpl(int l1, int l2, boolean b) {
1991         this.l1 = l1;
1992         this.currentL = l1;
1993         this.l2 = l2;
1994         this.b = b;
1995     }
1996  
1997     private int currentL;
1998  
1999     @Override
2000     public int getNextEvent() {
2001         if(currentL==l2)
2002             return -1;
2003         return currentL++;
2004     }
2005 }
2006 ----
2007 * Foo.java: 
2008 ----
2009 package org.opendaylight.controller.config.demo;
2010  
2011 public interface Foo {
2012  
2013     int getEventCount();
2014 }
2015 ----
2016 * FooImpl.java: 
2017 ----
2018 package org.opendaylight.controller.config.demo;
2019  
2020 public class FooImpl implements Foo {
2021  
2022     private final String strAttribute;
2023     private final Bar barDependency;
2024     private final int intAttribute;
2025  
2026     public FooImpl(String strAttribute, int intAttribute, Bar barDependency) {
2027         this.strAttribute = strAttribute;
2028         this.barDependency = barDependency;
2029         this.intAttribute = intAttribute;
2030     }
2031  
2032     @Override
2033     public int getEventCount() {
2034         int count = 0;
2035         while(barDependency.getNextEvent() != intAttribute) {
2036             count++;
2037         }
2038         return count;
2039     }
2040 }
2041 ----
2042 * pom.xml (config-demo project is defined as a sub-module of the controller project, and at this point contains only the configuration for maven-bundle-plugin): 
2043 ----
2044 <?xml version="1.0" encoding="UTF-8"?>
2045 <project xmlns="http://maven.apache.org/POM/4.0.0"
2046          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2047          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2048     <modelVersion>4.0.0</modelVersion>
2049  
2050     <parent>
2051         <artifactId>commons.opendaylight</artifactId>
2052         <groupId>org.opendaylight.controller</groupId>
2053         <version>1.4.1-SNAPSHOT</version>
2054         <relativePath>../commons/opendaylight/pom.xml</relativePath>
2055     </parent>
2056     <groupId>org.opendaylight.controller</groupId>
2057     <version>0.1.1-SNAPSHOT</version>
2058     <artifactId>config-demo</artifactId>
2059     <packaging>bundle</packaging>
2060     <name>${project.artifactId}</name>
2061     <prerequisites>
2062         <maven>3.0.4</maven>
2063     </prerequisites>
2064  
2065     <build>
2066         <plugins>
2067             <plugin>
2068                 <groupId>org.apache.felix</groupId>
2069                 <artifactId>maven-bundle-plugin</artifactId>
2070                 <version>2.4.0</version>
2071                 <extensions>true</extensions>
2072                 <configuration>
2073                     <instructions>
2074                         <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
2075                         <Export-Package>
2076                             org.opendaylight.controller.config.demo,
2077                         </Export-Package>
2078                     </instructions>
2079                 </configuration>
2080             </plugin>
2081         </plugins>
2082     </build>
2083  
2084 </project>
2085 ----
2086
2087 ==== Describing the module configuration using yang
2088 In order to fully leverage the utilities of the configuration subsystem, we need to describe the services, modules, their configurations, and the runtime state using the yang modeling language. We will define two services and two modules, which will be used to configure the instances of FooImpl and BarImpl. This definition will be split into two yang files: config-demo.yang (service definition) and config-demo-impl.yang (module definition).
2089
2090 * config-demo.yang 
2091 ----
2092 module config-demo {
2093     yang-version 1;
2094     namespace "urn:opendaylight:params:xml:ns:yang:controller:config:demo";
2095     prefix "demo";
2096  
2097     import config { prefix config; revision-date 2013-04-05; }
2098  
2099     description
2100         "Service definition for config-demo";
2101  
2102     revision "2013-10-14" {
2103         description
2104             "Initial revision";
2105     }
2106  
2107     // Service definition for service foo that encapsulates instances of org.opendaylight.controller.config.demo.Foo
2108     identity foo {
2109         description
2110             "Foo service definition";
2111  
2112         base "config:service-type";
2113         config:java-class "org.opendaylight.controller.config.demo.Foo";
2114     }
2115  
2116     identity bar {
2117         description
2118             "Bar service definition";
2119  
2120         base "config:service-type";
2121         config:java-class "org.opendaylight.controller.config.demo.Bar";
2122     }
2123 }
2124 ----
2125 The config yang module needs to be imported in order to define the services. There are two services defined, and these services correspond to the Java interfaces Foo and Bar (specified by the config:java-class extension). 
2126
2127 * config-demo-impl.yang
2128 ----
2129 module config-demo-impl {
2130  
2131     yang-version 1;
2132     namespace "urn:opendaylight:params:xml:ns:yang:controller:config:demo:java";
2133     prefix "demo-java";
2134  
2135     // Dependency on service definition for config-demo
2136     /* Service definitions could be also located in this yang file or even
2137      * in a separate maven project that is marked as maven dependency
2138      */
2139     import config-demo { prefix demo; revision-date 2013-10-14;}
2140  
2141     // Dependencies on config subsystem definition
2142     import config { prefix config; revision-date 2013-04-05; }
2143     import rpc-context { prefix rpcx; revision-date 2013-06-17; }
2144  
2145  
2146     description
2147         "Service implementation for config-demo";
2148  
2149     revision "2013-10-14" {
2150         description
2151             "Initial revision";
2152     }
2153                                                                       //----- module foo-impl ----- //
2154     // Module implementing foo service                                                              //
2155     identity foo-impl {                                                                             //
2156         base config:module-type;                                                                    //
2157         config:provided-service demo:foo;                                                           //
2158         config:java-name-prefix FooImpl;                                                            //
2159     }                                                                                               //
2160                                                                                                     //
2161     // Configuration for foo-impl module                                                            //
2162     augment "/config:modules/config:module/config:configuration" {                                  //
2163         case foo-impl {                                                                             //
2164             when "/config:modules/config:module/config:type = 'foo-impl'";                          //
2165                                                                                                     //
2166             leaf str-attribute {                                                                    //
2167                 type string;                                                                        //
2168             }                                                                                       //
2169                                                                                                     //
2170             leaf int-attribute {                                                                    //
2171                 type int32;                                                                         //
2172             }                                                                                       //
2173                                                                                                     //
2174                                                                                                     //
2175             // Dependency on bar service instance                                                   //
2176             container bar-dependency {                                                              //
2177                 uses config:service-ref {                                                           //
2178                     refine type {                                                                   //
2179                         mandatory true;                                                             //
2180                         config:required-identity demo:bar;                                          //
2181                     }                                                                               //
2182                 }                                                                                   //
2183             }                                                                                       //
2184                                                                                                     //
2185         }                                                                                           //
2186     }                                                                                               //
2187                                                                                                     //
2188     // Runtime state definition for foo-impl module                                                 //
2189     augment "/config:modules/config:module/config:state" {                                          //
2190         case foo-impl {                                                                             //
2191             when "/config:modules/config:module/config:type = 'foo-impl'";                          //
2192                                                                                                     //
2193                                                                                                     //
2194         }                                                                                           //
2195     }                                                                                               //
2196                                                                                       // ---------- //
2197     // Module implementing bar service
2198     identity bar-impl {
2199         base config:module-type;
2200         config:provided-service demo:bar;
2201         config:java-name-prefix BarImpl;
2202     }
2203  
2204     augment "/config:modules/config:module/config:configuration" {
2205         case bar-impl {
2206             when "/config:modules/config:module/config:type = 'bar-impl'";
2207  
2208             container dto-attribute {
2209                 leaf int-attribute {
2210                     type int32;
2211                 }
2212  
2213                 leaf int-attribute2 {
2214                     type int32;
2215                 }
2216  
2217                 leaf bool-attribute {
2218                     type boolean;
2219                 }
2220             }
2221  
2222         }
2223     }
2224  
2225     augment "/config:modules/config:module/config:state" {
2226         case bar-impl {
2227             when "/config:modules/config:module/config:type = 'bar-impl'";
2228  
2229         }
2230     }
2231  
2232 }
2233 ----
2234 The config yang module as well as the config-demo yang module need to be imported. There are two modules defined: foo-impl and bar-impl. Their configuration (defined in the augment "/config:modules/config:module/config:configuration" block) corresponds to the configuration of the FooImpl and BarImpl Java classes. In the constructor of FooImpl.java, we see that the configuration of foo-impl module defines three similar attributes. These arguments are used to instantiate the FooImpl class. These yang files are placed under the src/main/yang folder. 
2235
2236 ==== Updating the maven configuration in pom.xml
2237
2238 The yang-maven-plugin must be added to the pom.xml. This plugin will process the yang files, and generate the configuration code for the defined modules. Plugin configuration: +
2239 ----
2240 <plugin>
2241     <groupId>org.opendaylight.yangtools</groupId>
2242     <artifactId>yang-maven-plugin</artifactId>
2243     <version>${yangtools.version}</version>
2244     <executions>
2245         <execution>
2246             <goals>
2247                 <goal>generate-sources</goal>
2248             </goals>
2249             <configuration>
2250                 <codeGenerators>
2251                     <generator>
2252                         <codeGeneratorClass>
2253                             org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
2254                         </codeGeneratorClass>
2255                         <outputBaseDir>${project.build.directory}/generated-sources/config</outputBaseDir>
2256                         <additionalConfiguration>
2257                             <namespaceToPackage1>
2258                                 urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
2259                             </namespaceToPackage1>
2260                         </additionalConfiguration>
2261                     </generator>
2262                 </codeGenerators>
2263                 <inspectDependencies>true</inspectDependencies>
2264             </configuration>
2265         </execution>
2266     </executions>
2267     <dependencies>
2268         <dependency>
2269             <groupId>org.opendaylight.controller</groupId>
2270             <artifactId>yang-jmx-generator-plugin</artifactId>
2271             <version>${config.version}</version>
2272         </dependency>
2273     </dependencies>
2274 </plugin>
2275 ----
2276 The configuration important for the plugin: the output folder for the generated files, and the mapping between the yang namespaces and the java packages (Inspect dependencies must be set to true.). The default location for the yang files is under the src/main/yang folder. This plugin is backed by the artifact yang-jmx-generator-plugin and its class org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator is responsible for code generation. This artifact is part of the configuration subsystem. 
2277
2278 In addition to the yang-maven-plugin, it is neccessary to add the build-helper-maven-plugin in order to add the generated sources to the build process: 
2279 ----
2280 <plugin>
2281    <groupId>org.codehaus.mojo</groupId>
2282    <artifactId>build-helper-maven-plugin</artifactId>
2283    <version>1.8</version>
2284    <executions>
2285        <execution>
2286            <id>add-source</id>
2287            <phase>generate-sources</phase>
2288            <goals>
2289                <goal>add-source</goal>
2290            </goals>
2291            <configuration>
2292                <sources>
2293                   <source>${project.build.directory}/generated-sources/config</source>;
2294                </sources>
2295            </configuration>
2296        </execution>
2297    </executions>
2298 </plugin>
2299 ----
2300 Earlier, the configuration yang module in the yang files was imported. In order to acquire this yang module, we need to add a dependency to the pom file: 
2301 ----
2302 <dependency>
2303     <groupId>org.opendaylight.controller</groupId>
2304     <artifactId>config-api</artifactId>
2305     <version>${config.version}</version>
2306 </dependency>
2307 ----
2308 In addition, a couple of utility dependencies must be added:
2309 ----
2310 <dependency>
2311     <groupId>org.slf4j</groupId>
2312     <artifactId>slf4j-api</artifactId>
2313 </dependency>
2314 <dependency>
2315     <groupId>com.google.guava</groupId>
2316     <artifactId>guava</artifactId>
2317 </dependency>
2318 ----
2319 Run *mvn clean install*. 
2320
2321 ==== Generated java files
2322
2323 A set of new source files divided into two groups is seen. The first group is located under the ${project.build.directory}/generated-sources/config directory, which was specified in the yang-maven-plugin configuration. The second group is located under the src/main/java directory. Both groups then define the package org.opendaylight.controller.config.yang.config.demo.impl. The first group contains code that must not be edited in any way, since this code can be regenerated by the plugin if necessary. The code that needs to be edited belongs to the second group and is located under src/main/java.
2324
2325 ===== Generated config source files examples
2326
2327 * BarImplModuleMXBean.java 
2328 ----
2329 public interface BarImplModuleMXBean
2330 {
2331     public org.opendaylight.controller.config.yang.config.demo.java.DtoAttribute getDtoAttribute();
2332  
2333     public void setDtoAttribute(org.opendaylight.controller.config.yang.config.demo.java.DtoAttribute dtoAttribute);
2334  
2335 }
2336 ----
2337 The BarImplModuleMXBean interface represents the getter and the setter for dtoAttribute that will be exported to the configuration registry by means of JMX. The attribute was defined in the yang model: in this case, it is the composite type which was converted to OpenType. 
2338
2339 * Attribute definition from config-demo-impl.yang 
2340 ----
2341 // Module implementing bar service
2342     identity bar-impl {
2343         base config:module-type;
2344         config:provided-service demo:foo;
2345         config:java-name-prefix BarImpl;
2346     }
2347  
2348     augment "/config:modules/config:module/config:configuration" {
2349         case bar-impl {
2350             when "/config:modules/config:module/config:type = 'bar-impl'";
2351  
2352             container dto-attribute {
2353                 leaf int-attribute {
2354                     type int32;
2355                 }
2356  
2357                 leaf int-attribute2 {
2358                     type int32;
2359                 }
2360  
2361                 leaf bool-attribute {
2362                     type boolean;
2363                 }
2364             }
2365  
2366         }
2367     }
2368 ----
2369 From the container dto-attribute, the DtoAttribute java file was generated. The Class contains the plain constructor, and the getters and setters for the attributes defined as container leaves.
2370 Not only is ModuleMXBean generated from this module definition, but also BarImplModuleFactory and BarImplModule stubs (in fact AbstractBarImplModuleFactory and AbstractBarImplModule are generated too.). 
2371
2372 * AbstractBarImplModule.java +
2373 This abstract class is almost fully generated: only the method validate() has an empty body and the method createInstance() is abstract. The user must implement both methods by user. AbstractBarImplModule implements its ModuleMXBean, Module, RuntimeBeanRegistratorAwareModule, and the dependent service interface as defined in yang. Moreover, the class contains two types of constructors: one for the module created from the old module instance, and the second for module creation from scratch. 
2374
2375 * AbstractBarImplModuleFactory.java +
2376 Unlike AbstractModule, AbstractFactory is fully generated, but it is still an abstract class. The factory is responsible for module instances creation, and provides two type of instantiateModule methods for both module constructor types. It implements the ModuleFactory interface. 
2377
2378 Next, create the runtime bean for FooImplModule. Runtime beans are designated to capture data about the running module. 
2379
2380 * Add runtime bean definition to config-demo-impl.yang +
2381
2382 ===== Modifying generated sources
2383
2384 Generated source files: +
2385
2386 * src/main/java/**/BarImplModule 
2387 * src/main/java/**/BarImplModuleFactory 
2388 * src/main/java/**/FooImplModule 
2389 * src/main/java/**/FooImplModuleFactory 
2390
2391 *BarImplModule* +
2392 We will start by modifying BarImplModule. Two constructors and two generated methods are seen: 
2393 ----
2394 @Override
2395     public void validate(){
2396         super.validate();
2397         // Add custom validation for module attributes here.
2398     }
2399  
2400     @Override
2401     public java.lang.AutoCloseable createInstance() {
2402         //TODO:implement
2403         throw new java.lang.UnsupportedOperationException("Unimplemented stub method");
2404     }
2405 ----
2406 In *validate*, specify the validation for configuration attributes, for example:
2407 ----
2408 @Override
2409     public void validate(){
2410         super.validate();  
2411         Preconditions.checkNotNull(getDtoAttribute());
2412         Preconditions.checkNotNull(getDtoAttribute().getBoolAttribute());
2413         Preconditions.checkNotNull(getDtoAttribute().getIntAttribute());
2414         Preconditions.checkNotNull(getDtoAttribute().getIntAttribute2());
2415         Preconditions.checkState(getDtoAttribute().getIntAttribute() > getDtoAttribute().getIntAttribute2());
2416     }
2417 ----
2418 In *createInstance* you need to create a new instance of the bar service => Bar interface, for example:
2419 ----
2420 @Override
2421     public java.lang.AutoCloseable createInstance() {
2422         return new BarImpl(getDtoAttribute().getIntAttribute(), getDtoAttribute().getIntAttribute2(), getDtoAttribute()
2423                 .getBoolAttribute());
2424     }
2425 ----
2426 ===== Notes: 
2427
2428 * createInstance returns AutoCloseable so the returned type needs to implement it. (You can make BarImpl implement AutoCloseable, or create a Wrapper class around the BarImpl instance that implements AutoCloseable, or even extend the BarImpl class and make it implement it.) 
2429 * You can access all the configuration attributes by means of the getter methods. 
2430 * In config-demo-impl.yang, we defined the bar-impl configuration as a container dto-attribute. The code generator creates a transfer object DtoAttribute that you can access by means of the getDtoAttribute() method, and retrieve configuration data from it. You can even add a new constructor to BarImpl that takes this transfer object, and reduces the number of arguments. 
2431
2432 *FooImplModule* +
2433 We will not add any custom validation in this module. The createInstance method will look as follows: +
2434 ----
2435  @Override
2436     public java.lang.AutoCloseable createInstance() {
2437         return new FooImpl(getStrAttribute(), getIntAttribute(), getBarDependencyDependency());
2438     }
2439 ----
2440 ===== Adding support for default instances
2441
2442 In order to provide a default instance of module bar-impl, we need to further modify the generated code by the overriding method getDefaultModules in src/main/java/**/BarImplModuleFactory class. The body of this class is empty thus far, and it inherits the default behaviour from its parent abstract factory. Use the following code to replace the empty body: 
2443 ----
2444 public static final ModuleIdentifier defaultInstance1Id = new ModuleIdentifier(NAME, "defaultInstance1");
2445  
2446     @Override
2447     public Set<BarImplModule> getDefaultModules(DependencyResolverFactory dependencyResolverFactory, BundleContext bundleContext) {
2448         DependencyResolver depResolver1 = dependencyResolverFactory.createDependencyResolver(defaultInstance1Id);
2449         BarImplModule defaultModule1 = new BarImplModule(defaultInstance1Id, depResolver1);
2450         defaultModule1.setDtoAttribute(getDefaultConfiguration(bundleContext));
2451  
2452         return Sets.newHashSet(defaultModule1);
2453     }
2454  
2455     private DtoAttribute getDefaultConfiguration(BundleContext bundleContext) {
2456         DtoAttribute defaultConfiguration = new DtoAttribute();
2457  
2458         String property = bundleContext.getProperty("default.bool");
2459         defaultConfiguration.setBoolAttribute(property == null ? false : Boolean.parseBoolean(property));
2460  
2461         property = bundleContext.getProperty("default.int1");
2462         defaultConfiguration.setIntAttribute(property == null ? 55 : Integer.parseInt(property));
2463  
2464         property = bundleContext.getProperty("default.int2");
2465         defaultConfiguration.setIntAttribute2(property == null ? 0 : Integer.parseInt(property));
2466  
2467         return defaultConfiguration;
2468     }
2469 ----
2470 The _getDefaultModules_ method now produces an instance of the bar-impl module with the name _defaultInstance1_. (It is possible to produce multiple default instances since the return type is a Set of module instances.) Note the getDefaultConfiguration method. It provides the default configuration for default instances by trying to retrieve system properties from bundleContext (or provides hardcoded values in case the system property is not present). 
2471
2472 For the controller distribution, system properties can be fed by means of _config.ini_ file. 
2473
2474 The method _getDefaultModules_ is called automatically after a bundle containing this factory is started in the OSGi environment. Its default implementation returns an empty Set. 
2475
2476 The default instances approach is similar to the Activator class approach in OSGi with the advantage of default instances being managed by the configuration subsystem. This approach can either replace the Activator class approach, or be used along with it. 
2477
2478 *Verifying the default instances in distribution* +
2479
2480 If we add the config-demo bundle to the opendaylight distribution, we can verify the presence of the default instance. The file pom.xml under the opendaylight/distribution/opendaylight folder needs to be modified by adding the config-demo dependency: 
2481 ----
2482 <dependency>
2483     <groupId>${project.groupId}</groupId>
2484     <artifactId>config-demo</artifactId>
2485     <version>0.1.1-SNAPSHOT</version>
2486 </dependency>
2487 ----
2488 Now we need to rebuild the conf-demo module using mvn clean install. Then, we can build the distribution using the same mvn command under the _opendaylight/distribution/opendaylight_ folder. If we go to the _opendaylight/distribution/opendaylight/target/distribution.opendaylight-osgipackage/opendaylight_ folder, and execute run.sh, the opendaylight distribution should start. 
2489
2490 We can check the presence of the default instances by means of JMX using a tool such as _jvisualvm_.
2491
2492 === OpenDaylight Controller:Configuration examples user guide
2493 ==== Configuring thread pools with yangcli-pro
2494 Requirements: yangcli-pro version 13.04-9.2 or later +
2495
2496 ===== Connecting to plaintext TCP socket and ssh
2497 Currently SSH is exposed by the controller. The network interface and port are configured in configuration/config.ini . The current configuration of netconf is as follows: +
2498 ----
2499 # Netconf startup configuration
2500 #netconf.tcp.address=127.0.0.l
2501 #netconf.tcp.port=8383
2502  
2503 netconf.ssh.address=0.0.0.0
2504 netconf.ssh.port=1830
2505 ----
2506 To connect the yangcli-pro client, use the following syntax: +
2507 ----
2508 yangcli-pro --user=admin --password=admin --transport=ssh --ncport=1830 --server=localhost
2509 ----
2510 If the plaintext TCP port is not commented out, one can use the following: +
2511 ----
2512 yangcli-pro --user=a --password=a --transport=tcp --ncport=8383 --server=localhost
2513 ----
2514 Authentication in this case is ignored.
2515
2516 For better debugging, include following arguments: +
2517 ----
2518 --log=/tmp/yuma.log --log-level=debug4 --log-console
2519 ----
2520
2521 NOTE:  When the log file is set, the output will not appear on stdout.
2522
2523 ===== Configuring threadfactory
2524 The threadfactory is a service interface that can be plugged into threadpools, defined in config-threadpool-api (see the https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blob;f=opendaylight/config/threadpool-config-api/src/main/yang/threadpool.yang;h=8f3064822be319dfee6fd7c7061c8bee14db268f;hb=refs/heads/master[yang file].
2525 The implementation to be used is called threadfactory-naming. This implementation will set a name for each thread created using a configurable prefix and auto incremented index. See the https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blob;f=opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl.yang;h=a2366f285a0c0b8682b1093f18fb5ee184c9cde3;hb=refs/heads/master[Yang file].
2526
2527 . Launch yangcli-pro and connect to the server.
2528 . Enter *get-config source=running* to see the current configuration. +
2529 Example output: +
2530 ----
2531 rpc-reply {
2532   data {
2533     modules {
2534       module  binding-broker-singleton {
2535         type binding-impl:binding-broker-impl-singleton
2536         name binding-broker-singleton
2537       }
2538     }
2539     services {
2540       service  md-sal-binding:binding-broker-osgi-registry {
2541         type md-sal-binding:binding-broker-osgi-registry
2542         instance  ref_binding-broker-singleton {
2543           name ref_binding-broker-singleton
2544           provider /modules/module[type='binding-broker-impl-singleton'][name='binding-broker-singleton']
2545         }
2546       }
2547     }
2548   }
2549 }
2550 ----
2551 [start=3]
2552 . Enter the merge /modules/module.
2553 . At the prompt, enter the string value for the leaf <name>. This is the name of the config module. Enter threadfactory-bgp.
2554 . Set the identityref for the leaf <type>. Press Tab to see a list of available module names. Enter threadfactory-naming.
2555 . At the prompt, choose the case statement. Example output:
2556 ----
2557  1: case netty-threadgroup-fixed:
2558        leaf thread-count
2559   2: case netty-hashed-wheel-timer:
2560        leaf tick-duration
2561        leaf ticks-per-wheel
2562        container thread-factory
2563   3: case async-eventbus:
2564        container threadpool
2565   4: case threadfactory-naming:
2566        leaf name-prefix
2567   5: case threadpool-fixed:
2568        leaf max-thread-count
2569        container threadFactory
2570   6: case threadpool-flexible:
2571        leaf max-thread-count
2572        leaf minThreadCount
2573        leaf keepAliveMillis
2574        container threadFactory
2575   7: case threadpool-scheduled:
2576        leaf max-thread-count
2577        container threadFactory
2578   8: case logback:
2579        list file-appenders
2580        list rolling-appenders
2581        list console-appenders
2582        list loggers
2583 ----
2584 In this case, we chose 4. +
2585 [start=7]
2586 . Next fill in the string value for the leaf <name-prefix>. Enter bgp.
2587 : (You should get an OK response from the server.)
2588 [start=8]
2589 . Optionally issue get-config source=candidate to verify the change.
2590 . Issue commit.
2591 . Issue get-config source=running. Example output: +
2592 ----
2593 rpc-reply {
2594   data {
2595     modules {
2596       module  binding-broker-singleton {
2597         type binding-impl:binding-broker-impl-singleton
2598         name binding-broker-singleton
2599       }
2600       module  threadfactory-bgp {
2601         type th-java:threadfactory-naming
2602         name threadfactory-bgp
2603         name-prefix bgp
2604       }
2605     }
2606     services {
2607       service  th:threadfactory {
2608         type th:threadfactory
2609         instance  ref_threadfactory-bgp {
2610           name ref_threadfactory-bgp
2611           provider /modules/module[type='threadfactory-naming'][name='threadfactory-bgp']
2612         }
2613       }
2614       service  md-sal-binding:binding-broker-osgi-registry {
2615         type md-sal-binding:binding-broker-osgi-registry
2616         instance  ref_binding-broker-singleton {
2617           name ref_binding-broker-singleton
2618           provider /modules/module[type='binding-broker-impl-singleton'][name='binding-broker-singleton']
2619         }
2620       }
2621     }
2622   }
2623 }
2624 ----
2625 ==== Configuring fixed threadpool
2626
2627 Service interface threadpool is defined in the config-threadpool-api. The implementation used is called threadpool-fixed that is defined in config-threadpool-impl. This implementation creates a threadpool of fixed size. There are two mandatory attributes: size and dependency on a threadfactory.
2628
2629 . Issue get-config source=running. As you can see in the last step of configuring threadfactory, /services/service, the node associated with it has instance name ref_threadfactory-bgp.
2630 . Issue merge /modules/module.
2631 . Enter the name bgp-threadpool.
2632 . Enter the type threadpool.
2633 . Select the appropriate case statement.
2634 . Enter the value for leaf <max-thread-count>: 100.
2635 . Enter the threadfactory for attribute threadfactory/type. This is with reference to /services/service/type, in other words, the service interface.
2636 . Enter ref_threadfactory-bgp.
2637 Server response must be an OK message.
2638 [start=9]
2639 . Issue commit.
2640 . Issue get-config source=running.
2641 Example output: +
2642 ----
2643 rpc-reply {
2644   data {
2645     modules {
2646       module  binding-broker-singleton {
2647         type binding-impl:binding-broker-impl-singleton
2648         name binding-broker-singleton
2649       }
2650       module  bgp-threadpool {
2651         type th-java:threadpool-fixed
2652         name bgp-threadpool
2653         threadFactory {
2654           type th:threadfactory
2655           name ref_threadfactory-bgp
2656         }
2657         max-thread-count 100
2658       }
2659       module  threadfactory-bgp {
2660         type th-java:threadfactory-naming
2661         name threadfactory-bgp
2662         name-prefix bgp
2663       }
2664     }
2665     services {
2666       service  th:threadpool {
2667         type th:threadpool
2668         instance  ref_bgp-threadpool {
2669           name ref_bgp-threadpool
2670           provider /modules/module[type='threadpool-fixed'][name='bgp-threadpool']
2671         }
2672       }
2673       service  th:threadfactory {
2674         type th:threadfactory
2675         instance  ref_threadfactory-bgp {
2676           name ref_threadfactory-bgp
2677           provider /modules/module[type='threadfactory-naming'][name='threadfactory-bgp']
2678         }
2679       }
2680       service  md-sal-binding:binding-broker-osgi-registry {
2681         type md-sal-binding:binding-broker-osgi-registry
2682         instance  ref_binding-broker-singleton {
2683           name ref_binding-broker-singleton
2684           provider /modules/module[type='binding-broker-impl-singleton'][name='binding-broker-singleton']
2685         }
2686       }
2687     }
2688   }
2689 }
2690 ----
2691 To see the actual netconf messages, use the logging arguments described at the top of this page. To validate that a threadpool has been created, a tool like VisualVM can be used.
2692
2693 ==== Logback configuration - Yuma
2694 This approach to configure logback will utilize a 3rd party cli netconf client from Yuma. We will modify existing console appender in logback and then call reset rpc on logback to clear its status list.
2695
2696 For initial configuration of the controller and startup parameters for yuma, see the threadpool example: https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:Threadpool[Threadpool configuration using Yuma].
2697
2698 Start the controller and yuma cli client as in the previous example.
2699
2700 There is no need to initialize the configuration module wrapping logback manually, since it creates a default instance. Therefore you should see the output containing logback configuration after the execution of get-config source=running command in yuma:
2701 ----
2702 rpc-reply {
2703   data {
2704     modules {
2705       module  singleton {
2706         type logging:logback
2707         name singleton
2708         console-appenders {
2709           threshold-filter ERROR
2710           name STDOUT
2711           encoder-pattern '%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n'
2712         }
2713         file-appenders {
2714           append true
2715           file-name logs/audit.log
2716           name audit-file
2717           encoder-pattern '%date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n'
2718         }
2719         loggers {
2720           level WARN
2721           logger-name org.opendaylight.controller.logging.bridge
2722         }
2723         loggers {
2724           level INFO
2725           logger-name audit
2726           appenders audit-file
2727         }
2728         loggers {
2729           level ERROR
2730           logger-name ROOT
2731           appenders STDOUT
2732           appenders opendaylight.log
2733         }
2734         loggers {
2735           level INFO
2736           logger-name org.opendaylight
2737         }
2738         loggers {
2739           level WARN
2740           logger-name io.netty
2741         }
2742         rolling-appenders {
2743           append true
2744           max-file-size 10MB
2745           file-name logs/opendaylight.log
2746           name opendaylight.log
2747           file-name-pattern logs/opendaylight.%d.log.zip
2748           encoder-pattern '%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n'
2749           clean-history-on-start false
2750           max-history 1
2751           rolling-policy-type TimeBasedRollingPolicy
2752         }
2753       }
2754       module  binding-broker-singleton {
2755         type binding-impl:binding-broker-impl-singleton
2756         name binding-broker-singleton
2757       }
2758     }
2759     services {
2760       service  md-sal-binding:binding-broker-osgi-registry {
2761         type md-sal-binding:binding-broker-osgi-registry
2762         instance  ref_binding-broker-singleton {
2763           name ref_binding-broker-singleton
2764           provider /modules/module[type='binding-broker-impl-singleton'][name='binding-broker-singleton']
2765         }
2766       }
2767     }
2768   }
2769 }
2770 ----
2771
2772 ===== Modifying existing console appender in logback
2773 . Start edit-config with merge option:
2774 ----
2775 merge /modules/module
2776 ----
2777 [start=2]
2778 . For Name of the module, enter *singleton*.
2779 . For Type, enter *logback*.
2780 . Pick the corresponding case statement with the name logback.
2781 We do not want to modify file-appenders, rolling-appenders and loggers lists, so the answer to questions from yuma is N (for no):
2782 ----
2783 Filling optional case /modules/module/configuration/logback:
2784 Add optional list 'file-appenders'?
2785 Enter Y for yes, N for no, or C to cancel: [default: Y]
2786 ----
2787 [start=5]
2788 . As we want to modify console-appenders, the answer to the question from Yuma is Y:
2789 ----
2790 Filling optional case /modules/module/configuration/logback:
2791 Add optional list 'console-appenders'?
2792 Enter Y for yes, N for no, or C to cancel: [default: Y]
2793 ----
2794 [start=6]
2795 . This will start a new configuration process for console appender and we will fill following values:
2796
2797 * <encoder-pattern> %date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n
2798 * <threshold-filter> INFO
2799 * <name> STDOUT
2800 [start=7]
2801 . Answer N to the next question.
2802 ----
2803 Add another list?
2804 Enter Y for yes, N for no, or C to cancel: [default: N]
2805 ----
2806 Notice that we changed the level for threshold-filter for STDOUT console appender from ERROR to INFO. Now issue a commit command to commit the changed configuration, and the response from get-config source=running command should look like this:
2807 ----
2808 rpc-reply {
2809   data {
2810     modules {
2811       module  singleton {
2812         type logging:logback
2813         name singleton
2814         console-appenders {
2815           threshold-filter INFO
2816           name STDOUT
2817           encoder-pattern '%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{36} - %msg%n'
2818         }
2819         file-appenders {
2820           append true
2821           file-name logs/audit.log
2822           name audit-file
2823           encoder-pattern '%date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n'
2824         }
2825         loggers {
2826           level WARN
2827           logger-name org.opendaylight.controller.logging.bridge
2828         }
2829         loggers {
2830           level INFO
2831           logger-name audit
2832           appenders audit-file
2833         }
2834         loggers {
2835           level ERROR
2836           logger-name ROOT
2837           appenders STDOUT
2838           appenders opendaylight.log
2839         }
2840         loggers {
2841           level INFO
2842           logger-name org.opendaylight
2843         }
2844         loggers {
2845           level WARN
2846           logger-name io.netty
2847         }
2848         rolling-appenders {
2849           append true
2850           max-file-size 10MB
2851           file-name logs/opendaylight.log
2852           name opendaylight.log
2853           file-name-pattern logs/opendaylight.%d.log.zip
2854           encoder-pattern '%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n'
2855           clean-history-on-start false
2856           max-history 1
2857           rolling-policy-type TimeBasedRollingPolicy
2858         }
2859       }
2860       module  binding-broker-singleton {
2861         type binding-impl:binding-broker-impl-singleton
2862         name binding-broker-singleton
2863       }
2864     }
2865     services {
2866       service  md-sal-binding:binding-broker-osgi-registry {
2867         type md-sal-binding:binding-broker-osgi-registry
2868         instance  ref_binding-broker-singleton {
2869           name ref_binding-broker-singleton
2870           provider /modules/module[type='binding-broker-impl-singleton'][name='binding-broker-singleton']
2871         }
2872       }
2873     }
2874   }
2875 }
2876 ----
2877 ==== Invoking RPCs
2878 *Invoking Reset RPC on logback* +
2879 The configuration module for logback exposes some information about its current state(list of logback status messages). This information can be accessed using get netconf operation or get command from yuma. Example response after issuing get command in yuma:
2880 ----
2881 rpc-reply {
2882   data {
2883     modules {
2884       module  singleton {
2885         type logging:logback
2886         name singleton
2887         status {
2888           message 'Found resource [configuration/logback.xml] at
2889 [file:/.../controller/opendaylight/distribution/opendaylight/target/distribution.opendaylight-
2890 osgipackage/opendaylight/configuration/logback.xml]'
2891           level INFO
2892           date 2479534352
2893         }
2894         status {
2895           message 'debug attribute not set'
2896           level INFO
2897           date 2479534441
2898         }
2899         status {
2900           message 'Will scan for changes in
2901 [[/.../controller/opendaylight/distribution/opendaylight/target/distribution.opendaylight-
2902 osgipackage/opendaylight/configuration/logback.xml]] 
2903 every 60 seconds.'
2904           level INFO
2905           date 2479534448
2906         }
2907         status {
2908           message 'Adding ReconfigureOnChangeFilter as a turbo filter'
2909           level INFO
2910           date 2479534448
2911         }
2912  ...
2913 ----
2914 Logback also exposes an rpc called reset that wipes out the list of logback status messages and to invoke an rpc with name reset on module named singleton of type logback, following command needs to be issued in yuma:
2915 ----
2916 reset context-instance="/modules/module[type='logback' and name='singleton']"
2917 ----
2918 After an ok response, issuing get command should produce response with empty logback status message list:
2919 ----
2920 rpc-reply {
2921   data {
2922     modules {
2923       module  singleton {
2924         type logging:logback
2925         name singleton
2926       }
2927     }
2928   }
2929 }
2930 ----
2931 This response confirms successful execution of the reset rpc on logback.
2932
2933 *Invoking shutdown RPC* +
2934 This command entered in yuma will shut down the server. If all bundles do not stop correctly within 10 seconds, it will force the process to exit.
2935 ----
2936 shutdown context-instance="/modules/module[type='shutdown' and name='shutdown']",input-secret="",max-wait-time="10000",reason="reason"
2937 ----
2938 === OpenDaylight Controller Configuration: Logback Examples
2939 ==== Logback Configuration Example
2940
2941 The Logback logger configuration is part of the config subsystem. This module allows changes to the Logback configuration at runtime. It is used here as an example to demonstrate the YANG to Java code generator and to show how the configuration transaction works. 
2942
2943 ==== Java code generation
2944 The logging configuration YANG module definition can be found in the config-logging.yang file. The code is generated by the yang-maven-plugin and yang-jmx-generator-plugin. The output java files are located as defined in the plugin configuration, where additional configuration parameters can be set. The logback module is defined as identity, with the base "config:module-type"; it does not provide or depend on any service interface. 
2945 ----
2946 identity logback {
2947     description
2948         "Actual state of logback configuration.";
2949     base config:module-type;
2950     config:java-name-prefix Logback;
2951 }
2952 ----
2953 The next logback module attributes are defined in the "/config:modules/config:module/config:configuration" augment as the snippet below shows. 
2954 ----
2955 augment "/config:modules/config:module/config:configuration" {
2956     case logback {
2957         when "/config:modules/config:module/config:type = 'logback'";
2958  
2959         list console-appenders {
2960  
2961             leaf encoder-pattern {
2962                 type string;
2963                 mandatory true;
2964             }
2965  
2966             leaf threshold-filter {
2967                 type string;
2968                 default 'ALL';
2969             }
2970  
2971             leaf name {
2972                 type string;
2973                 mandatory true;
2974             }
2975             config:java-name-prefix ConsoleAppenderTO;
2976         }
2977          ...
2978 ----
2979 Now LogbackModule and LogbackModuleFactory can be generated. In fact, three more java files related to this module will be generated. By the augment definition, TypeObjects too are generated (that is to say, ConsoleAppenderTO). They are regular java classes with getters and setters for arguments defined as leaves.
2980
2981 * *LogbackModuleMXBean* is the interface containing getters and setters for attributes defined in the configuration augment.
2982 * *AbstractLogbackModule* is the abstract java class, which implements Module, RuntimeBeanRegistratorAwareModule, and LogbackModuleMXBean. It contains almost all functionality, except validate and createInstance methods. 
2983 * *AbstractLogbackModuleFactory* is the abstract java class responsible for creating module instances. It implements the ModuleFactory interface.
2984 * *LogbackModule* class extends AbstractLogbackModule. It is located in a different place (source/main/java) and can be modified by the user, so that the abstract method is implemented and the validate method is overridden. 
2985 * *LogbackModuleFactory* class extends AbstractLogbackModuleFactory and overrides its instantiateModule methods.
2986 Next, the runtime bean is defined in the "/config:modules/config:module/config:state" augment. +
2987 ----
2988 augment "/config:modules/config:module/config:state" {
2989     case logback {
2990         when "/config:modules/config:module/config:type = 'logback'";
2991  
2992         rpcx:rpc-context-instance "logback-rpc";
2993  
2994         list status {
2995             config:java-name-prefix StatusTO;
2996  
2997             leaf level {
2998                 type string;
2999             }
3000  
3001             leaf message {
3002                 type string;
3003             }
3004  
3005             leaf date {
3006                 type uint32;
3007             }
3008         }
3009     }
3010 }
3011 ----
3012 * The *Generator* plugin creates another set of java files. 
3013 * *LogbackRuntimeMXBean* is the interface extending RuntimeBean. It contains the getter method for the argument defined in the augment. 
3014 * *LogbackRuntimeRegistrator* class serves as the registrator for runtime beans. 
3015 * *LogbackRuntimeRegistration* class serves as the registration ticket. An instance is returned after registration. 
3016
3017 The Logback config also defines logback-rpc with the reset method. It is also defined in the state augment, owing to the context. 
3018 ----
3019 identity logback-rpc;
3020 rpc reset {
3021     input {
3022         uses rpcx:rpc-context-ref {
3023             refine context-instance {
3024                 rpcx:rpc-context-instance logback-rpc;
3025             }
3026         }
3027     }
3028 }
3029 ----
3030 The Reset method is defined in the LogbackRuntimeMXBean interface.
3031
3032 ==== Logback configuration: Jolokia
3033
3034 To create configuration on the running OSGi server: Jolokia (http://www.jolokia.org/) is used as a JMX-HTTP bridge, which listens at http://localhost:8080/controller/nb/v2/jolokia and curl to request over HTTP. 
3035
3036 . Start the controller. Find more here: https://wiki.opendaylight.org/view/OpenDaylight_Controller:Pulling,_Hacking,_and_Pushing_the_Code_from_the_CLI 
3037 . Request Jolokia: 
3038 ----
3039 curl http://localhost:8080/controller/nb/v2/jolokia --user admin:admin
3040 ----
3041 The response must resemble the following: +
3042 ----
3043 {
3044     "timestamp": 1382425537,
3045     "status": 200,
3046     "request": {
3047         "type": "version"
3048     },
3049     "value": {
3050         "protocol": "7.0",
3051         "agent": "1.1.1",
3052         "info": {
3053             "product": "equinox",
3054             "vendor": "Eclipse",
3055             "version": "3.8.1.v20120830-144521"
3056         }
3057     }
3058 }
3059 ----
3060 Jolokia is working. 
3061 To configure Logback, first, create a configuration transaction. ConfigResgistryModule offers the operation beginConfig(), and to invoke it: 
3062 ----
3063 curl -X POST -H "Content-Type: application/json" -d '{"type":"exec","mbean":"org.opendaylight.controller:type=ConfigRegistry","arguments":[],"operation":"beginConfig"}' http://localhost:8080/controller/nb/v2/jolokia --user admin:admin
3064 ----
3065 The configuration transaction was created. The response received: +
3066 ----
3067 {
3068     "timestamp": 1383034210,
3069     "status": 200,
3070     "request": {
3071         "operation": "beginConfig",
3072         "mbean": "org.opendaylight.controller:type=ConfigRegistry",
3073         "type": "exec"
3074     },
3075     "value": {
3076         "objectName": "org.opendaylight.controller:TransactionName=ConfigTransaction-1-2,type=ConfigTransaction"
3077     }
3078 }
3079 ----
3080 At this stage, the transaction can be aborted, but we want to create the module bean to be configured. In the created ConfigTransaction call createModule method, the module identifier is logback, and the name must be singleton as only one instance of the Logback configuration is needed.
3081 ----
3082 curl -X POST -H "Content-Type: application/json" -d '{"type":"exec","mbean":"org.opendaylight.controller:TransactionName=ConfigTransaction-1-2,type=ConfigTransaction","arguments":["logback","singleton"],"operation":"createModule"}' http://localhost:8080/controller/nb/v2/jolokia --user admin:admin
3083 ----
3084 The LogbackModule bean was created. The response returned: 
3085 ----
3086 {
3087     "timestamp": 1383034580,
3088     "status": 200,
3089     "request": {
3090         "operation": "createModule",
3091         "mbean": "org.opendaylight.controller:TransactionName=ConfigTransaction-1-2,type=ConfigTransaction",
3092         "arguments": [
3093             "logback",
3094             "singleton"
3095         ],
3096         "type": "exec"
3097     },
3098     "value": {
3099         "objectName": "org.opendaylight.controller:TransactionName=ConfigTransaction-1-2,instanceName=singleton,moduleFactoryName=logback,type=Module"
3100     }
3101 }
3102 ----
3103 * The configuration bean attributes are set to values obtained from the loggers configuration, with which the server was started. To see attributes, request: 
3104 ----
3105 curl -X POST -H "Content-Type: application/json" -d '{"type":"read", "mbean":"org.opendaylight.controller:instanceName=singleton,TransactionName=ConfigTransaction-1-2,type=Module,moduleFactoryName=logback"}' http://localhost:8080/controller/nb/v2/jolokia --user admin:admin
3106 ----
3107 In the response body, the value contains all attributes (CompositeData) and its nested attribute values. 
3108 * Now, the proposed configuration can be committed.
3109 ----
3110 curl -X POST -H "Content-Type: application/json" -d '{"type":"exec","mbean":"org.opendaylight.controller:type=ConfigRegistry","arguments":["org.opendaylight.controller:instanceName=singleton,TransactionName=ConfigTransaction-1-2,type=Module,moduleFactoryName=logback"],"operation":"commitConfig"}' http://localhost:8080/controller/nb/v2/jolokia --user admin:admin
3111 ----
3112 The configuration was successfully validated and committed, and the module instance created.
3113 ----
3114 {
3115     "timestamp": 1383034793,
3116     "status": 200,
3117     "request": {
3118         "operation": "commitConfig",
3119         "mbean": "org.opendaylight.controller:type=ConfigRegistry",
3120         "arguments": [
3121             "org.opendaylight.controller:instanceName=singleton,TransactionName=ConfigTransaction-1-2,type=Module,moduleFactoryName=logback"
3122         ],
3123         "type": "exec"
3124     },
3125     "value": {
3126         "newInstances": [
3127             {
3128                 "objectName": "org.opendaylight.controller:instanceName=singleton,moduleFactoryName=logback,type=Module"
3129             }
3130         ],
3131         "reusedInstances": [],
3132         "recreatedInstances": []
3133     }
3134 }
3135 ----
3136 * The runtime bean was registered, and can provide the status information of the configuration and rpc operation reset. To see the status, try requesting:
3137 ----
3138 curl -X POST -H "Content-Type: application/json" -d '{"type":"read","mbean":"org.opendaylight.controller:instanceName=singleton,type=RuntimeBean,moduleFactoryName=logback"}' http://localhost:8080/controller/nb/v2/jolokia --user admin:admin
3139 ----
3140 The entire logback status is in the response body. 
3141
3142 * To invoke the rpc method reset: 
3143 ----
3144 curl -X POST -H "Content-Type: application/json" -d '{"type":"exec",
3145 "mbean":"org.opendaylight.controller:instanceName=singleton,type=RuntimeBean,moduleFactoryName=logback",
3146 "operation":"reset","arguments":[]}' http://localhost:8080/controller/nb/v2/jolokia --user admin:admin
3147 ----
3148 The answer:
3149 ----
3150 {
3151     "timestamp": 1383035001,
3152     "status": 200,
3153     "request": {
3154         "operation": "reset",
3155         "mbean": "org.opendaylight.controller:instanceName=singleton,moduleFactoryName=logback,type=RuntimeBean",
3156         "type": "exec"
3157     },
3158     "value": null
3159 }
3160 ----
3161 Now, the runtime bean status attribute will be empty: 
3162 ----
3163 {
3164     "timestamp": 1383035126,
3165     "status": 200,
3166     "request": {
3167         "mbean": "org.opendaylight.controller:instanceName=singleton,moduleFactoryName=logback,type=RuntimeBean",
3168         "type": "read"
3169     },
3170     "value": {
3171         "StatusTO": []
3172     }
3173 }
3174 ----
3175 ==== Logback configuration: Netconf
3176
3177 In this case, NETCONF RPCs are used to configure logback. The Netconf server listens at port 8383. To communicate over TCP, telnet is used. More about NETCONF is available at: http://tools.ietf.org/html/rfc6241. Netconf implementation is a part of the Controller - netconf-subsystem. The RPCs of Netconf are XML, and the operations are mapped to JMX operations. 
3178 * A server re-start is required. The procedure is the same as above. 
3179 * Open a terminal and connect to the server:
3180 ----
3181 telnet localhost 8383
3182 ----
3183 A Hello message received from the server contains the server capabilities and session-id. To establish connection to the client,send a hello message: 
3184 ----
3185 <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3186     <capabilities>
3187         <capability>urn:ietf:params:netconf:base:1.0</capability>
3188     </capabilities>
3189 </hello>
3190 ]]>]]>
3191 ----
3192 * With the connection created, the client and server can communicate. To see the running modules and services, send an RPC to the server:
3193 ----
3194 <rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3195     <get-config>
3196         <source>
3197             <running/>
3198         </source>
3199     </get-config>
3200 </rpc>
3201 ]]>]]>
3202 ----
3203
3204 * To configure logback, create a configuration transaction, and create a configuration module. It can be done in one step (in client point of view): 
3205 ----
3206 <rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3207     <edit-config>
3208         <target>
3209             <candidate/>
3210         </target>
3211         <default-operation>merge</default-operation>
3212         <config>
3213             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3214                 <module>
3215                     <name>singleton</name>
3216                     <type xmlns:logging="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
3217                         logging:logback
3218                     </type>
3219                 </module>
3220             </modules>
3221         </config>
3222     </edit-config>
3223 </rpc>
3224 ]]>]]>
3225 ----
3226
3227 If the configuration worked, the client receives a positive response: 
3228
3229 ----
3230 <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3231 <ok/>
3232 </rpc-reply>
3233 ]]>]]>
3234 ----
3235
3236 * The Logback configuration bean attributes contain values loaded from the running Logback configuration. Send a request to the server with an RPC:
3237 ----
3238 <rpc id="a" a="64" xmlnx="a:b:c:d" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3239     <get-config>
3240         <source>
3241             <candidate/>
3242         </source>
3243     </get-config>
3244 </rpc>
3245 ]]>]]>
3246 ----
3247
3248 * The reply includes the entire configuration that started the server. Assume that we want to change the RollingFileAppender named opendaylight.log attributes - maxFileSize, filename, and maxHistory. ( attribute of TimeBasedRollingPolicy). The proposed configuration: 
3249
3250 ----
3251 <rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3252     <edit-config>
3253         <target>
3254             <candidate/>
3255         </target>
3256         <default-operation>merge</default-operation>
3257         <config>
3258             <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3259                 <module>
3260                     <name>singleton</name>
3261                     <type xmlns:logging="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
3262                         logging:logback
3263                     </type>
3264                     <rolling-appenders xmlns="urn:opendaylight:params:xml:ns:yang:controller:logback:config">
3265                         <append>true</append>
3266                         <max-file-size>5MB</max-file-size>
3267                         <file-name>logs/opendaylight-new.log</file-name>
3268                         <name>opendaylight.log</name>
3269                         <file-name-pattern>logs/opendaylight.%d.log.zip</file-name-pattern>
3270                         <encoder-pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n</encoder-pattern>
3271                         <clean-history-on-start>false</clean-history-on-start>
3272                         <max-history>7</max-history>
3273                         <rolling-policy-type>TimeBasedRollingPolicy</rolling-policy-type>
3274                     </rolling-appenders>
3275                 </module>
3276             </modules>
3277         </config>
3278     </edit-config>
3279 </rpc>
3280 ]]>]]>
3281 ----
3282 This configuration is merged with the proposed module configuration. If it passes the validation process successfully, an "ok" reply is received. 
3283
3284 * The configuration bean is ready to be committed:
3285 ----
3286 <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3287     <commit></commit>
3288 </rpc>
3289 ]]>]]>
3290 ---- 
3291 If successful, the ok message is received obtained, and the logback configuration is set. To verify, look into the logs directory to find a new log file named opendaylight-new.log 
3292
3293 * Correctly close the session with the session-id: 
3294 ----
3295 <rpc message-id="2" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3296     <close-session xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"/>
3297 </rpc>
3298 ]]>]]>
3299 ----
3300 ===== Logback configuration - Yuma
3301
3302 For a yangcli-pro example, see the https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:User_guide[user guide]. 
3303
3304 === Opendaylight Controller: Configuration Logback.xml
3305 Logging in ODL container is done by means of http://logback.qos.ch/[Logback]. Comprehensive documentation is available at http://logback.qos.ch/documentation.html.
3306
3307 By default, logging messages are appended to stdout of the java process and to file logs/opendaylight.log. When debugging a problem it might be useful to increase logging level:
3308 ----
3309 <logger name="org.opendaylight.controller" level="DEBUG"/>
3310 ----
3311 Logger tags can be appended under root node <configuration/>. Name of logger is used to select all loggers to which specified rules should apply. Loggers are usually named after class in which they reside. The example above matches all loggers in controller - they all are starting with org.opendaylight.controller . There are 5 logging levels: TRACE,DEBUG,INFO, WARN, ERROR. Additionally one can specify which appenders should be used for given loggers. This might be helpful to redirect certain log messages to another file or send them to syslog or over SMTP. 
3312 == OpenDaylight Controller Configuration: Examples of Threadpool
3313
3314 === Configuration example of thread pools using yangcli-pro
3315
3316 For a yangcli-pro example, see the https://wiki.opendaylight.org/view/OpenDaylight_Controller:Config:Examples:User_guide[Examples User Guide].
3317
3318 === Configuration example of thread pools using telnet
3319 It is also possible to manipulate the configuration without the yuma cli. With just a telnet or ssh connection, it is possible to send the plain text containing netconf rpcs encoded in the xml format and achieve the same results as with yuma cli. 
3320
3321 This example reproduces the configuration of a threadpool and a threadfactory from the previous example using just a telnet connection. We can also use ssh connection, with the netconf rpcs sending procedure remaining the same. For detailed information about initial configuration for the controller as well as the configuration process, see the example using yuma cli. 
3322
3323 === Connecting to plaintext TCP socket
3324
3325 . Open a telnet connection:
3326 ----
3327 telnet 127.0.0.1 8383
3328 ----
3329 [start=2]
3330 . Open an ssh connection: 
3331 ----
3332 ssh netconf@127.0.0.1 -p 1830 -s netconf
3333 ----
3334 The password for user netconf is : netconf, and the separator for the messages is: +
3335 ----
3336 ]]>]]>
3337 ----
3338 Every message needs end with these 6 characters. 
3339
3340 The server sends a hello message: +
3341 ----
3342 <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3343 <capabilities>
3344 <capability>urn:ietf:params:netconf:base:1.0</capability>
3345 <capability>urn:ietf:params:netconf:capability:exi:1.0</capability>
3346 <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&amp;revision=2013-08-27</capability>
3347 <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&amp;revision=2013-11-07</capability>
3348 <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
3349 <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&amp;revision=2013-04-09</capability>
3350 <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
3351 <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05</capability>
3352 <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
3353 <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
3354 <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&amp;revision=2013-06-17</capability>
3355 <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
3356 <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&amp;revision=2013-11-19</capability>
3357 <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24</capability>
3358 <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
3359 <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&amp;revision=2013-04-05</capability>
3360 <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24</capability>
3361 <capability>urn:opendaylight:params:xml:ns:yang:controller:logback:config?module=config-logging&amp;revision=2013-07-16</capability>
3362 <capability>urn:opendaylight:params:xml:ns:yang:iana?module=iana&amp;revision=2013-08-16</capability>
3363 <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&amp;revision=2013-07-09</capability>
3364 <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
3365 <capability>http://netconfcentral.org/ns/toaster?module=toaster&amp;revision=2009-11-20</capability>
3366 <capability>urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&amp;revision=2013-08-19</capability>
3367 <capability>urn:opendaylight:params:xml:ns:yang:nps-concepts?module=nps-concepts&amp;revision=2013-09-30</capability>
3368 </capabilities>
3369  
3370 <session-id>4</session-id>
3371 </hello>
3372 ]]>]]>
3373 ----
3374 [start=3]
3375 . As the client, you must respond with a hello message: 
3376 ----
3377 <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3378     <capabilities>
3379         <capability>urn:ietf:params:netconf:base:1.0</capability>
3380     </capabilities>
3381 </hello>
3382 ]]>]]>
3383 ----
3384 Although there is no response to the hello message, the session is already established. 
3385
3386 === Configuring threadfactory
3387
3388 . The following is the Xml equivalent to *get-config source=running*: + 
3389 ----
3390 <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3391     <get-config>
3392         <source>
3393             <running/>
3394         </source>
3395     </get-config>
3396 </rpc>
3397 ]]>]]>
3398 ----
3399 The response containing the current configuration: +
3400 ----
3401 <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3402         <data>
3403                 <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3404                         <module>
3405                                 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl-singleton</type>
3406                                 <name>binding-broker-singleton</name>
3407                         </module>
3408                 </modules>
3409                 <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3410                         <service>
3411                                 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
3412                                 <instance>
3413                                         <name>ref_binding-broker-singleton</name>
3414                                         <provider>/modules/module[type='binding-broker-impl-singleton'][name='binding-broker-singleton']</provider>
3415                                 </instance>
3416                         </service>
3417                 </services>
3418         </data>
3419 </rpc-reply>]]>]]>
3420 ----
3421 [start=2]
3422 . To create an instance of threadfactory-naming with the name threadfactory-bgp, and the attribute name-prefix set to bgp, send the message: 
3423 ----
3424 <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3425         <edit-config>
3426                 <target>
3427                         <candidate/>
3428                 </target>
3429                 <default-operation>merge</default-operation>
3430                 <config>
3431                         <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3432                                 <module xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="merge">
3433                                         <name>threadfactory-bgp</name>
3434                                         <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">th-java:threadfactory-naming</type>
3435                                         <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">bgp</name-prefix>
3436                                 </module>
3437                         </modules>
3438                 </config>
3439         </edit-config>
3440 </rpc>]]>]]>
3441 ----
3442 [start=3]
3443 . To commit the threadfactory instance, send a commit message: 
3444 ----
3445 <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3446         <commit/>
3447 </rpc>]]>]]>
3448 ----
3449 The Netconf endpoint should respond with ok to edit-config, as well as the commit message: +
3450
3451 ----
3452 <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3453         <ok/>
3454 </rpc-reply>]]>]]>
3455 ----
3456 [start=4]
3457 . The response to the get-config message (the same as the first message sent in this example) should contain the commited instance of threadfactory-naming: 
3458 ----
3459 <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="101">
3460         <data>
3461                 <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3462                         <module>
3463                                 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl-singleton</type>
3464                                 <name>binding-broker-singleton</name>
3465                         </module>
3466  
3467                         <module>
3468                                 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory-naming</type>
3469                                 <name>threadfactory-bgp</name>
3470                                 <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">bgp</name-prefix>
3471                         </module>
3472                 </modules>
3473  
3474                 <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3475                         <service>
3476                                 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
3477                                 <instance>
3478                                         <name>ref_threadfactory-bgp</name>
3479                                         <provider>/modules/module[type='threadfactory-naming'][name='threadfactory-bgp']</provider>
3480                                 </instance>
3481                         </service>
3482                         <service>
3483                                 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-broker-osgi-registry</type>
3484                                 <instance>
3485                                         <name>ref_binding-broker-singleton</name>
3486                                         <provider>/modules/module[type='binding-broker-impl-singleton'][name='binding-broker-singleton']</provider>
3487                                 </instance>
3488                         </service>
3489                 </services>
3490         </data>
3491 </rpc-reply>]]>]]>
3492 ----
3493 === Configuring fixed threadpool
3494
3495 * To create an instance of *threadpool-fixed* , with the same configuration and the same dependency as before, send the following message: 
3496
3497 ----
3498 <rpc message-id="101" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
3499         <edit-config>
3500                 <target>
3501                         <candidate/>
3502                 </target>
3503                 <default-operation>merge</default-operation>
3504                 <config>
3505                         <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3506                                 <module xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="merge">
3507                                         <name>bgp-threadpool</name>
3508                                         <type xmlns:th-java="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">th-java:threadpool-fixed</type>
3509                                         <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">100</max-thread-count>
3510                                         <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">
3511                                                 <type xmlns:th="urn:opendaylight:params:xml:ns:yang:controller:threadpool">th:threadfactory</type>
3512                                                 <name>ref_th-bgp</name>
3513                                         </threadFactory>
3514                                 </module>
3515                         </modules>
3516  
3517                         <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
3518                         <service>
3519                                 <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
3520                                 <instance>
3521                                         <name>ref_th-bgp</name>
3522                                         <provider>/modules/module[type='threadfactory-naming'][name='threadfactory-bgp']</provider>
3523                                 </instance>
3524                         </service>
3525                 </services>
3526                 </config>
3527         </edit-config>
3528 </rpc>]]>]]>
3529 ----
3530 Notice the _services_ tag. If an instance is to be referenced as a dependency by another module, it needs to be placed under this tag as a service instance with a unique reference name. Tag _provider_ points to a unique instance that is already present in the config subsystem, or is created within the current edit-config operation. 
3531 The tag _name_ contains the reference name that can be referenced by other modules to create a dependency. In this case, a new instance of threadpool uses this reference in its configuration under the _threadFactory_ tag).
3532
3533 You should get an ok response again, and the configuration subsystem will inject the dependency into the threadpool. Now you can commit the configuration (ok response once more) and the process is finished. The config subsystem is now in the same state as it was at the end of the previous example.
3534
3535 === OpenDaylight Controller MD-SAL: Model reference
3536
3537 A full list of models, with links to the yang, descriptions, JavaDoc and REST APIs, see the OpenDaylight wiki page here: https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Model_Reference
3538
3539 ////
3540 ==== Model reference
3541
3542 ===== Yang extensions
3543 [cols="5*",^]
3544 |===
3545 | Model | Description | ODL component 2+^| API definition
3546
3547 |https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/yang-ext/src/main/yang/yang-ext.yang;a=blob[yang-ext.yang] | Yang Extensions for OpenDaylight | https://wiki.opendaylight.org/view/YANG_Tools:Main[YANG Tools] 
3548 | https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/yang-ext/target/apidocs/index.html[Javadoc] | https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/yang-ext/target/site/restconf/yang-ext.html[REST]
3549 |===
3550 ===== Base types
3551
3552 [options="header"]
3553 |===
3554 | Model | Description | ODL component | API definition
3555 | https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=concepts/src/main/yang/iana.yang;a=blob[iana.yang] | IANA definition of private enterprise number | https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS\PCEP] | --| --
3556 | https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/iana/iana-afn-safi/src/main/yang/iana-afn-safi@2013-07-04.yang;a=blob[iana-afn-safi yang] | Definitions for the 'AFN' and 'SAFI' IANA-registered enumerations http://datatracker.ietf.org/doc/draft-ietf-netmod-iana-afn-safi/[Draft] | https://wiki.opendaylight.org/view/YANG_Tools:Main[Yang tools] | https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/iana/iana-afn-safi/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/iana/iana-afn-safi/target/site/restconf/iana-afn-safi.html[REST]
3557 |https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/iana/iana-if-type/src/main/yang/iana-if-type@2013-07-04.yang;a=blob[iana-if-type yang] | Definitions for IANA-registered interface types http://datatracker.ietf.org/doc/rfc7224/[Draft-ietf-netmod-iana-if-type]| https://wiki.opendaylight.org/view/YANG_Tools:Main[Yang tools]| https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/iana/iana-if-type/target/apidocs/index.html[JavaDoc]| https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/iana/iana-if-type/target/site/restconf/iana-if-type.html[REST]
3558 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=concepts/src/main/yang/ieee754.yang;a=blob[ieee754.yang] | Definitions of IEEE754 floating point types | https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]| --| --
3559 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=concepts/src/main/yang/network-concepts.yang;a=blob[network-concepts.yang] | Base network types | https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS\PCEP] | --| --
3560 |===
3561 ===== Configuration subsystem
3562 [cols="5*",^]
3563 |===
3564 | Model | Description | ODL component 2+^| API definition
3565
3566 5+^|Base types
3567
3568 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/config-api/src/main/yang/config.yang;a=blob[config.yang] | Base YANG definitions for configuration subsystem | https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller] | https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/config-api/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/config-api/target/site/models/config.html[REST]
3569 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/config-api/src/main/yang/rpc-context.yang;a=blob[rpc-context.yang]| Base YANG definitions for rpc context reference used for rpc routing | https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/config-api/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/config-api/target/site/models/rpc-context.html[REST]
3570 5+^|Base modules
3571 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/netty-threadgroup-config/src/main/yang/netty-threadgroup.yang;a=blob[netty-threadgroup.yang]| Base YANG definitions for netty threadgroup implementation |  https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller] | https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/netty-threadgroup-config/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/netty-threadgroup-config/target/site/models/threadgroup.html[REST]
3572 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl-flexible.yang;a=blob[threadpool-impl-flexible.yang] |Base YANG definitions for thread services pure Java implementation| https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller] | https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/threadpool-config-impl/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/threadpool-config-impl/target/site/models/threadpool-impl-flexible.html[REST]
3573 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl-scheduled.yang;a=blob[threadpool-impl-scheduled.yang] | Base YANG definitions for thread services pure Java implementation | https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/threadpool-config-impl/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/threadpool-config-impl/target/site/models/threadpool-impl-scheduled.html[REST]
3574 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl.yang;a=blob[threadpool-impl.yang] | Base YANG definitions for thread services pure Java implementation | https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/threadpool-config-impl/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/threadpool-config-impl/target/site/models/threadpool-impl.html[REST]
3575 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/threadpool-config-impl/src/main/yang/threadpool-impl-fixed.yang;a=blob[threadpool-impl-fixed.yang] |Base YANG definitions for thread services pure Java implementation | https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/threadpool-config-impl/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/threadpool-config-impl/target/site/models/threadpool-impl-fixed.html[REST]
3576 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/netty-config-api/src/main/yang/netty.yang;a=blob[netty.yang] | Base YANG definitions for netty services | https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| JavaDoc| https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config/netty-config-api/target/site/models/netty.html[REST]
3577 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/threadpool-config-api/src/main/yang/threadpool.yang;a=blob[threadpool.yang]| Base YANG definitions for thread-related services | https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/threadpool-config-api/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config//threadpool-config-api/target/site/models//threadpool.html[REST]
3578 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/logback-config/src/main/yang/config-logging.yang;a=blob[config-logging.yang]| Base YANG definitions for logging service|https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/logback-config/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config//logback-config/target/site/models//config-logging.html[REST]
3579 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/shutdown-api/src/main/yang/shutdown.yang;a=blob[shutdown.yang]| Base YANG definitions for shutdown service| https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/shutdown-api/target/apidocs/index.html[JavaDoc] | https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config//shutdown-api/target/site/models//shutdown.html[REST]
3580 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/shutdown-impl/src/main/yang/shutdown-impl.yang;a=blob[ shutdown-impl.yang]|Base YANG definitions for shutdown implementation|https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/shutdown-impl/target/apidocs/index.html[JavaDoc] |https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config//shutdown-impl/target/site/models//shutdown-impl.html[REST]
3581 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/netty-timer-config/src/main/yang/netty-timer.yang;a=blob[ netty-timer.yang]| Base YANG definitions for netty timer implementation| https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]| https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/netty-timer-config/target/apidocs/index.html[JavaDoc]| https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config//netty-timer-config/target/site/models//netty-timer.html[REST]
3582 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/config/netty-event-executor-config/src/main/yang/netty-event-executor.yang;a=blob[ netty-event-executor.yang]| Base YANG definitions for netty event executor implementation| https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/config/netty-event-executor-config/target/apidocs/index.html[JavaDoc]| https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/config//netty-event-executor-config/target/site/models//netty-event-executor.html[REST]
3583 |===
3584 ===== MD-SAL modules
3585 [cols="5*",^]
3586 |===
3587 | Model | Description | ODL component 2+^| API definition
3588
3589 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-common.yang;a=blob[opendaylight-md-sal-common.yang]|Common definition for MD-SAL| https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/md-sal/sal-dom-api/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/sal-dom-api/target/site/models/opendaylight-md-sal-common.html[REST]
3590 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-dom-api/src/main/yang/opendaylight-md-sal-dom.yang;a=blob[ opendaylight-md-sal-dom.yang]| Service definition for Binding Aware MD-SAL| https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/md-sal/sal-dom-api/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/sal-dom-api/target/site/models/opendaylight-md-sal-dom.html[REST]
3591 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-remote/src/main/yang/opendaylight-md-sal-remote.yang;a=blob[ opendaylight-md-sal-remote.yang]|Definition of types related to Internet Assigned Numbers Authority|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|JavaDoc| REST
3592 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-binding-config/src/main/yang/opendaylight-md-sal-binding.yang;a=blob[opendaylight-md-sal-binding.yang]| Service definition for Binding Aware MD-SAL| https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--| https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/sal-binding-config/target/site/models/opendaylight-md-sal-binding.html[REST]
3593 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-netconf-connector/src/main/yang/odl-sal-netconf-connector-cfg.yang;a=blob[odl-sal-netconf-connector-cfg.yang]|Service definition for Binding Aware MD-SAL| https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/md-sal/sal-netconf-connector/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/sal-netconf-connector/target/site/models/odl-sal-netconf-connector-cfg.html[REST]
3594 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-binding-broker/src/main/yang/opendaylight-binding-broker-impl.yang;a=blob[ opendaylight-binding-broker-impl.yang]|Service definition for Binding Aware MD-SAL|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/md-sal/sal-binding-broker/target/apidocs/index.html[JavaDoc]|--
3595 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang;a=blob[ opendaylight-dom-broker-impl.yang]|Service definition for Binding Aware MD-SAL| https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/md-sal/sal-dom-broker/target/apidocs/index.html[JavaDoc]|--
3596 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/samples/toaster/src/main/yang/toaster.yang;a=blob[toaster.yang]|YANG version of the TOASTER-MIB|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL] |--|--
3597 |===
3598 ===== Netconf endpoint
3599 [cols="5*",^]
3600 |===
3601 | Model | Description | ODL component 2+^| API definition
3602
3603 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/netconf/ietf-netconf-monitoring/src/main/yang/ietf-netconf-monitoring.yang;a=blob[ietf-netconf-monitoring.yang]|NETCONF Monitoring Module (http://datatracker.ietf.org/doc/rfc6022/[RFC 6022]|https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]|https://jenkins.opendaylight.org/controller/job/controller-daily/ws/opendaylight/netconf/ietf-netconf-monitoring/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/netconf//ietf-netconf-monitoring/target/site/models//ietf-netconf-monitoring.html[REST]
3604 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/netconf/ietf-netconf-monitoring-extension/src/main/yang/ietf-netconf-monitoring-extension.yang;a=blob[ietf-netconf-monitoring-extension.yang]|NETCONF Monitoring Module extension for tcp transport type|https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main[Controller]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/netconf//ietf-netconf-monitoring-extension/target/site/models//ietf-netconf-monitoring-extension.html[REST]
3605 |===
3606 ===== Services
3607 [cols="5*",^]
3608 |===
3609 | Model | Description | ODL component 2+^| API definition
3610
3611 5+^|Inventory
3612 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-inventory/src/main/yang/opendaylight-inventory.yang;a=blob[opendaylight-inventory.yang]| The base (abstract) inventory model |https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-topology/target/site/models/opendaylight-topology.html[REST]
3613 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang;a=blob[ netconf-node-inventory.yang]|The netconf-specific augmentation of the base inventory model |https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-inventory/target/site/models/netconf-node-inventory.html[REST]
3614 5+^|Topology
3615
3616 |https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/ietf/ietf-topology/src/main/yang/network-topology@2013-10-21.yang;a=blob[network-topology.yang]|The base (abstract) network topology model http://datatracker.ietf.org/doc/draft-clemm-netmod-yang-network-topo/[Draft-clemm]|https://wiki.opendaylight.org/view/YANG_Tools:Main[Yang tools]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology/target/site/restconf/network-topology.html[REST]
3617 |https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/ietf/ietf-topology-l3-unicast-igp/src/main/yang/l3-unicast-igp-topology@2013-10-21.yang;a=blob[ l3-unicast-igp-topology.yang]|The base L3 IGP network topology model  http://datatracker.ietf.org/doc/draft-clemm-netmod-yang-network-topo/[Draft-clemm]|https://wiki.opendaylight.org/view/YANG_Tools:Main[Yang tools]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology-l3-unicast-igp/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology-l3-unicast-igp/target/site/restconf/l3-unicast-igp-topology.html[REST]
3618 |https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/ietf/ietf-topology-isis/src/main/yang/isis-topology@2013-10-21.yang;a=blob[isis-topology.yang]|Network topology data types specific to IS-IS (http://datatracker.ietf.org/doc/draft-clemm-netmod-yang-network-topo/[Draft clemm])|https://wiki.opendaylight.org/view/YANG_Tools:Main[Yang tools]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology-isis/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology-isis/target/site/restconf/isis-topology.html[REST]
3619 |https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/ietf/ietf-topology-ospf/src/main/yang/ospf-topology@2013-10-21.yang;a=blob[ospf-topology.yang]|Network topology data types specific to OSPF (http://datatracker.ietf.org/doc/draft-clemm-netmod-yang-network-topo/[Draft clemm])|https://wiki.opendaylight.org/view/YANG_Tools:Main[Yang tools]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology-ospf/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-topology-ospf/target/site/restconf/ospf-topology.html[REST]
3620 |https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;f=model/ietf/ietf-ted/src/main/yang/ted@2013-10-21.yang;a=blob[ted.yang]|Data types for the Traffic Engineering Database (http://datatracker.ietf.org/doc/draft-clemm-netmod-yang-network-topo/[Draft clemm])|https://wiki.opendaylight.org/view/YANG_Tools:Main[Yang tools]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-ted/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/yangtools/job/yangtools-merge/lastSuccessfulBuild/artifact/model/ietf/ietf-ted/target/site/restconf/ted.html[REST]
3621 | https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=topology/segment-routing/src/main/yang/topology-tunnel-sr.yang;a=blob[topology-tunnel-sr.yang]|Segment Routing extensions to base tunnel topology model.|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS\PCEP] |--|--
3622 5+^|Model topology
3623 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang;a=blob[opendaylight-topology.yang]|Opendaylight-topology|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-topology/target/site/models/opendaylight-topology.html[REST]
3624 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang;a=blob[opendaylight-topology.yang]|Opendaylight-topology-inventory|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-topology/target/site/models/opendaylight-topology-inventory.html[REST]
3625 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-topology/src/main/yang/opendaylight-topology.yang;a=blob[opendaylight-topology.yang]|Opendaylight-topology-view|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-topology/target/site/models/opendaylight-topology-view.html[REST]
3626 |===
3627 ===== OpenFlow services
3628 [cols="5*",^]
3629 |===
3630 | Model | Description | ODL component 2+^| API definition
3631
3632 5+^|Flow base types
3633 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-action-types.yang;a=blob[opendaylight-action-types.yang]|Data types for OpenFlow action structures(https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.1.pdf[O.F 1.3.1 Section A 3.4.2]|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-action-types.html[REST]
3634 | https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-flow-types.yang;a=blob[ opendaylight-flow-types.yang]|Data types for programming flows (match, action, instruction, group, meter)|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-flow-types.html[REST]
3635 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-group-types.yang;a=blob[opendaylight-group-types.yang]|Data types for OpenFlow groups (https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.1.pdf[OF 1.3.1 Section 5.6])|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-group-types.html[REST]
3636 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-match-types.yang;a=blob[opendaylight-match-types.yang]|Opendaylight-match-types|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-match-types.html[REST]
3637 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-meter-types.yang;a=blob[opendaylight-meter-types.yang]|Data types for OpenFlow meter structures (https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.1.pdf[OF 1.3.1 Section 5.7])|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-meter-types.html[REST]
3638 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-port-types.yang;a=blob[opendaylight-port-types.yang]|Data types for OpenFlow port structures (https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.1.pdf[OF 1.3.1 Section A.2.1])|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-port-types.html[REST]
3639 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-queue-types.yang;a=blob[opendaylight-queue-types.yang]|Data types for OpenFlow action structures (https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.1.pdf[OF 1.3.1 Section A 3.6])|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-queue-types.html[REST]
3640 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-base/src/main/yang/opendaylight-table-types.yang;a=blob[opendaylight-table-types.yang]|Data types for table programming (https://www.opennetworking.org/images/stories/downloads/sdn-resources/onf-specifications/openflow/openflow-spec-v1.3.1.pdf[OF 1.3.1 Section 5])|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-base/target/site/models/opendaylight-table-types.html[REST]
3641 5+^|Flow service
3642 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-capable-transaction.yang;a=blob[flow-capable-transaction.yang]|flow-capable-transaction| https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-service/target/site/models/flow-capable-transaction.html[REST]
3643 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-errors.yang;a=blob[flow-errors.yang]|Flow errors|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-service/target/site/models/flow-errors.html[REST]
3644 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-node-inventory.yang;a=blob[flow-node-inventory.yang]|flow-node-inventory |https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-service/target/site/models/flow-node-inventory.html[REST]
3645 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-topology-discovery.yang;a=blob[flow-topology-discovery.yang]|flow-topology-discovery |https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-service/target/site/models/flow-topology-discovery.html[REST]
3646 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-service/src/main/yang/packet-processing.yang;a=blob[packet-processing.yang]|packet-processing |https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-service/target/site/models/packet-processing.html[REST]
3647 5+^|Flow statistics
3648
3649 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-statistics.yang;a=blob[opendaylight-flow-statistics.yang]|individual and aggregate flow statistics APIs and notification interfaces | https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-statistics/target/site/models/opendaylight-flow-statistics.html[REST]
3650 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-flow-table-statistics.yang;a=blob[opendaylight-flow-table-statistics.yang]|Flow table statistics collection APIs and notification interfaces |https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-statistics/target/site/models/opendaylight-flow-table-statistics.html[REST]
3651 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-group-statistics.yang;a=blob[opendaylight-group-statistics.yang]|Group stats collection APIs and notification interfaces|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-statistics/target/site/models/opendaylight-group-statistics.html[REST]
3652 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-meter-statistics.yang;a=blob[opendaylight-meter-statistics.yang]|Meter collection APIs and notification interfaces |https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-statistics/target/site/models/opendaylight-meter-statistics.html[REST]
3653 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-port-statistics.yang;a=blob[opendaylight-port-statistics.yang]|Node connector stats collection APIs and notification interfaces|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-statistics/target/site/models/opendaylight-port-statistics.html[REST]
3654 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-queue-statistics.yang;a=blob[opendaylight-queue-statistics.yang]|Queue statistics collection APIs and notification interfaces|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-statistics/target/site/models/opendaylight-queue-statistics.html[REST]
3655 |https://git.opendaylight.org/gerrit/gitweb?p=controller.git;f=opendaylight/md-sal/model/model-flow-statistics/src/main/yang/opendaylight-statistics-types.yang;a=blob[opendaylight-statistics-types.yang]|Generic stats type definitions (Node Connector, Flow, Group, Meter, Queue etc.)|https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL[MD-SAL]|--|https://jenkins.opendaylight.org/controller/job/controller-merge/lastSuccessfulBuild/artifact/opendaylight/md-sal/model/model-flow-statistics/target/site/models/opendaylight-statistics-types.html[REST]
3656 |===
3657 ===== Affinity services
3658 [cols="5*",^]
3659 |===
3660 | Model | Description | ODL component 2+^| API definition
3661
3662 |https://git.opendaylight.org/gerrit/gitweb?p=affinity.git;f=affinity/yang/src/main/yang/affinity.yang;a=blob[affinity.yang]|Affinity|https://wiki.opendaylight.org/view/Project_Proposals:Affinity_Metadata_Service[Affinity metadata services]|--|--
3663 |===
3664 ===== BGPPCEP
3665 [cols="5*",^]
3666 |===
3667 5+^|BGP models
3668 | Model | Description | ODL component 2+^| API definition
3669
3670 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=bgp/concepts/src/main/yang/bgp-types.yang;a=blob[bgp-types.yang]|Contains the base concepts contained in http://datatracker.ietf.org/doc/rfc4271/[RFC 4271] and http://datatracker.ietf.org/doc/rfc4760/[RFC 4760]|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3671 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=bgp/parser-api/src/main/yang/bgp-message.yang;a=blob[bgp-message.yang]|Contains the base data model of a BGP message (http://datatracker.ietf.org/doc/rfc4271/[RFC 4271] and (http://datatracker.ietf.org/doc/rfc4893/[RFC 4893]|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3672 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=bgp/parser-api/src/main/yang/bgp-multiprotocol.yang;a=blob[bgp-multiprotocol.yang]|Base data model of a BGP message (http://datatracker.ietf.org/doc/rfc4271/[RFC 4271]|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3673 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=bgp/linkstate/src/main/yang/bgp-linkstate.yang;a=blob[bgp-linkstate.yang]|Base data model of a BGP message (http://datatracker.ietf.org/doc/rfc4271/[RFC 4271]|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3674 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=bgp/rib-api/src/main/yang/bgp-rib.yang;a=blob[bgp-rib.yang]|Contains the concept of a Routing Information Base, as defined by http://datatracker.ietf.org/doc/rfc4271/[RFC 4271]|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3675 5+^|PCEP models 
3676 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=pcep/ietf-stateful02/src/main/yang/odl-pcep-crabbe-initiated00.yang;a=blob[odl-pcep-crabbe-initiated00.yang]|Data model for PCEP extensions defined in http://tools.ietf.org/html/draft-crabbe-pce-pce-initiated-lsp-00[Draft Crabbe]|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3677 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=pcep/api/src/main/yang/pcep-message.yang;a=blob[pcep-message.yang]|Base data model the the PCEP message http://datatracker.ietf.org/doc/rfc5440/[RFC 5440], https://datatracker.ietf.org/doc/rfc5520/[RFC 5520], and http://datatracker.ietf.org/doc/rfc6006/[1]|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3678 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=pcep/api/src/main/yang/pcep-message.yang;a=blob[pcep-message.yang[pcep-message.yang]|Base data types for the PCEP message (http://datatracker.ietf.org/doc/rfc5440/[RFC 5440], https://datatracker.ietf.org/doc/rfc5520/[RFC 5520], and http://datatracker.ietf.org/doc/rfc6006/[2])|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3679 5+^|RSVP models
3680
3681 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=rsvp/api/src/main/yang/rsvp.yang;a=blob[rsvp.yang]|Contains the definition of types related to Resource Reservation Protocol (RSVP)|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3682 5+^|PCEP topology models 
3683
3684 | https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=pcep/topology-api/src/main/yang/network-topology-pcep.yang;a=blob[network-topology-pcep.yang]|PCEP extensions to base topology model|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3685 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=pcep/topology-api/src/main/yang/network-topology-pcep-programming.yang;a=blob[network-topology-pcep-programming.yang]|PCEP extensions to base topology model|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3686 5+^|PCEP tunnel topology models 
3687 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=pcep/tunnel-api/src/main/yang/topology-tunnel-pcep.yang;a=blob[topology-tunnel-pcep.yang]|PCEP extensions to base tunnel topology model|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3688 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=pcep/tunnel-api/src/main/yang/topology-tunnel-pcep-programming.yang;a=blob[topology-tunnel-pcep-programming.yang]|Programming extensions for tunnel topologies|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3689 5+^|Programming models
3690 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=programming/api/src/main/yang/programming.yang;a=blob[programming.yang]|The basic tunnel programming model|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]
3691 |--|--
3692 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=programming/topology-api/src/main/yang/network-topology-programming.yang;a=blob[network-topology-programming.yang]|Programming extensions for tunnel topologies|https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3693 |https://git.opendaylight.org/gerrit/gitweb?p=bgpcep.git;f=programming/tunnel-api/src/main/yang/topology-tunnel-programming.yang;a=blob[topology-tunnel-programming.yang]|Programming extensions for tunnel topologies|
3694 https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main[BGP-LS PCEP]|--|--
3695 |===
3696 ===== Plugins
3697 [cols="5*",^]
3698 |===
3699 5+^|OpenFlow protocol library
3700 | Model | Description | ODL component 2+^| API definition
3701
3702 |https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;f=openflow-protocol-api/src/main/yang/openflow-action.yang;a=blob[openflow-action.yang]|Base Openflow actions|https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main[OpenFlowJava]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-merge/org.opendaylight.openflowjava$openflow-protocol-api/ws/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-verify/ws/openflow-protocol-api/target/site/restconf/openflow-action.html[REST]
3703 |https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;f=openflow-protocol-api/src/main/yang/openflow-augments.yang;a=blob[openflow-augments.yang]|Object augmentations|https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main[OpenFlow Java]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-merge/org.opendaylight.openflowjava$openflow-protocol-api/ws/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-verify/ws/openflow-protocol-api/target/site/restconf/openflow-augments.html[REST]
3704 |https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;f=openflow-protocol-api/src/main/yang/openflow-extensible-match.yang;a=blob[openflow-extensible-match.yang]|Openflow OXM match|
3705 https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main[OpenFlow Java]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-merge/org.opendaylight.openflowjava$openflow-protocol-api/ws/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-verify/ws/openflow-protocol-api/target/site/restconf/openflow-extensible-match.html[REST]
3706 |https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;f=openflow-protocol-api/src/main/yang/openflow-instruction.yang;a=blob[openflow-instruction.yang]|Base Openflow instructions|https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main[OpenFlowJava]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-merge/org.opendaylight.openflowjava$openflow-protocol-api/ws/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-verify/ws/openflow-protocol-api/target/site/restconf/openflow-instruction.html[REST]
3707 |https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;f=openflow-protocol-api/src/main/yang/openflow-protocol.yang;a=blob[openflow-protocol.yang]|Openflow Protocol messages|https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main[OpenFlowJava]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-merge/org.opendaylight.openflowjava$openflow-protocol-api/ws/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-verify/ws/openflow-protocol-api/target/site/restconf/openflow-protocol.html[REST]
3708 |https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;f=openflow-protocol-api/src/main/yang/openflow-types.yang;a=blob[openflow-types.yang]|Common Openflow specific types|https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main[OpenFlowJava]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-merge/org.opendaylight.openflowjava$openflow-protocol-api/ws/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-verify/ws/openflow-protocol-api/target/site/restconf/openflow-types.html[REST]
3709 |https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;f=openflow-protocol-api/src/main/yang/system-notifications.yang;a=blob[system-notifications.yang]|System notification objects|https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main[OpenFlowJava]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-merge/org.opendaylight.openflowjava$openflow-protocol-api/ws/target/apidocs/index.html[JavaDoc]|https://jenkins.opendaylight.org/openflowjava/job/openflowjava-verify/ws/openflow-protocol-api/target/site/restconf/system-notifications.html[REST]
3710 |===
3711 ////