Developer HowTo for SO Module
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.
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)