# generate swagger client
RUN /go/bin/swagger generate client -f api/appmgr_rest_api.yaml -t pkg/ -m appmgrmodel -c appmgrclient
-# build and test o1agent
-#RUN GO111MODULE=on GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o o1agent cmd/o1agent.go
+# build and test o1agent
RUN ./build_o1agent.sh
-# make the data model based on the ric yang model
+# Install the data models based on the ric yang model
RUN /usr/local/bin/sysrepoctl -i /go/src/ws/agent/yang/o-ran-sc-ric-xapp-desc-v1.yang
RUN /usr/local/bin/sysrepoctl -i /go/src/ws/agent/yang/o-ran-sc-ric-ueec-config-v1.yang
RUN /usr/local/bin/sysrepoctl -i /go/src/ws/agent/yang/o-ran-sc-ric-gnb-status-v1.yang
source = flag.String("source", "running", "Source datastore")
target = flag.String("target", "running", "Target datastore")
subtree = flag.String("subtree", "netconf-server", "Subtree or module to select")
+ namespace = flag.String("namespace", "urn:o-ran:ric:gnb-status:1.0", "XML namespace")
file = flag.String("file", "", "Configuration file")
action = flag.String("action", "get", "Netconf command: get or edit")
timeout = flag.Int("timeout", 30, "Timeout")
- getStateXml = "<get><filter type=\"subtree\"><ric xmlns=\"urn:o-ran:ric:gnb-status:1.0\"></ric></filter></get>"
+ getStateXml = "<get><filter type=\"subtree\"><ric xmlns=\"%s\"></ric></filter></get>"
getConfigXml = "<get-config><source><%s/></source><filter type=\"subtree\"><%s/></filter></get-config>"
editConfigXml = "<edit-config><target><%s/></target><config>%s</config></edit-config>"
)
return
}
+ session := startSSHSession()
+ if session == nil {
+ return
+ }
+ defer session.Close()
+
switch *action {
case "get":
- getConfig(getStateXml)
+ getStatus(session, getStateXml)
case "get-config":
- getConfig(getConfigXml)
+ getConfig(session, getConfigXml)
case "edit":
- editConfig()
+ editConfig(session)
}
}
-func getConfig(cmdXml string) {
- session := startSSHSession()
- if session == nil {
+func getStatus(session *netconf.Session, cmdXml string) {
+ cmd := netconf.RawMethod(fmt.Sprintf(cmdXml, *namespace))
+ reply, err := session.Exec(cmd)
+ if err != nil {
+ log.Fatal(err)
return
}
- defer session.Close()
+ displayReply(reply.RawReply)
+}
+func getConfig(session *netconf.Session, cmdXml string) {
cmd := netconf.RawMethod(fmt.Sprintf(cmdXml, *source, *subtree))
reply, err := session.Exec(cmd)
if err != nil {
displayReply(reply.RawReply)
}
-func editConfig() {
+func editConfig(session *netconf.Session) {
if *file == "" {
log.Fatal("Configuration file missing!")
return
}
- session := startSSHSession()
- if session == nil {
- return
- }
- defer session.Close()
-
if data, err := ioutil.ReadFile(*file); err == nil {
cmd := netconf.RawMethod(fmt.Sprintf(editConfigXml, *target, data))
reply, err := session.Exec(cmd)
"level": 4
},
"db": {
- "host": "localhost",
- "port": 6379,
"namespaces": ["sdl", "rnib"]
},
"rmr": {
"timeout": 30
},
"nbi": {
- "schemas": ["o-ran-sc-ric-xapp-desc-v1", "o-ran-sc-ric-ueec-config-v1"],
- "modulePath": "/opt/ric/yang/",
- "moduleFile": "ric-model.yang",
- "xpaths": {
- "xapp": "/ric-model:ric/xapps//*",
- "config": "/ric-model:ric/config//*",
- "data":"/ric-model:ric/xapps/status"
- }
+ "schemas": ["o-ran-sc-ric-xapp-desc-v1", "o-ran-sc-ric-ueec-config-v1"]
},
"controls": {
"active": true
func (n *Nbi) DoSubscription(schemas []string) bool {
log.Info("Subscribing YANG modules ... %v", schemas)
+
for _, module := range schemas {
modName := C.CString(module)
defer C.free(unsafe.Pointer(modName))
}
func (n *Nbi) SubscribeStatusData() bool {
- mod := C.CString("o-ran-sc-ric-gnb-status-v1")
- path := C.CString("/o-ran-sc-ric-gnb-status-v1:ric/nodes")
+ if ok := n.SubscribeStatus("o-ran-sc-ric-gnb-status-v1", "/o-ran-sc-ric-gnb-status-v1:ric/nodes"); !ok {
+ return ok
+ }
+
+ if ok := n.SubscribeStatus("o-ran-sc-ric-xapp-desc-v1", "/o-ran-sc-ric-xapp-desc-v1:ric/health"); !ok {
+ return ok
+ }
+ return true
+}
+
+func (n *Nbi) SubscribeStatus(module, xpath string) bool {
+ mod := C.CString(module)
+ path := C.CString(xpath)
defer C.free(unsafe.Pointer(mod))
defer C.free(unsafe.Pointer(path))
func nbiGnbStateCB(session *C.sr_session_ctx_t, module *C.char, xpath *C.char, req_xpath *C.char, reqid C.uint32_t, parent **C.char) C.int {
log.Info("NBI: Module state data for module='%s' path='%s' rpath='%s' requested [id=%d]", C.GoString(module), C.GoString(xpath), C.GoString(req_xpath), reqid)
+ if C.GoString(module) == "o-ran-sc-ric-xapp-desc-v1" {
+ log.Info("xApp health query not implemtented yet!")
+ return C.SR_ERR_OK
+ }
+
gnbs, err := xapp.Rnib.GetListGnbIds()
if err != nil || len(gnbs) == 0 {
log.Info("Rnib.GetListGnbIds() returned elementCount=%d err:%v", len(gnbs), err)
"JSON string of override file for 'helm install' command";
}
}
+
+ grouping xapp-status {
+ leaf name {
+ type string;
+ description
+ "Name of the xApp in helm chart";
+ }
+ leaf status {
+ type boolean;
+ description
+ "The status of xApp: true=healthy false=not-healthy";
+ }
+ }
- // Top-level (root) manager object
+ // Top-level (root) managed object
container ric {
container xapps {
list xapp {
key "name";
uses xapp-descriptor;
}
- }
+ }
+ container health {
+ config false;
+ list status {
+ key "name";
+ uses xapp-status;
+ }
+ description
+ "State data of the xApps";
+ }
}
}
\ No newline at end of file