</parent>
<groupId>org.o-ran-sc.nonrtric</groupId>
<artifactId>a1-policy-management-service</artifactId>
- <version>2.3.0-SNAPSHOT</version>
+ <version>2.4.0-SNAPSHOT</version>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
</parent>
<groupId>org.o-ran-sc.nonrtric</groupId>
<artifactId>dmaap-adaptor</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>1.1.0-SNAPSHOT</version>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<system>JIRA</system>
<url>https://jira.o-ran-sc.org/</url>
</issueManagement>
-</project>
\ No newline at end of file
+</project>
!consumer/
dmaap
!dmaap/
+ics
+!ics/
Once the initial registration is done, the producer will constantly poll MR for all configured job types. When receiving messages for a type, it will distribute these messages to all jobs registered for the type. If no jobs for that type are registered, the messages will be discarded. If a consumer is unavailable for distribution, the messages will be discarded for that consumer until it is available again.
-The producer provides a REST API to control the log level. The available levels are the same as the ones used in the configuration above.
+The producer provides a REST API that fulfills the ICS Data producer API, see [Data producer (callbacks)](<https://docs.o-ran-sc.org/projects/o-ran-sc-nonrtric/en/latest/ics-api.html#tag/Data-producer-(callbacks)>). The health check method returns the registration status of the producer in ICS as JSON. It also provides a method to control the log level of the producer. The available log levels are the same as the ones used in the configuration above.
PUT https://mrproducer:8085/admin/log?level=<new level>
"oransc.org/nonrtric/dmaapmediatorproducer/internal/jobs"
)
-const StatusPath = "/status"
-const AddJobPath = "/jobs"
+const HealthCheckPath = "/health_check"
+const AddJobPath = "/info_job"
const jobIdToken = "infoJobId"
const deleteJobPath = AddJobPath + "/{" + jobIdToken + "}"
const logLevelToken = "level"
}
}
-func NewRouter(jm jobs.JobsManager) *mux.Router {
+func NewRouter(jm jobs.JobsManager, hcf func(http.ResponseWriter, *http.Request)) *mux.Router {
callbackHandler := NewProducerCallbackHandler(jm)
r := mux.NewRouter()
- r.HandleFunc(StatusPath, statusHandler).Methods(http.MethodGet).Name("status")
+ r.HandleFunc(HealthCheckPath, hcf).Methods(http.MethodGet).Name("health_check")
r.HandleFunc(AddJobPath, callbackHandler.addInfoJobHandler).Methods(http.MethodPost).Name("add")
r.HandleFunc(deleteJobPath, callbackHandler.deleteInfoJobHandler).Methods(http.MethodDelete).Name("delete")
r.HandleFunc(logAdminPath, callbackHandler.setLogLevel).Methods(http.MethodPut).Name("setLogLevel")
return r
}
-func statusHandler(w http.ResponseWriter, r *http.Request) {
- // Just respond OK to show the server is alive for now. Might be extended later.
-}
-
func (h *ProducerCallbackHandler) addInfoJobHandler(w http.ResponseWriter, r *http.Request) {
b, readErr := ioutil.ReadAll(r.Body)
if readErr != nil {
func TestNewRouter(t *testing.T) {
assertions := require.New(t)
- r := NewRouter(nil)
- statusRoute := r.Get("status")
+ r := NewRouter(nil, nil)
+ statusRoute := r.Get("health_check")
assertions.NotNil(statusRoute)
supportedMethods, err := statusRoute.GetMethods()
assertions.Equal([]string{http.MethodGet}, supportedMethods)
assertions.Nil(err)
path, _ := statusRoute.GetPathTemplate()
- assertions.Equal("/status", path)
+ assertions.Equal("/health_check", path)
addJobRoute := r.Get("add")
assertions.NotNil(addJobRoute)
assertions.Equal([]string{http.MethodPost}, supportedMethods)
assertions.Nil(err)
path, _ = addJobRoute.GetPathTemplate()
- assertions.Equal("/jobs", path)
+ assertions.Equal("/info_job", path)
deleteJobRoute := r.Get("delete")
assertions.NotNil(deleteJobRoute)
assertions.Equal([]string{http.MethodDelete}, supportedMethods)
assertions.Nil(err)
path, _ = deleteJobRoute.GetPathTemplate()
- assertions.Equal("/jobs/{infoJobId}", path)
+ assertions.Equal("/info_job/{infoJobId}", path)
notFoundHandler := r.NotFoundHandler
handler := http.HandlerFunc(notFoundHandler.ServeHTTP)
assertions.Equal("/admin/log", path)
}
-func TestStatusHandler(t *testing.T) {
- assertions := require.New(t)
-
- handler := http.HandlerFunc(statusHandler)
- responseRecorder := httptest.NewRecorder()
- r := newRequest(http.MethodGet, "/status", nil, t)
-
- handler.ServeHTTP(responseRecorder, r)
-
- assertions.Equal(http.StatusOK, responseRecorder.Code)
- assertions.Equal("", responseRecorder.Body.String())
-}
-
func TestAddInfoJobHandler(t *testing.T) {
assertions := require.New(t)
)
var configuration *config.Config
+var registered bool
func init() {
configuration = config.New()
retryClient := restclient.CreateRetryClient(cert)
jobsManager := jobs.NewJobsManagerImpl(retryClient, configuration.DMaaPMRAddress, restclient.CreateClientWithoutRetry(cert, 10*time.Second))
+ go startCallbackServer(jobsManager, callbackAddress)
+
if err := registerTypesAndProducer(jobsManager, configuration.InfoCoordinatorAddress, callbackAddress, retryClient); err != nil {
log.Fatalf("Stopping producer due to: %v", err)
}
+ registered = true
jobsManager.StartJobsForAllTypes()
log.Debug("Starting DMaaP Mediator Producer")
- go func() {
- log.Debugf("Starting callback server at port %v", configuration.InfoProducerPort)
- r := server.NewRouter(jobsManager)
- if restclient.IsUrlSecure(callbackAddress) {
- log.Fatalf("Server stopped: %v", http.ListenAndServeTLS(fmt.Sprintf(":%v", configuration.InfoProducerPort), configuration.ProducerCertPath, configuration.ProducerKeyPath, r))
- } else {
- log.Fatalf("Server stopped: %v", http.ListenAndServe(fmt.Sprintf(":%v", configuration.InfoProducerPort), r))
- }
- }()
keepProducerAlive()
}
}
producer := config.ProducerRegistrationInfo{
- InfoProducerSupervisionCallbackUrl: callbackAddress + server.StatusPath,
+ InfoProducerSupervisionCallbackUrl: callbackAddress + server.HealthCheckPath,
SupportedInfoTypes: jobTypesHandler.GetSupportedTypes(),
InfoJobCallbackUrl: callbackAddress + server.AddJobPath,
}
return nil
}
+func startCallbackServer(jobsManager jobs.JobsManager, callbackAddress string) {
+ log.Debugf("Starting callback server at port %v", configuration.InfoProducerPort)
+ r := server.NewRouter(jobsManager, statusHandler)
+ if restclient.IsUrlSecure(callbackAddress) {
+ log.Fatalf("Server stopped: %v", http.ListenAndServeTLS(fmt.Sprintf(":%v", configuration.InfoProducerPort), configuration.ProducerCertPath, configuration.ProducerKeyPath, r))
+ } else {
+ log.Fatalf("Server stopped: %v", http.ListenAndServe(fmt.Sprintf(":%v", configuration.InfoProducerPort), r))
+ }
+}
+
+func statusHandler(w http.ResponseWriter, r *http.Request) {
+ registeredStatus := "not registered"
+ if registered {
+ registeredStatus = "registered"
+ }
+ fmt.Fprintf(w, `{"status": "%v"}`, registeredStatus)
+}
+
func keepProducerAlive() {
forever := make(chan int)
<-forever
<groupId>oransc.org</groupId>
<artifactId>dmaapmediatorproducer</artifactId>
- <version>1.0.0</version>
+ <version>1.1.0</version>
<properties>
<docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
</properties>
}
fmt.Println("Registering consumer: ", jobInfo)
body, _ := json.Marshal(jobInfo)
- putErr := restclient.Put(fmt.Sprintf("http://localhost:8083/data-consumer/v1/info-jobs/job%v", port), body, &httpClient)
+ putErr := restclient.Put(fmt.Sprintf("https://localhost:8083/data-consumer/v1/info-jobs/job%v", port), body, &httpClient)
if putErr != nil {
fmt.Println("Unable to register consumer: ", putErr)
}
--- /dev/null
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2021: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package main
+
+import (
+ "flag"
+ "fmt"
+ "net/http"
+
+ "github.com/gorilla/mux"
+)
+
+func main() {
+ port := flag.Int("port", 8434, "The port this stub will listen on")
+ flag.Parse()
+ fmt.Println("Starting ICS stub on port ", *port)
+
+ r := mux.NewRouter()
+ r.HandleFunc("/data-producer/v1/info-types/{typeId}", handleTypeRegistration).Methods(http.MethodPut, http.MethodPut)
+ r.HandleFunc("/data-producer/v1/info-producers/{producerId}", handleProducerRegistration).Methods(http.MethodPut, http.MethodPut)
+ fmt.Println(http.ListenAndServe(fmt.Sprintf(":%v", *port), r))
+}
+
+func handleTypeRegistration(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ id, ok := vars["typeId"]
+ if ok {
+ fmt.Println("Registered type ", id)
+ }
+}
+
+func handleProducerRegistration(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ id, ok := vars["producerId"]
+ if ok {
+ fmt.Println("Registered producer ", id)
+ }
+}
This document describes how to install the Non-RT RIC components, their dependencies and required system resources.
-Preface
--------
-
-See the README file in the "`docker-compose <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=docker-compose>`_" folder for more information.
-
Software Installation and Deployment
------------------------------------
-f ics/docker-compose.yaml
The example above is just an example to start some of the components.
-For more information on running and configuring the functions can be found in the Readme file in the "`docker-compose <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=docker-compose>`__" folder, and on the `wiki page <https://wiki.o-ran-sc.org/display/RICNR/Release+E+-+Run>`_
+For more information on running and configuring the functions can be found in the README file in the "`docker-compose <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=docker-compose>`__" folder, and on the `wiki page <https://wiki.o-ran-sc.org/display/RICNR/Release+E+-+Run>`_
Install with Helm
+++++++++++++++++
Summary
-------
-The Non-RealTime RIC (RAN Intelligent Controller) is an Orchestration and Automation function described by the O-RAN Alliance for non-real-time intelligent management of RAN (Radio Access Network) functions. The primary goal of the Non-RealTime RIC is to support non-real-time radio resource management, higher layer procedure optimization, policy optimization in RAN, and providing guidance, parameters, policies and AI/ML models to support the operation of near-RealTime RIC functions in the RAN to achieve higher-level non-real-time objectives. NONRTRIC functions include service and policy management, RAN analytics and model-training for the near-RealTime RICs. The NONRTRIC project provides concepts, specifications, architecture and reference implementations as defined and described by the `O-RAN Alliance <https://www.o-ran.org>`_ architecture.
+The Non-RealTime RIC (RAN Intelligent Controller) is an Orchestration and Automation function described by the O-RAN Alliance for non-real-time intelligent management of RAN (Radio Access Network) functions.
-The O-RAN-SC NONRTRIC implementation communicates with near-RealTime RIC elements in the RAN via the A1 interface. Using the A1 interface the NONRTRIC will facilitate the provision of policies for individual UEs or groups of UEs; monitor and provide basic feedback on policy state from near-RealTime RICs; provide enrichment information as required by near-RealTime RICs; and facilitate ML model training, distribution and inference in cooperation with the near-RealTime RICs.
+The primary goal of the Non-RealTime RIC is to support non-real-time radio resource management, higher layer procedure optimization, policy optimization in RAN, and providing guidance, parameters, policies and AI/ML models to support the operation of near-RealTime RIC functions in the RAN to achieve higher-level non-real-time objectives.
+
+Non-RealTime RIC functions include service and policy management, RAN analytics and model-training for the near-RealTime RICs.
+The Non-RealTime RIC platform hosts and coordinates rApps (Non-RT RIC applications) to perform Non-RealTime RIC tasks.
+The Non-RealTime RIC also hosts the new R1 interface (between rApps and SMO/Non-RealTime-RIC services)
+
+The O-RAN-SC (OSC) NONRTRIC project provides concepts, architecture and reference implementations as defined and described by the `O-RAN Alliance <https://www.o-ran.org>`_ architecture.
+The OSC NONRTRIC implementation communicates with near-RealTime RIC elements in the RAN via the A1 interface. Using the A1 interface the NONRTRIC will facilitate the provision of policies for individual UEs or groups of UEs; monitor and provide basic feedback on policy state from near-RealTime RICs; provide enrichment information as required by near-RealTime RICs; and facilitate ML model training, distribution and inference in cooperation with the near-RealTime RICs.
|archpic|
These are the components that make up the Non-RT-RIC:
-* Non-RT-RIC Control Panel / Dashboard
-* A1 Policy Management Service (developed in ONAP)
-* A1/SDNC Controller & A1 Adapter (Controller plugin)
+* Non-RT-RIC Control Panel
* Information Coordinator Service
+* A1 Policy Management Service
+* A1 Policy Controller / Adapter
+* Near-RT RIC A1 Simulator
* Non-RT-RIC (Spring Cloud) Service Gateway
* Non-RT-RIC (Kong) Service Exposure Prototyping
+* DMaaP/Kafka Information Producer Adapters
* Initial Non-RT-RIC App Catalogue
-* Near-RT-RIC A1 Simulator
-* DMaap Adaptor
+* Initial K8S Helm Chart LCM Manager
+* Test Framework
+* Use Cases
-The code base for "E" Release is in the `NONRTRIC <https://gerrit.o-ran-sc.org/r/admin/repos/nonrtric>`_, `NONRTRIC-ControlPanel <https://gerrit.o-ran-sc.org/r/admin/repos/portal/nonrtric-controlpanel>`_, and `Near-RT-RIC A1-Simulator <https://gerrit.o-ran-sc.org/r/admin/repos/sim/a1-interface>`_ , Gerrit source repositories (E-Release Branch).
+ + "Helloworld" O-RU Fronthaul Recovery use case
+ + "Helloworld" O-DU Slice Assurance use case
+
+The source code for "E" Release is in the `NONRTRIC <https://gerrit.o-ran-sc.org/r/admin/repos/nonrtric>`_, `NONRTRIC-ControlPanel <https://gerrit.o-ran-sc.org/r/admin/repos/portal/nonrtric-controlpanel>`_, and `Near-RT-RIC A1-Simulator <https://gerrit.o-ran-sc.org/r/admin/repos/sim/a1-interface>`_ Gerrit source repositories (E-Release Branch).
Non-RT-RIC Control Panel / NONRTRIC Dashboard
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Graphical user interface
* View and Manage A1 policies in the RAN (near-RT-RICs)
-* Interacts with the Policy agent’s NBI (REST API)
-* Graphical A1 policy creation/editing is model-driven, based on policy type’s JSON schema
+* Graphical A1 policy creation/editing is model-driven, based on policy type's JSON schema
* View and manage producers and jobs for the Information coordinator service
* Configure A1 Policy Management Service (e.g. add/remove near-rt-rics)
-* Interacts with the A1-PolicyManagementService & A1-EI-Coordinator (REST NBIs) via Service Exposure gateway
-
+* Interacts with the A1-Policy Management Service & Information Coordination Service (REST NBIs) via Service Exposure gateway
+
Implementation:
* Frontend: Angular framework
* Repo: *portal/nonrtric-controlpanel*
-Please refer the developer guide and the wiki to set up in your local environment.
+Please refer the developer guide and the `Wiki <https://wiki.o-ran-sc.org/display/RICNR/>`_ to set up in your local environment.
More details available at the `NONRTRIC-Portal documentation site <https://docs.o-ran-sc.org/projects/o-ran-sc-portal-nonrtric-controlpanel>`_
+Information Coordination Service
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Coordinate/Register Information Types, Producers, Consumers, and Jobs.
+
+Coordinate/Register A1-EI Types, Producers, Consumers, and Jobs (A1 Enrichment Information Job Coordination).
+
+* Maintains a registry of:
+
+ + Information Types / schemas
+ + Information Producers
+ + Information Consumers
+ + Information Jobs
+
+* Information Query API (e.g. per producer, per consumer, per types)
+* Query status of Information jobs
+* After Information-type/Producer/Consumer/Job is successfully registered delivery/flow can happen directly between Information Producers and Information Consumers
+* The Information Coordinator Service natively supports the O-RAN A1 Enrichment Information (A1-EI) interface, supporting coordination A1-EI Jobs where information (A1-EI)flow from the SMO/Non-RT-RIC/rApps to near-RT-RICs over the A1 interface.
+
+Implementation:
+
+* Implemented as a Java Spring Boot application
+
A1 Policy Management Service (from ONAP CCSDK)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ Create/Query/Update/Delete A1 Policy Instances in near-RT-RICs
+ Query Status for A1 Policy Instances
-* Maintains (persistent) cache of RAN’s A1 Policy information
+* Maintains (persistent) cache of RAN's A1 Policy information
* Support RAN-wide view of A1 Policy information
* Streamline A1 traffic
* Enable (optional) re-synchronization after inconsistencies / near-RT-RIC restarts
* Supports a large number of near-RT-RICs (& multi-version support)
-
+
* Converged ONAP & O-RAN-SC A1 Adapter/Controller functions in ONAP SDNC/CCSDK (Optionally deploy without A1 Adaptor to connect direct to near-RT-RICs)
* Support for different Southbound connectors per near-RT-RIC - e.g. different A1 versions, different near-RT-RIC version, different A1 adapter/controllers supports different or proprietary A1 controllers/EMSs
-See also: `A1 Policy Management Service in ONAP <https://wiki.onap.org/pages/viewpage.action?pageId=84672221>`_
-
+See also: `A1 Policy Management Service in ONAP <https://wiki.onap.org/pages/viewpage.action?pageId=84672221>`_
Implementation:
+
* Implemented as a Java Spring Boot application
A1/SDNC Controller & A1 Adapter (Controller plugin)
* NETCONF YANG > RESTCONF adapter
* SLI Mapping logic supported
* Can be included in an any controller based on ONAP CCSDK
-* Continues to support both a dedicated OSC A1-controller persona and an ONAP SDNC persona
-
-See also: `A1 Adapter/Controller Functions in ONAP <https://wiki.onap.org/pages/viewpage.action?pageId=84672221>`_
-
-Information Coordination Service
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Coordinate/Register A1-EI Types, Producers, Consumers, and Jobs.
-* Maintains a registry of:
+See also: `A1 Adapter/Controller Functions in ONAP <https://wiki.onap.org/pages/viewpage.action?pageId=84672221>`_
- - A1-EI Data Types / schemas
- - A1-EI Producers
- - A1-EI Consumers
- - A1-EI Jobs
+A1 Interface / Near-RT-RIC Simulator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* A1-EI Query API (e.g. per producer, per consumer, per types)
-* Query status of A1-EI jobs
-* Monitors all near-RT-RICs and recovers from inconsistencies
-* After EI-type/Producer/Consumer/Job is successfully registered delivery/flow can happen directly between A1-EI Producers (in SMO/NONRTRIC domain) and A1-EI consumers (near-RT-RICs in RAN domain)
-* *Being extended to coordinate non-A1 Information exchange between NONRTRIC Apps*
+Stateful A1 test stub.
+* Used to create multiple stateful A1 providers (simulated near-rt-rics)
+* Supports A1-Policy and A1-Enrichment Information
+* Swagger-based northbound interface, so easy to change the A1 profile exposed (e.g. A1 version, A1 Policy Types, A1-E1 consumers, etc)
+* All A1-AP versions supported
Implementation:
-* Implemented as a Java Spring Boot application
-
-Dmaap Adapter
-~~~~~~~~~~~~~
-
-Is a generic information producer, which registers itself as an information producer of information types (in Information Coordination Service).
-The information types are defined in a configuration file.
-Information jobs can retrieve data from DMaaP or Kafka topics and push this to data consumers (accessing the ICS API).
-
-Implementation (2 implementations):
+* Implemented as a Python application
+* Repo: *sim/a1-interface*
-1. Implementation as a Java Spring Boot application
-2. Implementation as a Go application
+More details available at the `A1 Simulator documentation site <https://docs.o-ran-sc.org/projects/o-ran-sc-sim-a1-interface>`_
Non-RT-RIC (Spring Cloud) Service Gateway
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Support Apps to use A1 Services
+Support Apps to use A1 Services
* `Spring Cloud Gateway <https://cloud.spring.io/spring-cloud-gateway>`_ provides the library to build a basic API gateway
-* Exposes A1 Policy Management Service & Information Coordinator Service.
+* Exposes A1 Policy Management Service & Information Coordinator Service.
* Additional predicates can be added in code or preferably in the Gateway yaml configuration.
Implementation:
* Initial version based on `Kong API Gateway <https://docs.konghq.com/gateway-oss>`_ function
* Initial exposure candidates include A1 (NONRTRIC) services & O1 (OAM/SMO) services
-NONRTRIC Kubernetes deployment - including Kong configurations can be found in the OSC `it/dep <https://gerrit.o-ran-sc.org/r/gitweb?p=it/dep.git;a=tree;f=nonrtric/helm;hb=refs/heads/master>`_ Gerrit repo.
+NONRTRIC Kubernetes deployment - including Kong configurations can be found in the OSC `it/dep <https://gerrit.o-ran-sc.org/r/gitweb?p=it/dep.git;a=tree;f=nonrtric/helm/nonrtric>`_ Gerrit repo.
+
+DMaaP/Kafka Information Producer Adapters
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Configurable mediators to take information from DMaaP (& Kafka) and present it as a coordinated Information Producer
+
+These mediators/adapters are generic information producers, which registers themselves as an information producers of defined information types (in Information Coordination Service).
+The information types are defined in a configuration file.
+Information jobs defined using Information Coordination Service (ICS) then allow information consumers to retrieve data from DMaaP MR or Kafka topics (accessing the ICS API).
+
+Two alternative implementations to allow Information Consumers to consume DMaaP or Kafka events as coordinated Information Jobs.
+
+Implementations:
+
+1. A version implemented in Java (Spring) - Supporting DMaaP and Kafka mediation
+2. A version implemented in Go - Supporting DMaaP mediation
Initial Non-RT-RIC App Catalogue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Initial version co-developed with v. similar functions in ONAP
* *Limited functionality/integration for now*
-A1 Interface / Near-RT-RIC Simulator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test Framework
+~~~~~~~~~~~~~~
-Stateful A1 test stub.
+A full test environment with extensive test cases/scripts can be found in the ``test`` directory in the *nonrtric* source code
-* Used to create multiple stateful A1 providers (simulated near-rt-rics)
-* Supports A1-Policy and A1-Enrichment Information
-* Swagger-based northbound interface, so easy to change the A1 profile exposed (e.g. A1 version, A1 Policy Types, A1-E1 consumers, etc)
-* All A1-AP versions supported
+Use Cases
+~~~~~~~~~
-Implementation:
+"Helloworld" O-RU Fronthaul Recovery use case
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-* Implemented as a Python application
-* Repo: *sim/a1-interface*
+A very simplified closed-loop rApp use case to re-establish front-haul connections between O-DUs and O-RUs if they fail. Not intended to to be 'real-world'
-More details available at the `A1 Simulator documentation site <https://docs.o-ran-sc.org/projects/o-ran-sc-sim-a1-interface>`_
+"Helloworld" O-DU Slice Assurance use case
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A very simplified closed-loop rApp use case to re-prioritize a RAN slice's radio resource allocation priority if sufficient throughput cannot be maintained. Not intended to to be 'real-world'
| | | | Release |
| | | | |
+------------+----------+------------------+--------------------+
+| 2021-12-13 | 2.3.0 | Henrik Andersson | E Release |
+| | | | Renamed and minor |
+| | | | improvements |
++------------+----------+------------------+--------------------+
Version history Information Coordinator Service
===============================================
-+------------+----------+------------------+----------------+
-| **Date** | **Ver.** | **Author** | **Comment** |
-| | | | |
-+------------+----------+------------------+----------------+
-| 2020-12-03 | 1.0.0 | Henrik Andersson | Cherry Release |
-| | | | |
-+------------+----------+------------------+----------------+
-| 2021-06-23 | 1.1.0 | Henrik Andersson | D Release |
-| | | | |
-+------------+----------+------------------+----------------+
++------------+----------+------------------+--------------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+--------------------+
+| 2020-12-03 | 1.0.0 | Henrik Andersson | Cherry Release |
+| | | | |
++------------+----------+------------------+--------------------+
+| 2021-06-23 | 1.1.0 | Henrik Andersson | D Release |
+| | | | |
++------------+----------+------------------+--------------------+
+| 2021-12-13 | 1.2.0 | Henrik Andersson | E Release |
+| | | | Renamed and minor |
+| | | | improvements |
++------------+----------+------------------+--------------------+
Version history Service Catalogue
Version history Helm Manager
============================
-+------------+----------+------------------+-----------------+
-| **Date** | **Ver.** | **Author** | **Comment** |
-| | | | |
-+------------+----------+------------------+-----------------+
-| 2021-06-23 | 1.0.0 | Henrik Andersson | Initial version |
-| | | | D Release |
-+------------+----------+------------------+-----------------+
++------------+----------+------------------+-----------------------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+-----------------------------+
+| 2021-06-23 | 1.0.0 | Henrik Andersson | Initial version |
+| | | | D Release |
++------------+----------+------------------+-----------------------------+
+| 2021-12-14 | 1.1.0 | Henrik Andersson | E Release |
+| | | | Update to match ONAP Policy |
+| | | | helm participant |
++------------+----------+------------------+-----------------------------+
Version history SDNC A1 Controller
+------------+----------+------------------+--------------------+
+Version history DMaaP Adator
+============================
+
++------------+----------+------------------+-----------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+-----------------+
+| 2021-12-13 | 1.0.0 | Henrik Andersson | E Release |
+| | | | Initial version |
++------------+----------+------------------+-----------------+
+
+
+Version history DMaaP Mediator Producer
+=======================================
+
++------------+----------+------------------+-----------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+-----------------+
+| 2021-12-13 | 1.0.0 | Henrik Andersson | E Release |
+| | | | Initial version |
++------------+----------+------------------+-----------------+
+
+
+Version history usecase O-RU Front-Haul Recovery Script version
+===============================================================
+
++------------+----------+------------------+-----------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+-----------------+
+| 2021-12-13 | 1.0.0 | Henrik Andersson | E Release |
+| | | | Initial version |
++------------+----------+------------------+-----------------+
+
+
+Version history usecase O-RU Front-Haul Recovery Consumer Go version
+====================================================================
+
++------------+----------+------------------+-----------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+-----------------+
+| 2021-12-14 | 1.0.0 | Henrik Andersson | E Release |
+| | | | Initial version |
++------------+----------+------------------+-----------------+
+
+
+Version history usecase O-DU Slice Assurance
+============================================
+
++------------+----------+------------------+-----------------+
+| **Date** | **Ver.** | **Author** | **Comment** |
+| | | | |
++------------+----------+------------------+-----------------+
+| 2021-12-14 | 1.0.0 | Henrik Andersson | E Release |
+| | | | Initial version |
++------------+----------+------------------+-----------------+
+
+
Release Data
============
| | |
+-----------------------------+---------------------------------------------------+
| **Purpose of the delivery** | Minor bug fixes |
-+-----------------------------+---------------------------------------------------+
\ No newline at end of file
++-----------------------------+---------------------------------------------------+
+
+E Release
+---------
++-----------------------------+---------------------------------------------------+
+| **Project** | Non-RT RIC |
+| | |
++-----------------------------+---------------------------------------------------+
+| **Repo/commit-ID** | nonrtric/b472c167413a55a42fc7bfa08d2138f967a204fb |
+| | |
++-----------------------------+---------------------------------------------------+
+| **Release designation** | E |
+| | |
++-----------------------------+---------------------------------------------------+
+| **Release date** | 2021-12-13 |
+| | |
++-----------------------------+---------------------------------------------------+
+| **Purpose of the delivery** | Improvements and renaming. |
+| | Introduction of more usecase implementations. |
++-----------------------------+---------------------------------------------------+
.. _page: https://wiki.o-ran-sc.org/display/RICNR/
-There are functional requirements emitted by O-RAN WG2 for the Non-RT RIC, which are the following:
+The NONRTRIC project (and the O-RAN Non-RealTime RIC function) can be considered from a number of different viewpoints. This page presents some of these views:
-#. Non-RT RIC shall support data retrieval and analysis; the data may include performance, configuration or other data related to the application (recommended data shown in required data section for different use cases).
-#. Non-RT RIC shall support relevant AI/ML model training based on the data in 1. for non-real-time optimization of configuration parameters in RAN or Near-RT RIC, as applicable for the use case.
-#. Non-RT RIC shall support relevant AI/ML model training based on the data in 1. for generating/optimizing policies and intents to guide the behavior of applications in Near-RT RIC or RAN, as applicable for the use case.
-#. Non-RT RIC shall support training of relevant AI/ML models based on the data in 1. to be deployed/updated in Near-RT RIC as required by the applications.
-#. Non-RT RIC shall support performance monitoring and evaluation.
-#. Non-RT RIC shall support a fallback mechanism to prevent drastic degradation/fluctuation of performance, e.g. to restore to the previous policy or configuration.
+**Scope 1: A1 Controller (Mediator, Endpoint)**
-The non-functional requirements are the following ones:
+* Southbound: Provide termination point for A1 interface(s) - REST endpoint for messages to/from Near-RealTime RIC
+* Northbound: Provide a more generic interface for A1 operations - provide interface to rApps, without the need for A1 message generation, addressing, coordination, mediation, etc.
+* O1 interfaces do not terminate in NONRTRIC function (but may terminate in same controller host/instance)
-#. Non-RT RIC shall not update the same policy or configuration parameter for a given Near-RT RIC or RAN function more often than once per second.
-#. Non-RT RIC shall be able to update policies in several Near-RT RICs.
+**Scope 2: Coordinate/Host A1 Policy Management Services**
-Moreover, there are functional requirements regarding the A1 interface:
+* Map high level RAN goal/intent directives to finely-scoped A1 Policies towards individual Near-RT RIC instances
+* Informed by observed RAN context (provided over O1 via OAM functions), and other external context (via other SMO functions)
+* Dynamically coordinate life cycles of A1 Policies in individual Near-RT RICs as contexts change
-#. A1 interface shall support communication of policies/intents from Non-RT RIC to Near-RT RIC.
-#. A1 interface shall support AI/ML model deployment and update from Non-RT RIC to Near-RT RIC.
-#. A1 interface shall support communication of enrichment information from Non-RT RIC to Near-RT RIC.
-#. A1 interface shall support feedback from Near-RT RIC for monitoring AI/ML model performance.
-#. A1 interface shall support the policy/intents feedback from Near-RT RIC to Non-RT RIC.
+**Scope 3: Coordinate ML/AI Models - In RAN (“E2 nodes” & Near-RT RICs) and NONRTRIC (future)**
+
+* Acts as model-training host
+* May act as model-inference host (others: Near-RT RICs, “E2 nodes”)
+* Dynamically coordinate ML/AI model lifecycle management (e.g. re-train, re-deploy, etc)
+* Models are (always?) deployed over O1 interface
+
+**Scope 4: Enrichment Data Coordinator**
+
+* Additional context that is unavailable to Near-RT RICs (e.g. RAN data, SMO context, External context)
+* Dynamically coordinate access and pass data to appropriate Near-RT RICs (e.g. for use in ML/AI model inference)
+
+**Scope 5: rApp Host & rApp Coordinator**
+
+* rApps may act as, or form part of, NONRTRIC- or SMO-level applications
+* rApps, via rApp host function, may consume many other services - some from the NONRTRIC platform, some from the SMO platform, and some from other rApps
+* Dynamically coordinate rApp lifecycle management
+
+**Scope 6: Provide R1 interface for rApps**
+
+* rApps may only consume services over the R1 interface (from NONRTRIC platform, or from SMO platform, or from other rApps)
+* Platform services and services optionally provided by rApps must be exposed over the R1 Interface
+* These services may be "standardized" R1 services or R1 extensions (some may be proprietary)
All parts are Dockerized and can be started as individual containers, in the same network, in Docker.
The script based solution can be found here:
-`Script version <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/oruclosedlooprecovery/scriptversion;b=HEAD>`_.
+`Script version <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/oruclosedlooprecovery/scriptversion>`_.
ONAP Policy Solution
++++++++++++++++++++
There is also another solution for performing the front-haul recovery that is based on `ONAP Policy Framework <https://wiki.onap.org/display/DW/Policy+Framework+Project>`_.
A TOSCA Policy has been created that listens to DMaaP Message Router, makes a decision on an appropriate remedy and then signals the decision as a configuration change message via
REST call to the OAM controller. The policy based solution can be found here:
-`Policy version <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/oruclosedlooprecovery/apexpolicyversion;b=HEAD>`_.
+`Policy version <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/oruclosedlooprecovery/apexpolicyversion>`_.
-There is a `docker-compose <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=docker-compose/docker-compose-policy-framework;b=HEAD>`_ available
+There is a `docker-compose <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=docker-compose/docker-compose-policy-framework>`_ available
in the nonrtric repo for bringing up the complete standalone version of ONAP Policy Framework.
The detailed instructions for deploying and running this policy are provided in
The ICS Consumer solution is implemented in Go and instead of polling MR itself, it registers as a consumer of the "STD_Fault_Messages" job in ICS.
The Go implementation of the solution can be found here:
-`Go version <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/oruclosedlooprecovery/goversion;b=HEAD>`_.
+`Go version <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/oruclosedlooprecovery/goversion>`_.
O-DU Slice Assurance
--------------------
A very simplified closed-loop rApp use case to re-prioritize a RAN slice's radio resource allocation priority if sufficient throughput cannot be maintained. Not intended to to be 'real-world'.
The Go implementation of the solution can be found in
-this `link <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/odusliceassurance/goversion;b=HEAD>`_.
+this `link <https://gerrit.o-ran-sc.org/r/gitweb?p=nonrtric.git;a=tree;f=test/usecases/odusliceassurance/goversion>`_.
<groupId>org.o-ran-sc.nonrtric</groupId>
<artifactId>helm-manager</artifactId>
<!-- Update this when stepping version of the helm-manager -->
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.2.0-SNAPSHOT</version>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<system>JIRA</system>
<url>https://jira.o-ran-sc.org/</url>
</issueManagement>
-</project>
\ No newline at end of file
+</project>
</parent>
<groupId>org.o-ran-sc.nonrtric</groupId>
<artifactId>information-coordinator-service</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.3.0-SNAPSHOT</version>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<system>JIRA</system>
<url>https://jira.o-ran-sc.org/</url>
</issueManagement>
-</project>
\ No newline at end of file
+</project>
-# O-RAN-SC Non-RealTime RIC O-DU Closed Loop Usecase Slice Assurance
+# O-RAN-SC Non-RealTime RIC O-DU Closed Loop Usecase Slice Assurance
## Configuration
>- LOG_LEVEL Optional. The log level, which can be `Error`, `Warn`, `Info` or `Debug`. Defaults to `Info`.
>- POLLTIME Optional. Waiting time between one pull request to Dmaap and another. Defaults to 10 sec
+## Functionality
+
+There is a status call provided in a REST API on port 40936.
+>- /status OK
## Development
To make it easy to test during development of the consumer, there is a stub provided in the `stub` folder.
-This stub is used to simulate both received VES messages from Dmaap MR with information about performance measurements for the slices in a determinated DU and also SDNR, that sends information about Radio Resource Management Policy Ratio and allows to modify value for RRM Policy Dedicated Ratio from default to higher value.
+This stub is used to simulate both received VES messages from Dmaap MR with information about performance measurements for the slices in a determinated DU and also SDNR, that sends information about Radio Resource Management Policy Ratio and allows to modify value for RRM Policy Dedicated Ratio from default to higher value.
By default, SDNR stub listens to the port `3904`, but his can be overridden by passing a `--sdnr-port [PORT]` flag when starting the stub. For Dmaap MR stub default port is `3905` but it can be overriden by passing a `--dmaap-port [PORT]` flag when starting the stub.
# By default this file is in the docker build directory,
# but the location can configured in the JJB template.
---
-tag: 1.0.0
+tag: 1.1.0
--- /dev/null
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
--- /dev/null
+# Copyright (C) 2021 Nordix Foundation. All rights reserved.
+# ========================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=================================================
+
+apiVersion: v1
+name: odu-app
+description: A Helm chart for Kubernetes
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.1.0
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.16.0"
--- /dev/null
+{{/*
+# Copyright (C) 2021 Nordix Foundation. All rights reserved.
+# ========================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=================================================
+*/}}
+
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "odu-app.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "odu-app.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "odu-app.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "odu-app.labels" -}}
+helm.sh/chart: {{ include "odu-app.chart" . }}
+{{ include "odu-app.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "odu-app.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "odu-app.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "odu-app.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "odu-app.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
--- /dev/null
+# Copyright (C) 2021 Nordix Foundation. All rights reserved.
+# ========================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=================================================
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "odu-app.fullname" . }}
+ labels:
+ {{- include "odu-app.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ selector:
+ matchLabels:
+ {{- include "odu-app.selectorLabels" . | nindent 6 }}
+ template:
+ metadata:
+ {{- with .Values.podAnnotations }}
+ annotations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "odu-app.selectorLabels" . | nindent 8 }}
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ env:
+ - name: MR_HOST
+ value: "{{ .Values.messagerouter.host }}"
+ - name: MR_PORT
+ value: "{{ .Values.messagerouter.port }}"
+ - name: SDNR_ADDRESS
+ value: "{{ .Values.sdnr.address }}"
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
--- /dev/null
+# Copyright (C) 2021 Nordix Foundation. All rights reserved.
+# ========================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=================================================
+
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "odu-app.fullname" . }}
+ labels:
+ {{- include "odu-app.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ {{- include "odu-app.selectorLabels" . | nindent 4 }}
--- /dev/null
+# Copyright (C) 2021 Nordix Foundation. All rights reserved.
+# ========================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=================================================
+
+# Default values for odu-app.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+image:
+ repository: odu-app
+ pullPolicy: IfNotPresent
+ # Overrides the image tag whose default is the chart appVersion.
+ tag: "latest"
+
+messagerouter:
+ host: http://dmaap-mr
+ port: 3904
+
+sdnr:
+ address: http://sdnr-simulator:9990
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+podAnnotations: {}
+
+podSecurityContext: {}
+ # fsGroup: 2000
+
+securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+service:
+ type: ClusterIP
+ port: 80
+
+resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
}
func (c Config) String() string {
- return fmt.Sprintf("ConsumerHost: %v, ConsumerPort: %v, SDNRAddress: %v, SDNRUser: %v, SDNRPassword: %v, LogLevel: %v", c.MRHost, c.MRPort, c.SDNRAddress, c.SDNRUser, c.SDNPassword, c.LogLevel)
+ return fmt.Sprintf("[MRHost: %v, MRPort: %v, SDNRAddress: %v, SDNRUser: %v, SDNRPassword: %v, PollTime: %v, LogLevel: %v]", c.MRHost, c.MRPort, c.SDNRAddress, c.SDNRUser, c.SDNPassword, c.Polltime, c.LogLevel)
}
func getEnv(key string, defaultVal string) string {
import (
"fmt"
+ "net/http"
log "github.com/sirupsen/logrus"
"oransc.org/usecase/oduclosedloop/internal/config"
a := sliceassurance.App{}
a.Initialize(dmaapUrl, configuration.SDNRAddress)
- a.Run(TOPIC, configuration.Polltime)
+ go a.Run(TOPIC, configuration.Polltime)
+ http.HandleFunc("/status", statusHandler)
+
+ log.Fatal(http.ListenAndServe(":40936", nil))
}
func validateConfiguration(configuration *config.Config) error {
}
return nil
}
+
+func statusHandler(w http.ResponseWriter, r *http.Request) {
+ // Just respond OK to show the service is alive for now. Might be extended later.
+}
<groupId>oransc.org</groupId>
<artifactId>o-du-slice-assurance</artifactId>
- <version>1.0.0</version>
+ <version>1.1.0</version>
<properties>
<docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
</properties>
## Functionality
-The creation of the job is not done when the consumer is started. Instead the consumer provides a REST API where it can be started and stopped, described below.
+The creation of the job is not done when the consumer is started. Instead the consumer provides a REST API where it can be started and stopped, described below. The API is available on the host and port configured for the consumer
->- /start Creates the job in ICS.
->- /stop Deletes the job in ICS.
+>- /admin/start Creates the job in ICS.
+>- /admin/stop Deletes the job in ICS.
If the consumer is shut down with a SIGTERM, it will also delete the job before exiting.
+There is also a status call provided in the REST API. This will return the running status of the consumer as JSON.
+>- /status {"status": "started/stopped"}
+
## Development
To make it easy to test during development of the consumer, three stubs are provided in the `stub` folder.
# By default this file is in the docker build directory,
# but the location can configured in the JJB template.
---
-tag: 1.0.0
+tag: 1.1.0
}
func (c Config) String() string {
- return fmt.Sprintf("ConsumerHost: %v, ConsumerPort: %v, InfoCoordinatorAddress: %v, SDNRAddress: %v, SDNRUser: %v, SDNRPassword: %v, ORUToODUMapFile: %v, ConsumerCertPath: %v, ConsumerKeyPath: %v, LogLevel: %v", c.ConsumerHost, c.ConsumerPort, c.InfoCoordinatorAddress, c.SDNRAddress, c.SDNRUser, c.SDNPassword, c.ORUToODUMapFile, c.ConsumerCertPath, c.ConsumerKeyPath, c.LogLevel)
+ return fmt.Sprintf("{ConsumerHost: %v, ConsumerPort: %v, InfoCoordinatorAddress: %v, SDNRAddress: %v, SDNRUser: %v, SDNRPassword: %v, ORUToODUMapFile: %v, ConsumerCertPath: %v, ConsumerKeyPath: %v, LogLevel: %v}", c.ConsumerHost, c.ConsumerPort, c.InfoCoordinatorAddress, c.SDNRAddress, c.SDNRUser, c.SDNPassword, c.ORUToODUMapFile, c.ConsumerCertPath, c.ConsumerKeyPath, c.LogLevel)
}
func getEnv(key string, defaultVal string) string {
var linkfailureConfig linkfailure.Configuration
var lookupService repository.LookupService
var consumerPort string
+var started bool
func init() {
doInit()
r := mux.NewRouter()
r.HandleFunc("/", messageHandler.MessagesHandler).Methods(http.MethodPost).Name("messageHandler")
+ r.HandleFunc("/status", statusHandler).Methods(http.MethodGet).Name("status")
r.HandleFunc("/admin/start", startHandler).Methods(http.MethodPost).Name("start")
r.HandleFunc("/admin/stop", stopHandler).Methods(http.MethodPost).Name("stop")
return
}
log.Debug("Registered job.")
+ started = true
}
func stopHandler(w http.ResponseWriter, r *http.Request) {
return
}
log.Debug("Deleted job.")
+ started = false
+}
+
+func statusHandler(w http.ResponseWriter, r *http.Request) {
+ runStatus := "started"
+ if !started {
+ runStatus = "stopped"
+ }
+ fmt.Fprintf(w, `{"status": "%v"}`, runStatus)
}
func deleteOnShutdown(s chan os.Signal) {
assertions.Nil(err)
path, _ = stopHandlerRoute.GetPathTemplate()
assertions.Equal("/admin/stop", path)
+
+ statusHandlerRoute := r.Get("status")
+ assertions.NotNil(statusHandlerRoute)
+ supportedMethods, err = statusHandlerRoute.GetMethods()
+ assertions.Equal([]string{http.MethodGet}, supportedMethods)
+ assertions.Nil(err)
+ path, _ = statusHandlerRoute.GetPathTemplate()
+ assertions.Equal("/status", path)
}
func Test_startHandler(t *testing.T) {
expectedBody := wantedBody
assertions.Equal(expectedBody, body)
clientMock.AssertNumberOfCalls(t, "Do", 1)
+
+ // Check that the running status is "started"
+ statusHandler := http.HandlerFunc(statusHandler)
+ statusResponseRecorder := httptest.NewRecorder()
+ statusRequest, _ := http.NewRequest(http.MethodGet, "/status", nil)
+
+ statusHandler.ServeHTTP(statusResponseRecorder, statusRequest)
+
+ assertions.Equal(http.StatusOK, statusResponseRecorder.Code)
+ assertions.Equal(`{"status": "started"}`, statusResponseRecorder.Body.String())
})
}
}
assertions.Equal("enrichmentservice:8083", actualRequest.URL.Host)
assertions.Equal("/data-consumer/v1/info-jobs/14e7bb84-a44d-44c1-90b7-6995a92ad43c", actualRequest.URL.Path)
clientMock.AssertNumberOfCalls(t, "Do", 1)
+
+ // Check that the running status is "stopped"
+ statusHandler := http.HandlerFunc(statusHandler)
+ statusResponseRecorder := httptest.NewRecorder()
+ statusRequest, _ := http.NewRequest(http.MethodGet, "/status", nil)
+
+ statusHandler.ServeHTTP(statusResponseRecorder, statusRequest)
+
+ assertions.Equal(http.StatusOK, statusResponseRecorder.Code)
+ assertions.Equal(`{"status": "stopped"}`, statusResponseRecorder.Body.String())
})
}
}
<groupId>oransc.org</groupId>
<artifactId>o-ru-closed-loop-consumer</artifactId>
- <version>1.0.0</version>
+ <version>1.1.0</version>
<properties>
<docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
</properties>
func main() {
port := flag.Int("port", 8083, "The port this consumer will listen on")
flag.Parse()
- fmt.Println("Starting SDNR stub on port ", *port)
+ fmt.Println("Starting ICS stub on port ", *port)
r := mux.NewRouter()
r.HandleFunc("/data-consumer/v1/info-jobs/{jobId}", handleCalls).Methods(http.MethodPut, http.MethodDelete)