Developer HowTo for SO Module

From OSM Public Wiki
Jump to: navigation, search

Getting Started

Check out the SO module following the instructions @ RiftWare installation (release 0).

Programming Language

The SO module uses Python3.

Code Style

Please follow PEP8 style guide for all the Python code.

Directory Organization

The code organized into the following high level directories:
| - common (Contains common modules)
| - models (Contains the information models)
| - rwlaunchpad (Contains majority of the logic for SO
| - rwcm (Contains the logic for configuration manager)

Running Unit Tests

The unit tests for this module are in rwlaunchpad/test. Please make sure that these tests pass. Currently the following unit test files exist:
- mano_ut.py
- utest_rwnsm.py
NOTE: To run the unit tests make sure to source ${TOP_DIR}/rift-shell.

TODO: Merge and have one unit test target.

Development Environment

The SO module is organized into a group of tasklets. A tasklet is an instance of software task that can be independently scheduled. The tasklet may run standalone or along side other tasklets in a single process.

Inter tasklet communication is achieved through a transactional publish/subscribe middleware facility known as Distributed Transaction System (DTS). Transaction data and keying is based around yang-based schema.

Tasklets registers with DTS as publishers and/or subscribers and exchange model based data. The Python tasklets access this data as Python classes auto-generated from YANG model. The callbacks and asynchronous events from DTS subsystem are handled using Python 3 asyncio coroutines [1]. This greatly simplifies the handling of asynchronous events handling.

Management Interface

The SO uses YANG based schema's for configuration and operational data. From the YANG schema CLI, REST interfaces are autogenerated.

Coding Tips

This section introduces high level concepts that will help developer bootstrap quickly.

Creating a New Tasklet

Every new tasklet should inherit from rift.tasklets.Tasklets. The rift.tasklets.Tasklets class hides the details about interfacing with the DTS. For example:

   class NsmTasklet(rift.tasklets.Tasklet)
       """"
       The network service manager  tasklet
       """

Logging

Every tasklet is provided a log handle. Always use this log handle. An example is shown below:

   self.log.debug("Changing state to %s", next_state)

Use the appropriate logging levels when logging the messages.

Creating a DTS Handle

A DTS participant requires a handle. The following shows an example creating a handle:

   self._dts = rift.tasklets.DTS(self.tasklet_info,
                                 RwNsmYang.get_schema(),
                                 self.loop,
                                 self.on_dts_state_change)

Registering with DTS

The following code snippet shows an example of a tasklet registering as a publisher:

   XPATH = "D,/nsr:ns-instance-opdata/nsr:nsr"
   hdl = rift.tasklets.DTS.RegistrationHandler()
   handlers = rift.tasklets.Group.Handler()
   with self._dts.group_create(handler=handlers) as group:
       self._regh = group.register(xpath=NsrOpDataDtsHandler.XPATH,
                                   handler=hdl,
                                    flags=rwdts.Flag.PUBLISHER)

Publishing Data

Once the registration handle is available, CRUD operations can be performed. For example, the following code shows creation of a new element:

   xpath="D,/nsr:ns-instance-opdata/nsr:nsr[nsr:id=uuid]"
   self.regh.create_element(xpath, msg)