| .. This work is licensed under a Creative Commons Attribution 4.0 International License. |
| .. SPDX-License-Identifier: CC-BY-4.0 |
| .. Copyright (C) 2020 AT&T Intellectual Property |
| |
| Framework Overview |
| ================== |
| |
| This package is a framework for writing RAN Intelligent Controller |
| (RIC) Xapps in python. The framework reduces the amount of code |
| required in an Xapp by providing common features needed by all |
| Python-based Xapps including communication with the RIC message router |
| (RMR) and the Shared Data Layer (SDL). |
| |
| The framework was designed to suport many types of Xapps, including |
| applications that are purely reactive to RMR messages, and general |
| applications that initiate actions according to other criteria. |
| |
| For complete documentation see the ReadTheDocs site for |
| `xapp-frame-py <https://docs.o-ran-sc.org/projects/o-ran-sc-ric-plt-xapp-frame-py>`_. |
| |
| Reactive Xapps |
| -------------- |
| |
| A reactive Xapp acts on messages that are delivered (pushed) via RMR. |
| The Xapp only takes action upon receipt of an RMR message. The Xapp |
| never takes action at another time. |
| |
| This type of application is constructed by creating callback functions |
| and registering them with the framework by message type. When an RMR |
| message arrives, the appropriate callback is invoked based on the |
| message type. An Xapp may define and register a separate callback for |
| each expected message type. Every Xapp must define a default callback |
| function, which is invoked when a message arrives for which no |
| type-specific callback was registered. An analogy of this is AWS |
| Lambda: "execute this code every time an event comes in" (the code to |
| execute can depend on the type of event). |
| |
| General Xapps |
| ------------- |
| |
| A general Xapp acts according to its own criteria, which may include |
| receipt of RMR messages. |
| |
| This type of application is constructed by creating a single function |
| that is invoked by the framework after initialization. Typically that |
| function contains a `while (something)` event loop. When the function |
| returns, the Xapp stops. In this usage, the Xapp must fetch its own |
| data, either from RMR, SDL or other source. The framework does less |
| work for a general application compared to a reactive application; the |
| framework only sets up an RMR thread and an SDL connection before |
| invoking the client-provided function. |
| |
| Threading in the Framework |
| -------------------------- |
| |
| RMR interactions are processed in a thread started by the framework. |
| This implementation detail is documented here for transparency, but |
| most users will not have to worry about this. |
| |
| In both types of Xapp, the framework launches a separate thread whose |
| only job is to read from RMR and deposit all messages (and their |
| summaries) into a thread-safe queue. When the client Xapp reads from |
| RMR using the framework (this read is done by the framework itself in |
| the RMR Xapp, but by the client in a general Xapp), the read is done |
| from the framework-managed queue. The framework is implemented this |
| way so that a long-running client function (e.g., consume) will not |
| block RMR reads. This is important because RMR is *not* a persistent |
| message bus; if an RMR client does not read fast enough, messages can |
| be lost. So in this framework the client code is not in the same |
| thread as the RMR reads, to ensure that long-running client code will |
| not cause message loss. |
| |
| In the case of RMR Xapps, there are currently 3 potential threads; the |
| thread that reads from RMR directly, and the user can optionally have |
| the RMR queue read run in a thread, returning execution back to the |
| user thread. The default is only two threads however, where `.run` |
| does not return back execution and the user code is finished at that |
| point. |
| |
| Healthchecks |
| ------------ |
| |
| The framework provides a default RMR healthcheck probe handler for |
| reactive Xapps. When an RMR healthcheck message arrives, this handler |
| checks that the RMR thread is healthy (of course the Xapp cannot even |
| reply if the thread is not healthy!), and that the SDL connection is |
| healthy. The handler responds accordingly via RMR. The Xapp can |
| override this probe handler by registering a new callback for the |
| healthcheck message type. |
| |
| The framework provides no healthcheck handler for general Xapps. Those |
| applications must handle healthcheck probe messages appropriately when |
| they read their RMR mailboxes. |
| |
| There is no http service in the framework, so there is no support for |
| HTTP-based healthcheck probes, such as what a deployment manager like |
| Kubernetes may use. |
| |
| Examples |
| -------- |
| |
| Two sample Xapps using this framework are provided in the `examples` |
| directory of the |
| `git repository <https://gerrit.o-ran-sc.org/r/gitweb?p=ric-plt/xapp-frame.git;a=tree>`_. |
| The first, `ping`, is a general Xapp |
| that defines a main function that reads its RMR mailbox in addition to |
| other work. The second, `pong`, is a reactive Xapp that only takes |
| action when a message is received. |
| |
| To run a demonstration, build the Docker images for both examples |
| using the supplied Dockerfiles. Then start the Pong container (the |
| listener) followed by the Ping container (the sender). The Ping |
| application sends a message, the pong application receives the message |
| and use RMR's return-to-sender feature to reply. Ping then reads its |
| own mailbox and demonstrates other functionality. |