RDK services are a set of JSON-RPC based RESTful services for accessing various set-top box components. RDK Services are managed and accessed through the Thunder framework. Thunder supports both HTTP and Websocket requests, making the services easily accessible to Lightning, Web, and native client applications.
-
Before RDK accepts your code into the project you must sign the RDK Contributor License Agreement (CLA).
-
Each new file should include the latest RDKM license header.
-
License for this project is included in the root directory and there shouldn't be any additional license file in any of the subfolders.
-
Fork the repository, commit your changes, build and test it in at least one approved test platform/device.
-
To test it in a RDKV device, update SRC_URI and SRCREV in the rdkservices_git.bb recipe to point to your fork.
-
Submit your changes as a pull request to the latest sprint branch.
-
If more than one developer has to work on a particular feature, request for a dev branch to be created.
-
When a pull request is submitted, blackduck, copyright and cla checks will automatically be triggered. Ensure these checks have passed (turned into green).
-
At least one reviewer needs to review and approve the pull request.
-
For tracking and release management purposes, each pull request and all the commits in the pull request shall include RDK ticket number(s) or Github issue number(s) and “reason for the change”.
-
Any pull request from Comcast developers should include a link to successful gerrit verification (in the comment section).
-
To verify your changeset in gerrit, submit a test gerrit change to rdkservices_git.bb with the SRC_URI and SRCREV pointing to your fork.
-
If the changes to RDKServices require any Thunder framework changes, the contributor has to plan for a limited regression testing (with the Thunder and RDKServices changes) before submitting the pull request.
-
Comcast gerrit sprint branch will point to rdkservices sprint branch.
- For example 2103_sprint branch gerrit recipe will point to sprint/2103 branch in github.
-
Comcast gerrit stable2 branch will point to rdkservices main branch in github.
-
Git hash in rdkservices_git.bb (sprint_branch) will be updated periodically (at least once a week).
- Dev owner to follow up as needed and update the JIRA ticket to “ready for sprint testing”.
-
Once a change is verified in the sprint branch and approved by RM, the developer can contact the maintainers to cherry-pick the change set to the main branch or submit the cherry picked change set to the main branch.
- Git hash in rdkservices_git.bb (stable2) will be updated periodically.
- Dev owner to follow up as needed and update the ticket to “ready for release testing”.
-
What if a changeset in the sprint branch fails sprint testing?
- The developer has to submit a pull request to undo the commit before the end of the sprint cycle or
- The changeset will be abandoned in the sprint branch and won’t make into the main/stable2
-
Patches will increase the chances of build failures when the git hash is moved to a newer version.
-
We encourage everyone to upstream all the changes to GitHub instead of using patches
-
On a need basis, a developer can request the maintainers for an approval to use a patch in RDKV build (as a stop-gap measure). An unapproved patch will be rejected.
RDK services are described using JSON Schema. JSON Schema provides a standard approach for describing APIs and ensures consistency across all APIs. The Thunder framework includes two schemas that are used to describe a service:
- plugin.schema.json: A schema for defining a Thunder Plugin.
- interface.schema.json: A schema for defining the properties, methods, and events of a service.
Each RDK service has an instance of these schemas in the root of the service directory. For example, MyServicePlugin.json
and MyService.json
. These files are used to generate API documentation as Markdown. Each service has a Markdown file that is written to the /doc
directory in a service folder. The following demonstrates the folder structure:
/rdkservices
/MyService
/MyService.json
/MyServicePlugin.json
/doc
/doc/MyServicePlugin.md
Markdown files are generated using the Thunder JsonGenerator tool. See the Thunder README for documentation and requirements.
To generate the markdown:
-
Clone the Thunder repository if it is not already on your system.
-
Change directories to
Thunder/Tools/JsonGenerator
. -
Run
JsonGenerator.py
and provide the location of the service JSON plugin file using the--docs
argument and the output directory using the-o
argument. You must also include the--no-interfaces-section
argument; otherwise, an interface section is added to the markdown that links back to the ThunderInterfaces project. Make certain that you are pointing to the plugin definition and not the interface definition. Here is an example of using the JsonGenerator tool:./JsonGenerator.py --docs ../../../rdkservices/MyService/MyServicePlugin.json -o doc --no-interfaces-section --verbose $files
The
MyServicePlugin.md
file is written to the/doc
folder.
Use the existing services as a guide when learning the structure of both the plugin and interface schemas.
If you have any questions or concerns reach out to the RDKServices maintainers - Vijay Selvaraj / Anand Kandasamy
For a plugin specific question, maintainers might refer you to the plugin owner(s).
-
Be Consistent
-
The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you’re saying rather than on how you’re saying it.
-
If the code you add to a file looks drastically different from the existing code around it, it throws readers out of their rhythm. Avoid this.
-
If you’re editing code, take a few minutes to determine the coding style of the component and apply the same style.
-
To maintain uniformity in all text-editors, set TAB size to 2 or 4 spaces and replace TAB by SPACES
-
If they use spaces around all their arithmetic operators, you should too.
-
If the comments have little boxes of hash marks around them, make your comments have little boxes of hash marks around them too.
-
Minimise the use of exceptions and handle exceptions locally if possible
-
All resources acquired by a RDKSerice must be released by the Deinitialize method and/or the destructor
-
-
RDK services are implemented as Thunder Plugins and must adhere to the PluginHost::IPlugin interface. This interface is accessible by extending the AbstractPlugin helper class.
-
All RDK Services must have a callsign with a prefix of
org.rdk
. RDK Service name must be CamelCase and start with a capital letter. -
All method, parameter and event names must be camelCase and start with a lowercase letter.
-
MODULE_NAME
-
Thunder provides a trace and warning reporting feature. To accurately identify the source of a warning, Thunder needs to know the human readable name of the package (executable or library). This package name is defined by the MODULE_NAME and declared by the MODULE_NAME_DECLARATION()
-
Any package that includes a Thunder component requires such a definition and declaration. If the definition is missing, a compiler error will be reported (error missing MODULE_NAME) and if the declaration is missing, a linker error will be reported (missing or duplicate symbol)
-
MODULE_NAME is typically found in "Module.h" and "Module.cpp"
- Module.h
#ifndef MODULE_NAME #define MODULE_NAME Plugin_IOController #endif
- Module.c
#include "Module.h" MODULE_NAME_DECLARATION(BUILD_REFERENCE)
- Module.h
-
-
Versioning
-
All RDK Services by default will start with version 1.
-
Any client facing changes (like Removing or Adding an API) to RDKServices should be made by incrementing the version to the next whole number (2,3,4...). This will ensure that clients using existing versions are not affected.
-
Use the AbstractPlugin registerMethod helper function to register APIs to specific versions. Here is an example.
-
-
Initialization and Cleanup
-
Prefer to do Plugin Initialization within IPlugin Initialize(). If there is any error in initialization return non-empty string with useful error information. This will ensure that plugin doesn't get activated and also return this error information to the caller. Ensure that any Initialization done within Initialize() gets cleaned up within IPlugin Deinitialize() which gets called when the plugin is deactivated.
-
Ensure that any std::threads created are joined within Deinitialize() or the destructor to avoid std::terminate exception. Use the ThreadRAII class for creating threads which will ensure that the thread gets joined before destruction.
-