Developing apps on the OpenDaylight controller
==============================================
-This section provides information that is required to develop apps on
-the OpenDaylight controller.
-
-You can either develop apps within the controller using the model-driven
-SAL (MD-SAL) archetype or develop external apps and use the RESTCONF to
-communicate with the controller.
+This section provides the information required to develop apps on
+an OpenDaylight controller. Apps can be developed either within the
+controller using a Model-Driven SAL (MD-SAL) archetype or via an
+external app using the RESTCONF API to communicate with the controller.
Overview
--------
-This section enables you to get started with app development within the
-OpenDaylight controller. In this example, you perform the following
-steps to develop an app.
+This section starts app development within an OpenDaylight controller.
+
+Perform the following steps to develop an app:
1. Create a local repository for the code using a simple build process.
2. Start the OpenDaylight controller.
-3. Test a simple remote procedure call (RPC) which you have created
- based on the principle of *hello world*.
+3. Test a simple remote procedure call (RPC) that was created based on
+ the principle of *hello world*.
Prerequisites
-------------
-This example requires the following.
+The following are the prerequires for app creation:
-- A development environment with following set up and working correctly
+- A development environment with the following setup and working correctly
from the shell:
- Maven 3.5.2 or later
- Java 11-compliant JDK
- - An appropriate Maven settings.xml file. A simple way to get the
+ - An appropriate Maven settings.xml file. One way to get the
default OpenDaylight settings.xml file is:
.. code:: shell
.. note::
- If you are using Linux or Mac OS X as your development OS, your
- local repository is ~/.m2/repository. For other platforms the local
- repository location will vary.
+ For Linux or Mac OS X development operating systems, the default local
+ repository is ~/.m2/repository. For other platforms, the default local
+ repository location varies.
-Building an example module
+Building an Example module
--------------------------
-To develop an app perform the following steps.
+Perform the following steps to develop an app:
1. Create an *Example* project using Maven and an archetype called the
- *opendaylight-startup-archetype*. If you are downloading this project
- for the first time, then it will take sometime to pull all the code
- from the remote repository.
+ *opendaylight-startup-archetype*. For first time downloads, this project
+ will take some time to pull all the code from the remote repository.
.. code:: shell
* - Aluminium Development
- 1.4.0-SNAPSHOT
-2. Update the properties values as follows. Ensure that the values for
- the *groupId* and the *artifactId* are in **lower case**.
+2. Update the properties values. Ensure that the values for the groupId and
+ the artifactId are in lower case.
.. code:: text
Define value for property 'copyright': Copyright (c) 2021 Yoyodyne, Inc.
[INFO] Using property: copyrightYear = 2021
-3. Accept the default value of classPrefix that is,
+3. Accept the default value of classPrefix, that is:
``(${artifactId.substring(0,1).toUpperCase()}${artifactId.substring(1)})``.
The classPrefix creates a Java Class Prefix by capitalizing the first
character of the artifactId.
.. note::
- Depending on your development machine’s specification this might
- take a little while. Ensure that you are in the project’s root
- directory, ``example/``, and then issue the build command, shown
- below.
+ Build time varies depending on the development machine specification.
+ Ensure that you are in the project’s root directory (example/,) and then
+ issue the the following build command.
.. code:: shell
mvn clean install
-5. Start the *example* project for the first time.
+5. Initialize the *example* project.
.. code:: shell
ls
./karaf
-6. Wait for the karaf cli that appears as follows. Wait for OpenDaylight
- to fully load all the components. This can take a minute or two after
- the prompt appears. Check the CPU on your dev machine, specifically
- the Java process to see when it calms down.
+6. Wait for the Karaf CLI to appear. Wait for OpenDaylight to fully load
+ all components. This can take a minute or two after the prompt appears.
+ Check the CPU on the dev machine, specifically the Java process to see
+ when it slows down.
.. code:: shell
opendaylight-user@root>
7. Verify if the “example” module is built and search for the log entry
- which includes the entry *ExampleProvider Session Initiated*.
+ that includes the entry *ExampleProvider Session Initiated*.
.. code:: shell
log:display | grep Example
-8. Shutdown OpenDaylight through the console by using the following
- command.
+8. Enter the following command to shutdown OpenDaylight through the console:
.. code:: shell
--------------------------------
1. Build a *hello* example from the Maven archetype *opendaylight-startup-archetype*,
- same as above.
+ same as what was done in the previous steps.
-2. Now view the entry point to understand where the log line came from. The
- entry point is in the impl project:
+2. View the entry point to understand the origins of the log line. The
+ entry point starts in the ./impl project:
.. code:: shell
impl/src/main/java/org/opendaylight/hello/impl/HelloProvider.java
-3. Add any new things that you are doing in your implementation by
- using the ``HelloProvider.init`` method. It's analogous to
- an Activator.
+3. Add any new content that you are doing in your implementation by
+ using the ``HelloProvider.init`` method. It is analogous to an Activator.
.. code:: java
cd api/src/main/yang/
-2. Edit ``hello.yang`` as follows. In the following example, we are adding
+2. Edit the ``hello.yang`` file. In the following example, we are adding
the code in a YANG module to define the *hello-world* RPC:
.. code::
}
}
-3. Return to the ``hello/api`` directory and build your API as follows.
+3. Return to the hello/api directory. Do the following to build the API:
.. code:: shell
Implement the HelloWorld RPC API
--------------------------------
-1. Define the HelloService, which is invoked through the *hello-world*
- API.
+1. Define the HelloService that was invoked through the *hello-world* API.
.. code:: shell
</blueprint>
-3. Optionally, you can also build the Java classes which will register
- the new RPC. This is useful to test the edits you have made to
+3. Optionally, users can build the Java classes that will register
+ the new RPC. This is useful to test the edits that were made to
``HelloProvider.java``.
.. code:: shell
cd ../
-5. Build the entire *hello* again, which will pickup the changes you
- have made and build them into your project:
+5. Build the entire *hello* again. This will pickup the new changes,
+ and then build them into the project:
.. code:: shell
Test the *hello-world* RPC via REST
-----------------------------------
-There are a lot of ways to test your RPC. Following are some examples.
+There are a lot of ways to test a RPC. The following are a few examples.
1. Using the API Explorer through HTTP
Using a browser REST client
~~~~~~~~~~~~~~~~~~~~~~~~~~~
-| For example, use the following information in the Firefox plugin
- *RESTClient*
- `https://github.com/chao/RESTClient <https://github.com/chao/RESTClient>`_
+Next, use a browser to POST a REST client request.
+For example, use the following information in the Firefox plugin:
+
+*RESTClient* `https://github.com/chao/RESTClient <https://github.com/chao/RESTClient>`_
::
YANG Tools is set of libraries and tooling providing support for use
`YANG <https://tools.ietf.org/html/rfc6020>`__ for Java (or other
-JVM-based language) projects and applications.
+JVM-based language) projects and applications. The YANG Tools provides
+following features in OpenDaylight:
-YANG Tools provides following features in OpenDaylight:
-
-- parsing of YANG sources and semantic inference of relationship across
+- Parsing of YANG sources and semantic inference of relationship across
YANG models as defined in
`RFC6020 <https://tools.ietf.org/html/rfc6020>`__
-- representation of YANG-modeled data in Java
+- Representation of YANG-modeled data in Java
- **Normalized Node** representation - DOM-like tree model, which
uses conceptual meta-model more tailored to YANG and OpenDaylight
use-cases than a standard XML DOM model allows for.
-- serialization / deserialization of YANG-modeled data driven by YANG
+- Serialization / deserialization of YANG-modeled data driven by YANG
models
- XML - as defined in
- JSON - as defined in
`draft-lhotka-netmod-yang-json-01 <https://tools.ietf.org/html/rfc6020>`__
- - support for third-party generators processing YANG models.
+ - Support for third-party generators processing YANG models.
Architecture
~~~~~~~~~~~~
-YANG Tools project consists of following logical subsystems:
+YANG tools consist of the following logical subsystems:
+
+.. list-table:: **YANG Tools**
+ :widths: 20 50
+ :header-rows: 1
-- **Commons** - Set of general purpose code, which is not specific to
- YANG, but is also useful outside YANG Tools implementation.
+ * - Tool
+ - Description
+ * - **Commons**
+ - Set of general purpose code, which is not specific to
+ YANG, but is also useful outside YANG Tools implementation.
-- **YANG Model and Parser** - YANG semantic model and lexical and
- semantic parser of YANG models, which creates in-memory
- cross-referenced represenation of YANG models, which is used by other
- components to determine their behaviour based on the model.
+ * - **YANG Model and Parser**
+ - YANG semantic model and lexical and
+ semantic parser of YANG models, which creates in-memory
+ cross-referenced representation of YANG models, which is used by other
+ components to determine their behavior based on the model.
-- **YANG Data** - Definition of Normalized Node APIs and Data Tree
- APIs, reference implementation of these APIs and implementation of
- XML and JSON codecs for Normalized Nodes.
+ * - **YANG data**
+ - Definition of Normalized Node APIs and Data Tree
+ APIs, reference implementation of these APIs and implementation of
+ XML and JSON codecs for Normalized Nodes.
-- **YANG Maven Plugin** - Maven plugin which integrates YANG parser
- into Maven build lifecycle and provides code-generation framework for
- components, which wants to generate code or other artefacts based on
- YANG model.
+ * - **YANG Maven Plugin**
+ - Maven plugin which integrates YANG parser
+ into Maven build lifecycle and provides code-generation framework for
+ components, which wants to generate code or other artefacts based on YANG model.
Concepts
~~~~~~~~
YANG Parser
^^^^^^^^^^^
-Yang Statement Parser works on the idea of statement concepts as defined
+YANG Statement Parser works on the idea of statement concepts as defined
in RFC6020, section 6.3. We come up here with basic ModelStatement and
StatementDefinition, following RFC6020 idea of having sequence of
statements, where every statement contains keyword and zero or one
argument. ModelStatement is extended by DeclaredStatement (as it comes
from source, e.g. YANG source) and EffectiveStatement, which contains
-other substatements and tends to represent result of semantic processing
+other sub-statements and tends to represent result of semantic processing
of other statements (uses, augment for YANG). IdentifierNamespace
represents common superclass for YANG model namespaces.
-Input of the Yang Statement Parser is a collection of
+Input of the YANG Statement Parser is a collection of
StatementStreamSource objects. StatementStreamSource interface is used
for inference of effective model and is required to emit its statements
using supplied StatementWriter. Each source (e.g. YANG source) has to be
process.
Currently, there are two implementations of StatementStreamSource in
-Yangtools:
+YANGtools:
- YangStatementSourceImpl - intended for yang sources
- YinStatementSourceImpl - intended for yin sources
-YANG Data API
+YANG data API
^^^^^^^^^^^^^
Class diagram of yang data API
.. figure:: images/yang-data-api.png
- YANG Data API
+ YANG data API
-YANG Data Codecs
+YANG data Codecs
^^^^^^^^^^^^^^^^
Codecs which enable serialization of NormalizedNodes into YANG-modeled
First, StatementStreamSource objects with two constructor arguments
should be instantiated: path to the yang source file (which is a regular
-String object) and a boolean which determines if the path is absolute or
+String object) and a Boolean which determines if the path is absolute or
relative.
Next comes the initiation of new yang parsing cycle - which is
Then you should feed yang sources to it by calling method addSources()
that takes one or more StatementStreamSource objects as arguments.
-Finally you call the method buildEffective() on the reactor object which
+Finally, you call the method buildEffective() on the reactor object which
returns EffectiveSchemaContext (that is a concrete implementation of
SchemaContext). Now you are ready to work with contents of the added
yang sources.
has a semantic version compatible with the default one, for example
0.0.0, 0.1.3, 0.3.5 and so on.
-Working with YANG Data
+Working with YANG data
~~~~~~~~~~~~~~~~~~~~~~
-If you want to work with YANG Data you are going to need NormalizedNode
-objects that are specified in the YANG Data API. NormalizedNode is an
-interface at the top of the YANG Data hierarchy. It is extended through
+If you want to work with YANG data, you are going to need NormalizedNode
+objects that are specified in the YANG data API. NormalizedNode is an
+interface at the top of the YANG data hierarchy. It is extended through
sub-interfaces which define the behaviour of specific NormalizedNode
types like AnyXmlNode, ChoiceNode, LeafNode, ContainerNode, etc.
-Concrete implemenations of these interfaces are defined in
+Concrete implementations of these interfaces are defined in
yang-data-impl module. Once you have one or more NormalizedNode
instances, you can perform CRUD operations on YANG data tree which is an
in-memory database designed to store normalized nodes in a tree-like
structure.
-In some cases it is clear which NormalizedNode type belongs to which
+In some cases it, is clear which NormalizedNode type belongs to which
yang statement (e.g. AnyXmlNode, ChoiceNode, LeafNode). However, there
are some normalized nodes which are named differently from their yang
counterparts. They are listed below:
-- LeafSetNode - leaf-list
-
-- OrderedLeafSetNode - leaf-list that is ordered-by user
-
-- LeafSetEntryNode - concrete entry in a leaf-list
-
-- MapNode - keyed list
-
-- OrderedMapNode - keyed list that is ordered-by user
-
-- MapEntryNode - concrete entry in a keyed list
-
-- UnkeyedListNode - unkeyed list
-
-- UnkeyedListEntryNode - concrete entry in an unkeyed list
-
-In order to create a concrete NormalizedNode object you can use the
-utility class Builders or ImmutableNodes. These classes can be found in
-yang-data-impl module and they provide methods for building each type of
-normalized node. Here is a simple example of building a normalized node:
+.. list-table:: **Normalized Nodes**
+ :widths: auto
+ :header-rows: 1
+
+ * - Node
+ - Description
+ * - **LeafSetNode**
+ - Leaf-list
+ * - **OrderedLeafSetNode**
+ - Leaf-list that is ordered-by user
+ * - **LeafSetEntryNode**
+ - Concrete entry in a leaf-list
+ * - **MapNode**
+ - Keyed list
+ * - **OrderedMapNode**
+ - Keyed list that is ordered-by user
+ * - **MapEntryNode**
+ - Concrete entry in a keyed list
+ * - **UnkeyedListNode**
+ - Unkeyed list
+ * - **UnkeyedListEntryNode**
+ - Concrete entry in an unkeyed list
+
+To create a concrete NormalizedNode object, use the utility class Builders
+or ImmutableNodes. These classes can be found in `yang-data-impl` module and
+they provide methods for building each type of normalized node. Here is a
+simple example of building a normalized node:
.. code:: java
"pkval1".
Write operation is performed with both normalized nodes mentioned
-earlier. It consist of several steps. The first step is to instantiate a
+earlier. It consists of several steps. The first step is to instantiate a
DataTreeModification object based on a DataTreeSnapshot.
DataTreeSnapshot gives you the current state of the data tree. Then
comes the write operation which writes a normalized node at the provided
has to be called, marking the modification as ready for application to
the data tree. No further operations within the modification are
allowed. The modification is then validated - checked whether it can be
-applied to the data tree. Finally we commit it to the data tree.
+applied to the data tree. Finally, we commit it to the data tree.
-Now you can access the written nodes. In order to do this, you have to
+Now you can access the written nodes. In order to do this, you must
create a new DataTreeSnapshot instance and call the method readNode()
-with path argument pointing to a particular node in the tree.
+with path argument pointing to a node in the tree.
-Serialization / deserialization of YANG Data
+Serialization / deserialization of YANG data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If you want to deserialize YANG-modeled data which have the form of an
+If you want to deserialize YANG-modeled data that has the form of an
XML document, you can use the XML parser found in the module
yang-data-codec-xml. The parser walks through the XML document
containing YANG-modeled data based on the provided SchemaContext and
calling the method parse() on the XmlParserStream object with
XMLStreamReader as its argument.
-Finally you can access the result of parsing - a tree of NormalizedNodes
+Finally, you can access the result of parsing - a tree of NormalizedNodes
containg the data as they are defined in the parsed XML document - by
calling the method getResult() on the NormalizedNodeResult object.
-
-Introducing schema source repositories
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Writing YANG driven generators
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Introducing specific extension support for YANG parser
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Diagnostics
-~~~~~~~~~~~