Compare commits

...

4 Commits

Author SHA1 Message Date
Andrea Lacava
317afb54ed Adding readme and launch.sh 2023-05-16 18:06:12 -04:00
Andrea Lacava
bae85ce92b broken but closed loop 2023-05-04 17:34:49 -04:00
Andrea Lacava
ab0229b28c 200 + format 2023-05-04 17:12:49 -04:00
Andrea Lacava
6a0da46d20 start working on ns-o-ran branch 2023-05-04 15:39:36 -04:00
9 changed files with 392 additions and 50 deletions

View File

@ -1,4 +1,4 @@
FROM nexus3.o-ran-sc.org:10004/o-ran-sc/bldr-ubuntu18-c-go:1.9.0 as kpimonbuild FROM nexus3.o-ran-sc.org:10002/o-ran-sc/bldr-ubuntu18-c-go:1.9.0 as kpimonbuild
ENV PATH $PATH:/usr/local/bin ENV PATH $PATH:/usr/local/bin
ENV GOPATH /go ENV GOPATH /go
@ -14,9 +14,11 @@ RUN wget --content-disposition ${RMRLIBURL} && dpkg -i rmr_${RMRVERSION}_amd64.d
RUN wget --content-disposition ${RMRDEVURL} && dpkg -i rmr-dev_${RMRVERSION}_amd64.deb RUN wget --content-disposition ${RMRDEVURL} && dpkg -i rmr-dev_${RMRVERSION}_amd64.deb
RUN rm -f rmr_${RMRVERSION}_amd64.deb rmr-dev_${RMRVERSION}_amd64.deb RUN rm -f rmr_${RMRVERSION}_amd64.deb rmr-dev_${RMRVERSION}_amd64.deb
RUN apt update && apt install ca-certificates libgnutls30 -y
ARG XAPPFRAMEVERSION=v0.4.11 ARG XAPPFRAMEVERSION=v0.4.11
WORKDIR /go/src/gerrit.o-ran-sc.org/r/ric-plt WORKDIR /go/src/gerrit.o-ran-sc.org/r/ric-plt
RUN git clone "https://gerrit.o-ran-sc.org/r/ric-plt/sdlgo" RUN git clone -b cherry "https://gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
RUN git clone -b ${XAPPFRAMEVERSION} "https://gerrit.o-ran-sc.org/r/ric-plt/xapp-frame" RUN git clone -b ${XAPPFRAMEVERSION} "https://gerrit.o-ran-sc.org/r/ric-plt/xapp-frame"
RUN cd xapp-frame && \ RUN cd xapp-frame && \
GO111MODULE=on go mod vendor -v && \ GO111MODULE=on go mod vendor -v && \
@ -55,6 +57,14 @@ RUN go build ./cmd/kpimon.go && pwd && ls -lat
FROM ubuntu:18.04 FROM ubuntu:18.04
ENV PATH $PATH:/usr/local/bin
ENV GOPATH /go
ENV GOBIN /go/bin
ENV RMR_SEED_RT /opt/routes.txt
COPY routes.txt /opt/routes.txt
COPY --from=kpimonbuild /usr/local/lib /usr/local/lib COPY --from=kpimonbuild /usr/local/lib /usr/local/lib
COPY --from=kpimonbuild /usr/local/include/e2ap/*.h /usr/local/include/e2ap/ COPY --from=kpimonbuild /usr/local/include/e2ap/*.h /usr/local/include/e2ap/
COPY --from=kpimonbuild /usr/local/include/e2sm/*.h /usr/local/include/e2sm/ COPY --from=kpimonbuild /usr/local/include/e2sm/*.h /usr/local/include/e2sm/
@ -64,3 +74,5 @@ COPY --from=kpimonbuild /go/src/gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/config/
WORKDIR /go/src/gerrit.o-ran-sc.org/r/scp/ric-app/kpimon WORKDIR /go/src/gerrit.o-ran-sc.org/r/scp/ric-app/kpimon
COPY --from=kpimonbuild /go/src/gerrit.o-ran-sc.org/r/scp/ric-app/kpimon/kpimon . COPY --from=kpimonbuild /go/src/gerrit.o-ran-sc.org/r/scp/ric-app/kpimon/kpimon .
CMD sleep infinity

View File

@ -1,26 +1,83 @@
# UPDATED README
## PREREQUISITES
The near-RT-RIC has to be installed. If is not, follow the instructions here: https://docs.o-ran-sc.org/projects/o-ran-sc-ric-plt-ric-dep/en/latest/installation-guides.html
Take care in installing dms_cli, mandatory for the second part.
Chartmuseum has to be already on. If not availabe, run from the home folder:
>docker run --rm -u 0 -it -d -p 8090:8080 -e DEBUG=1 -e STORAGE=local -e STORAGE_LOCAL_ROOTDIR=/charts -v $(pwd)/charts:/charts chartmuseum/chartmuseum:latest
>
In addition to that, a local Docker registry is supposed to be running at 127.0.0.1:5000. In case it is not, run:
>docker run -d -p 5000:5000 --name registry registry:2
>
## Install and launch the xApp
Just use the ./launch_app.sh script.
What the script does is:
- creating an env. variable for the url of Chartmuseum.
- building the xApp from source and tagging it to 127.0.0.1.5000/{name-xapp}:version
- pushing the image to the registry (that's why it was tagged like that)
- Onboarding the xApp, using the tool *dms_cli* and the descriptor and validation schema. Notice that, inside, you find the image of the registry with its version. The xApp might have a different version. xApp version is a different thing than Docker image version.
- Installing the xApp in the RIC (notice that install = run)
- after 10 s, the script returns the name of the pod in the *ricxapp* namespace and the command to shell inside it
To run the kpimon: .
>/kpimon -f /opt/ric/config/config-file.json
# ORIGINAL README AND LICENSE
================================================================================== ==================================================================================
Copyright (c) 2020 AT&T Intellectual Property. Copyright (c) 2020 AT&T Intellectual Property.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
================================================================================== ==================================================================================
KPI Monitoring KPI Monitoring
================ ================
This repository contains the source for the RIC KPI monitoring application. This repository contains the source for the RIC KPI monitoring application.
This xApp can be onboarded through the xApp Onboarder. The xapp descriptor This xApp can be onboarded through the xApp Onboarder. The xapp descriptor
is under the xapp-descriptor/ directory. is under the xapp-descriptor/ directory.
Then the xapp can be deployed through the App Manager. Then the xapp can be deployed through the App Manager.
rte|12010|service-ricplt-e2term-rmr-alpha.ricplt:38000

View File

@ -1,11 +1,147 @@
package main package main
import ( import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
"time"
"gerrit.o-ran-sc.org/r/scp/ric-app/kpimon/control" "gerrit.o-ran-sc.org/r/scp/ric-app/kpimon/control"
) )
func main() { func main() {
response_deregister, err := deRegisterXApp()
if err != nil {
print("Error: " + err.Error())
}
responseDeRegisterString := string(response_deregister)
print("RESPONSE DEREGISTER POST: ")
println(responseDeRegisterString)
time.Sleep(5 * time.Second)
response, err := registerXApp()
if err != nil {
print("Error: " + err.Error())
}
responseString := string(response)
print("RESPONSE REGISTER POST: ")
println(responseString)
time.Sleep(5 * time.Second)
c := control.NewControl() c := control.NewControl()
c.Run() c.Run()
} }
func registerXApp() ([]byte, error) {
url := "http://service-ricplt-appmgr-http.ricplt:8080/ric/v1/register"
// Read payload from config-file.json
payload, err := ioutil.ReadFile("/opt/ric/config/config-file.json")
if err != nil {
print("Error READ CONF: " + err.Error())
}
hostname := os.Getenv("HOSTNAME")
XAPP_NAME := hostname
XAPP_VERSION := "1.0.0"
// RICPLT_NAMESPACE := "ricplt"
XAPP_NAMESPACE := "ricxapp"
// http_endpoint := "SERVICE_" + strings.ToUpper(XAPP_NAMESPACE) + "_" + strings.ToUpper(XAPP_NAME) + "_HTTP_PORT"
rmr_os_key := "SERVICE_" + strings.ToUpper(XAPP_NAMESPACE) + "_" + strings.ToUpper(XAPP_NAME) + "_RMR_PORT"
rmr_endpoint := strings.Split(os.Getenv(rmr_os_key), "//")[1]
config := string(payload)
// Create new JSON
request := map[string]interface{}{
"appName": hostname,
"appVersion": XAPP_VERSION,
"configPath": "",
"appInstanceName": XAPP_NAME,
"httpEndpoint": "",
"rmrEndpoint": rmr_endpoint,
"config": config,
}
// Encode the JSON object as a string
requestString, err := json.Marshal(request)
if err != nil {
fmt.Println("Error encoding JSON:", err)
return nil, err
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestString))
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
func deRegisterXApp() ([]byte, error) {
url := "http://service-ricplt-appmgr-http.ricplt:8080/ric/v1/deregister"
hostname := os.Getenv("HOSTNAME")
XAPP_NAME := hostname
// Create new JSON
request := map[string]interface{}{
"appName": hostname,
"appInstanceName": XAPP_NAME,
}
// Encode the JSON object as a string
requestString, err := json.Marshal(request)
if err != nil {
fmt.Println("Error encoding JSON:", err)
return nil, err
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestString))
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}

View File

@ -9,6 +9,7 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"gerrit.o-ran-sc.org/r/ric-plt/sdlgo" "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
//"github.com/go-redis/redis" //"github.com/go-redis/redis"
@ -40,7 +41,11 @@ func init() {
} }
func NewControl() Control { func NewControl() Control {
str := os.Getenv("ranList") println("Starting new control.")
// str := os.Getenv("ranList")
str := "gnb_131_133_31000000,gnb_131_133_32000000,gnb_131_133_33000000,gnb_131_133_34000000,gnb_131_133_35000000"
println("Ran list is " + str + " ---- ")
return Control{strings.Split(str, ","), return Control{strings.Split(str, ","),
5, 5, 5, 5,
make(chan *xapp.RMRParams), make(chan *xapp.RMRParams),
@ -90,7 +95,7 @@ func (c *Control) startTimerSubReq() {
count++ count++
xapp.Logger.Debug("send RIC_SUB_REQ to gNodeB with cnt=%d", count) xapp.Logger.Debug("send RIC_SUB_REQ to gNodeB with cnt=%d", count)
log.Printf("send RIC_SUB_REQ to gNodeB with cnt=%d", count) log.Printf("send RIC_SUB_REQ to gNodeB with cnt=%d", count)
err := c.sendRicSubRequest(1001, 1001, 0) err := c.sendRicSubRequest(1001, 0, 200)
if err != nil && count < MAX_SUBSCRIPTION_ATTEMPTS { if err != nil && count < MAX_SUBSCRIPTION_ATTEMPTS {
t.Reset(5 * time.Second) t.Reset(5 * time.Second)
} else { } else {
@ -980,7 +985,6 @@ func (c *Control) handleIndication(params *xapp.RMRParams) (err error) {
continue continue
} }
//err = c.client.Set("{TS-cell-metrics}," + cellIDHdr, newCellJsonStr, 0).Err() //err = c.client.Set("{TS-cell-metrics}," + cellIDHdr, newCellJsonStr, 0).Err()
//if err != nil { //if err != nil {
// xapp.Logger.Error("Failed to set CellMetrics into redis with CellID [%s]: %v", cellIDHdr, err) // xapp.Logger.Error("Failed to set CellMetrics into redis with CellID [%s]: %v", cellIDHdr, err)
@ -1121,8 +1125,8 @@ func (c *Control) setEventCreateExpiredTimer(ranName string) {
delete(c.eventCreateExpiredMap, ranName) delete(c.eventCreateExpiredMap, ranName)
c.eventCreateExpiredMu.Unlock() c.eventCreateExpiredMu.Unlock()
if !isResponsed { if !isResponsed {
xapp.Logger.Debug("RIC_SUB_REQ[%s]: RIC Event Create Timer experied!", ranName) xapp.Logger.Debug("RIC_SUB_REQ[%s]: RIC Event Create Timer expired!", ranName)
log.Printf("RIC_SUB_REQ[%s]: RIC Event Create Timer experied!", ranName) log.Printf("RIC_SUB_REQ[%s]: RIC Event Create Timer expired!", ranName)
// c.sendRicSubDelRequest(subID, requestSN, funcID) // c.sendRicSubDelRequest(subID, requestSN, funcID)
return return
} }
@ -1162,8 +1166,8 @@ func (c *Control) setEventDeleteExpiredTimer(ranName string) {
delete(c.eventDeleteExpiredMap, ranName) delete(c.eventDeleteExpiredMap, ranName)
c.eventDeleteExpiredMu.Unlock() c.eventDeleteExpiredMu.Unlock()
if !isResponsed { if !isResponsed {
xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer experied!", ranName) xapp.Logger.Debug("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer expired!", ranName)
log.Printf("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer experied!", ranName) log.Printf("RIC_SUB_DEL_REQ[%s]: RIC Event Delete Timer expired!", ranName)
return return
} }
default: default:
@ -1243,7 +1247,7 @@ func (c *Control) sendRicSubRequest(subID int, requestSN int, funcID int) (err e
log.Printf("Set Payload: %x", params.Payload) log.Printf("Set Payload: %x", params.Payload)
//params.Meid = &xapp.RMRMeid{RanName: c.ranList[index]} //params.Meid = &xapp.RMRMeid{RanName: c.ranList[index]}
params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"} params.Meid = &xapp.RMRMeid{PlmnID: "313131", EnbID: "::", RanName: "gnb_131_133_31000000"}
xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId) xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
log.Printf("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId) log.Printf("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
@ -1279,10 +1283,10 @@ func (c *Control) sendRicSubDelRequest(subID int, requestSN int, funcID int) (er
if funcID == 0 { if funcID == 0 {
//params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "0"} //params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "0"}
params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"} params.Meid = &xapp.RMRMeid{PlmnID: "313131", EnbID: "::", RanName: "gnb_131_133_31000000"}
} else { } else {
//params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "3"} //params.Meid = &xapp.RMRMeid{PlmnID: "::", EnbID: "::", RanName: "3"}
params.Meid = &xapp.RMRMeid{PlmnID: "373437", EnbID: "10110101110001100111011110001", RanName: "gnb_734_733_b5c67788"} params.Meid = &xapp.RMRMeid{PlmnID: "313131", EnbID: "::", RanName: "gnb_131_133_31000000"}
} }
xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId) xapp.Logger.Debug("The RMR message to be sent is %d with SubId=%d", params.Mtype, params.SubId)
@ -1299,4 +1303,3 @@ func (c *Control) sendRicSubDelRequest(subID int, requestSN int, funcID int) (er
return nil return nil
} }

26
launch_app.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
#set -x
export CHART_REPO_URL=http://0.0.0.0:8090
dms_cli uninstall xappkpimon ricxapp
docker build . -f Dockerfile -t 127.0.0.1:5000/kpimon_master:1.0.0 # --no-cache
docker push 127.0.0.1:5000/kpimon_master:1.0.0
# dms_cli onboard config.json schema.json
dms_cli install xappkpimon 1.0.0 ricxapp
echo "Wait for 10 seconds"
sleep 10
unset $pod_name
pod_name=$(kubectl get pods -n ricxapp --no-headers -o custom-columns=":metadata.name")
echo kubectl exec -ti -n ricxapp $pod_name bash
# To run the kpimon
# ./kpimon -f /opt/ric/config/config-file.json

View File

@ -0,0 +1,5 @@
newrt|start
rte|20011|service-ricplt-a1mediator-rmr.ricplt:4562
rte|20012|service-ricplt-a1mediator-rmr.ricplt:4562
rte|12010|service-ricplt-submgr-rmr.ricplt:4560
newrt|end

View File

@ -5,8 +5,8 @@
{ {
"name": "xappkpimon", "name": "xappkpimon",
"image": { "image": {
"registry": "nexus3.o-ran-sc.org:10002", "registry": "127.0.0.1:5000",
"name": "o-ran-sc/scp-ric-app-kpimon", "name": "kpimon_master",
"tag": "1.0.0" "tag": "1.0.0"
} }
} }

View File

@ -0,0 +1,41 @@
{
"xapp_name": "xappkpimon",
"version": "1.0.0",
"containers": [
{
"name": "xappkpimon",
"image": {
"registry": "127.0.0.1:5000",
"name": "kpimon_sleep",
"tag": "1.0.0"
}
}
],
"messaging": {
"ports": [
{
"name": "rmr-data",
"container": "xappkpimon",
"port": 4560,
"rxMessages": ["RIC_SUB_RESP", "RIC_INDICATION"],
"txMessages": ["RIC_SUB_REQ"],
"policies": [],
"description": "rmr receive data port for xappkpimon"
},
{
"name": "rmr-route",
"container": "xappkpimon",
"port": 4561,
"description": "rmr route port for xappkpimon"
}
]
},
"rmr": {
"protPort": "tcp:4560",
"maxSize": 2072,
"numWorkers": 1,
"rxMessages": ["RIC_SUB_RESP", "RIC_INDICATION"],
"txMessages": ["RIC_SUB_REQ"],
"policies": []
}
}

62
xapp-descriptor/schema.json Executable file
View File

@ -0,0 +1,62 @@
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "object",
"title": "The Root Schema",
"required": [
"active",
"interfaceId"
],
"properties": {
"active": {
"$id": "#/properties/active",
"type": "boolean",
"title": "The Active Schema",
"default": false,
"examples": [
false
]
},
"interfaceId": {
"$id": "#/properties/interfaceId",
"type": "object",
"title": "The Interfaceid Schema",
"required": [
"globalENBId"
],
"properties": {
"globalENBId": {
"$id": "#/properties/interfaceId/properties/globalENBId",
"type": "object",
"title": "The Globalenbid Schema",
"required": [
"plmnId",
"eNBId"
],
"properties": {
"plmnId": {
"$id": "#/properties/interfaceId/properties/globalENBId/properties/plmnId",
"type": "string",
"title": "The Plmnid Schema",
"default": "",
"examples": [
"310150"
],
"pattern": "^(.*)$"
},
"eNBId": {
"$id": "#/properties/interfaceId/properties/globalENBId/properties/eNBId",
"type": "integer",
"title": "The Enbid Schema",
"default": 0,
"examples": [
202251
]
}
}
}
}
}
}
}