--- /dev/null
+agent/build
+agent/Makefile
# limitations under the License.
#----------------------------------------------------------
-FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:4-u18.04-nng AS o2mediator-build
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:4-u18.04-nng AS o1mediator-build
RUN apt-get update -y && apt-get install -y jq \
git \
cd /opt/dev && \
git clone https://github.com/sysrepo/sysrepo.git && \
cd sysrepo && mkdir build && cd build && \
- cmake -DCMAKE_BUILD_TYPE:String="Release" -DSR_RPC_CB_TIMEOUT=30000 -DENABLE_TESTS=OFF -DREPOSITORY_LOC:PATH=/etc/sysrepo .. && \
+ cmake -DCMAKE_BUILD_TYPE:String="Release" -DENABLE_TESTS=OFF -DREPOSITORY_LOC:PATH=/etc/sysrepo .. && \
make -j2 && \
make install && make sr_clean && \
ldconfig
cd /opt/dev && \
git clone https://github.com/CESNET/Netopeer2.git && \
cd Netopeer2/server && mkdir build && cd build && \
- cmake -DCMAKE_BUILD_TYPE:String="Release" .. && \
+ cmake -DCMAKE_BUILD_TYPE:String="Release" -DNP2SRV_DATA_CHANGE_TIMEOUT=30000 -DNP2SRV_DATA_CHANGE_WAIT=ON .. && \
make -j2 && \
make install && \
cd ../../cli && mkdir build && cd build && \
# ======================================================================
# RMR
-ARG RMRVERSION=1.11.0
+ARG RMRVERSION=3.1.0
ARG RMRLIBURL=https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_${RMRVERSION}_amd64.deb/download.deb
ARG RMRDEVURL=https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_${RMRVERSION}_amd64.deb/download.deb
&& chmod +x swagger
RUN mkdir -p /go/src/ws
+COPY . /go/src/ws
WORKDIR "/go/src/ws/agent"
# Module prepare (if go.mod/go.sum updated)
-COPY agent /go/src/ws
RUN GO111MODULE=on go mod download
+# Fetch xApp Manager REST API spec
RUN mkdir -p api \
&& mkdir -p pkg \
&& git clone "https://gerrit.o-ran-sc.org/r/ric-plt/appmgr" \
&& cp appmgr/api/appmgr_rest_api.yaml api/ \
&& rm -rf appmgr
-# build and test
-COPY . /go/src/ws
-
# generate swagger client
RUN /go/bin/swagger generate client -f api/appmgr_rest_api.yaml -t pkg/ -m appmgrmodel -c appmgrclient
-# build the o1agent
-RUN GO111MODULE=on GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o o1agent cmd/o1agent.go
+# build and test o1agent
+#RUN GO111MODULE=on GO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o o1agent cmd/o1agent.go
-COPY . /go/src/ws
+RUN ./build_o1agent.sh
# make the data model 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
CMD ["/bin/bash"]
COPY config/supervisord.conf ${CONFIGDIR}/supervisord.conf
# libraries and binaries & config
-COPY --from=o2mediator-build /usr/local/share/ /usr/local/share/
-COPY --from=o2mediator-build /usr/local/etc/ /usr/local/etc/
-COPY --from=o2mediator-build /usr/local/bin/ /usr/local/bin/
-COPY --from=o2mediator-build /usr/local/lib/ /usr/local/lib/
+COPY --from=o1mediator-build /usr/local/share/ /usr/local/share/
+COPY --from=o1mediator-build /usr/local/etc/ /usr/local/etc/
+COPY --from=o1mediator-build /usr/local/bin/ /usr/local/bin/
+COPY --from=o1mediator-build /usr/local/lib/ /usr/local/lib/
RUN ldconfig
# copy yang models with data
-COPY --from=o2mediator-build /etc/sysrepo /etc/sysrepo
+COPY --from=o1mediator-build /etc/sysrepo /etc/sysrepo
-COPY --from=o2mediator-build /go/src/ws/agent/o1agent /usr/local/bin
-COPY --from=o2mediator-build /go/src/ws/manager/src/process-state.py /usr/local/bin
+COPY --from=o1mediator-build /go/src/ws/agent/o1agent /usr/local/bin
+COPY --from=o1mediator-build /go/src/ws/manager/src/process-state.py /usr/local/bin
RUN mkdir -p /etc/o1agent
-COPY --from=o2mediator-build /go/src/ws/agent/config/* /etc/o1agent/
+COPY --from=o1mediator-build /go/src/ws/agent/config/* /etc/o1agent/
# ports available outside 8080 for mediator and 9001 supervise http control interrface
# port 830 for netconf client ssh session
--- /dev/null
+#
+# 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.
+#
+# This source code is part of the near-RT RIC (RAN Intelligent Controller)
+# platform project (RICP).
+#
+
+
+set -e
+set -x
+
+# setup version tag
+if [ -f ../container-tag.yaml ]
+then
+ tag=$(grep "tag:" ../container-tag.yaml | awk '{print $2}')
+else
+ tag="-"
+fi
+
+hash=$(git rev-parse --short HEAD || true)
+
+export GOPATH=$HOME/go
+export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
+export CFG_FILE=config/config-file.json
+export RMR_SEED_RT=config/uta_rtg_ut.rt
+GO111MODULE=on GO_ENABLED=0 GOOS=linux
+
+# Build o1mediator
+go build -a -installsuffix cgo -ldflags "-X main.Version=$tag -X main.Hash=$hash" -o o1agent ./cmd/o1agent.go
+
+# Run o1agent UT
+go test -v -p 1 -cover -coverprofile cover.out ./pkg/nbi/ -c -o ./nbi_test && ./nbi_test
package main
import (
+ "log"
+ "strings"
+ "time"
+ "os"
"bytes"
- "encoding/json"
"flag"
"fmt"
+ "encoding/json"
+ "io/ioutil"
"github.com/Juniper/go-netconf/netconf"
xj "github.com/basgys/goxml2json"
"golang.org/x/crypto/ssh"
- "io/ioutil"
- "log"
- "strings"
- "time"
)
var (
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>"
getConfigXml = "<get-config><source><%s/></source><filter type=\"subtree\"><%s/></filter></get-config>"
editConfigXml = "<edit-config><target><%s/></target><config>%s</config></edit-config>"
)
func main() {
+ defer func() { // catch or finally
+ if err := recover(); err != nil { //catch
+ fmt.Fprintf(os.Stderr, "Something went wrong: %v\n", err)
+ os.Exit(1)
+ }
+ }()
+
if flag.Parse(); flag.Parsed() == false {
log.Fatal("Syntax error!")
return
switch *action {
case "get":
- getConfig()
+ getConfig(getStateXml)
+ case "get-config":
+ getConfig(getConfigXml)
case "edit":
editConfig()
}
}
-func getConfig() {
+func getConfig(cmdXml string) {
session := startSSHSession()
if session == nil {
return
}
defer session.Close()
- cmd := netconf.RawMethod(fmt.Sprintf(getConfigXml, *source, *subtree))
+ cmd := netconf.RawMethod(fmt.Sprintf(cmdXml, *source, *subtree))
reply, err := session.Exec(cmd)
if err != nil {
log.Fatal(err)
import (
"os"
- "os/signal"
- "syscall"
+ "os/signal"
+ "syscall"
+ "fmt"
- "github.com/spf13/viper"
"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
- "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/sbi"
"gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/nbi"
+ "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/sbi"
+ "github.com/spf13/viper"
)
+var Version string
+var Hash string
+
type O1Agent struct {
- rmrReady bool
- nbiClient *nbi.Nbi
- sigChan chan os.Signal
+ rmrReady bool
+ nbiClient *nbi.Nbi
+ sigChan chan os.Signal
}
func (o O1Agent) Consume(rp *xapp.RMRParams) (err error) {
}
func (o *O1Agent) Run() {
- xapp.Logger.SetMdc("o1agent", "0.3.1")
+ xapp.Logger.SetMdc("o1agent", fmt.Sprintf("%s:%s", Version, Hash))
xapp.SetReadyCB(func(d interface{}) { o.rmrReady = true }, true)
xapp.AddConfigChangeListener(o.ConfigChangeHandler)
xapp.Resource.InjectStatusCb(o.StatusCB)
func (o *O1Agent) Sighandler() {
xapp.Logger.Info("Signal handler installed!")
- <- o.sigChan
+ <-o.sigChan
o.nbiClient.Stop()
os.Exit(1)
}
sbiClient := sbi.NewSBIClient(host, baseUrl, []string{prot}, timeout)
return &O1Agent{
- rmrReady: false,
+ rmrReady: false,
nbiClient: nbi.NewNbi(sbiClient),
- sigChan: make(chan os.Signal, 1),
+ sigChan: make(chan os.Signal, 1),
}
}
xapp.Logger.Error("NBI initialization failed!")
return
}
-
+
o1Agent.Run()
}
"logger": {
"level": 4
},
+ "db": {
+ "host": "localhost",
+ "port": 6379,
+ "namespaces": ["sdl", "rnib"]
+ },
"rmr": {
"protPort": "tcp:4560",
"maxSize": 65536,
go 1.12
-replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.21
+replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.26
replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.0
gerrit.o-ran-sc.org/r/com/golog v0.0.1
gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.0-00010101000000-000000000000
github.com/Juniper/go-netconf v0.1.1 // indirect
+ github.com/basgys/goxml2json v1.1.0 // indirect
github.com/coreos/go-etcd v2.0.0+incompatible // indirect
github.com/fsnotify/fsnotify v1.4.7
- github.com/go-openapi/errors v0.19.2
+ github.com/go-openapi/errors v0.19.3
github.com/go-openapi/loads v0.19.4
github.com/go-openapi/runtime v0.19.7
github.com/go-openapi/spec v0.19.4
- github.com/go-openapi/strfmt v0.19.3
- github.com/go-openapi/swag v0.19.5
- github.com/go-openapi/validate v0.19.4
+ github.com/go-openapi/strfmt v0.19.4
+ github.com/go-openapi/swag v0.19.7
+ github.com/go-openapi/validate v0.19.6
github.com/gorilla/mux v1.7.1
github.com/jessevdk/go-flags v1.4.0
github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75
gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.19/go.mod h1:c7zYW0EOxX1wQ4p1yigO2t+RjtwYSVdEXxSA+IqFxIk=
gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.21 h1:Ur+OXnHXlRQG9mp5B05SfS/0ZmuORwC8+SQJKuIjQNw=
gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.21/go.mod h1:WHzMFLWFYnKZzAT76Lu8wXqcM9MQ9hHM0sxlV45icSw=
+gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.26 h1:zFsExCZVAX9vTcLEHNsYgxnKDsGREKoVaz/jwRfTTOI=
+gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.0.26/go.mod h1:lW3UYpVXwPiOR39t6JgNCE4kdmMSdPVelMPC/Pp9fQM=
gerrit.oran-osc.org/r/ric-plt/sdlgo.git v0.0.1 h1:l2dl31r++3xhgCumTzwvuo0/F415eqU4aFk/uDQ4WnM=
gerrit.oran-osc.org/r/ric-plt/sdlgo.git v0.0.1/go.mod h1:LVhkNS82IofJTBK/VYPKiYed9MG/3OFwvWC6MGSDw1w=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw=
+github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY=
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/errors v0.19.3 h1:7MGZI1ibQDLasvAz8HuhvYk9eNJbJkCOXWsSjjMS+Zc=
+github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
+github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA=
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
+github.com/go-openapi/strfmt v0.19.4 h1:eRvaqAhpL0IL6Trh5fDsGnGhiXndzHFuA05w6sXH6/g=
+github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.7 h1:VRuXN2EnMSsZdauzdss6JBC29YotDqG59BZ+tdlIL1s=
+github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo=
github.com/go-openapi/validate v0.19.4 h1:LGjO87VyXY3bIKjlYpXSFuLRG2mTeuYlZyeNwFFWpyM=
github.com/go-openapi/validate v0.19.4/go.mod h1:BkJ0ZmXui7yB0bJXWSXgLPNTmbLVeX/3D1xn/N9mMUM=
+github.com/go-openapi/validate v0.19.6 h1:WsKw9J1WzYBVxWRYwLqEk3325RL6G0SSWksuamkk6q0=
+github.com/go-openapi/validate v0.19.6/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-redis/redis v6.15.3+incompatible h1:NZ0O90AhLSvSrvLZ/S9h7D4kl1mW2PrKyxL7MyBKO2g=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
+github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/segmentio/ksuid v1.0.2 h1:9yBfKyw4ECGTdALaF09Snw3sLJmYIX6AbPJrAy6MrDc=
github.com/segmentio/ksuid v1.0.2/go.mod h1:BXuJDr2byAiHuQaQtSKoXh1J0YmUDurywOXgB2w+OSU=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/valyala/fastjson v1.4.1 h1:hrltpHpIpkaxll8QltMU8c3QZ5+qIiCL8yKqPFJI/yE=
github.com/valyala/fastjson v1.4.1/go.mod h1:nV6MsjxL2IMJQUoHDIrjEI7oLyeqK6aBD7EFWPsvP8o=
+github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1 h1:Sq1fR+0c58RME5EoqKdjkiQAmPjmfHlZOoRI6fTUOcs=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.mongodb.org/mongo-driver v1.1.2 h1:jxcFYjlkl8xaERsgLo+RNquI0epW6zuy/ZRQs6jnrFA=
+go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
sr_val_t *get_val(sr_val_t *val, size_t i) {
return &val[i];
+}
+
+int gnb_status_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *req_xpath, uint32_t req_id, struct lyd_node **parent, void *private_data) {
+ return nbiGnbStateCB(session, (char *)module_name, (char *)xpath, (char *)req_xpath, req_id, (char **)parent);
+}
+
+void create_new_path(sr_session_ctx_t *session, char **parent, char *key, char *value) {
+ struct lyd_node **p = (struct lyd_node **)parent;
+
+ if (*parent == NULL) {
+ *p = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), key, value, 0, 0);
+ } else {
+ lyd_new_path(*p, sr_get_context(sr_session_get_connection(session)), key, value, 0, 0);
+ }
}
\ No newline at end of file
char * get_data_json(sr_session_ctx_t *session, const char *module_name);
+int gnb_status_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, const char *req_xpath, uint32_t req_id, struct lyd_node **parent, void *private_data);
+
+void create_new_path(sr_session_ctx_t *session, char **parent, char *key, char *value);
+
#endif
package nbi
-import (
- "time"
+import (
+ "encoding/json"
"errors"
"fmt"
- "strings"
- "unsafe"
- "encoding/json"
"github.com/spf13/viper"
"github.com/valyala/fastjson"
+ "strings"
+ "time"
+ "unsafe"
"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
"gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/sbi"
sbiClient = s
nbiClient = &Nbi{
- schemas: viper.GetStringSlice("nbi.schemas"),
+ schemas: viper.GetStringSlice("nbi.schemas"),
cleanupChan: make(chan bool),
}
return nbiClient
return true
}
-func (n *Nbi) Stop() {
+func (n *Nbi) Stop() {
C.sr_unsubscribe(n.subscription)
C.sr_session_stop(n.session)
C.sr_disconnect(n.connection)
return false
}
}
- return true
+ return n.SubscribeStatusData()
}
func (n *Nbi) SubscribeModule(module *C.char) bool {
return true
}
+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")
+ defer C.free(unsafe.Pointer(mod))
+ defer C.free(unsafe.Pointer(path))
+
+ rc := C.sr_oper_get_items_subscribe(n.session, mod, path, C.sr_oper_get_items_cb(C.gnb_status_cb), nil, 0, &n.subscription)
+ if C.SR_ERR_OK != rc {
+ log.Error("NBI: sr_oper_get_items_subscribe failed: %s", C.GoString(C.sr_strerror(rc)))
+ return false
+ }
+ return true
+}
+
//export nbiModuleChangeCB
func nbiModuleChangeCB(session *C.sr_session_ctx_t, module *C.char, xpath *C.char, event C.sr_event_t, reqId C.int) C.int {
changedModule := C.GoString(module)
desc := sbiClient.BuildXappDescriptor(xappName, namespace, relName, version)
switch oper {
- case C.SR_OP_CREATED:
- return sbiClient.DeployXapp(desc)
- case C.SR_OP_DELETED:
- return sbiClient.UndeployXapp(desc)
- default:
- return errors.New(fmt.Sprintf("Operation '%d' not supported!", oper))
+ case C.SR_OP_CREATED:
+ return sbiClient.DeployXapp(desc)
+ case C.SR_OP_DELETED:
+ return sbiClient.UndeployXapp(desc)
+ default:
+ return errors.New(fmt.Sprintf("Operation '%d' not supported!", oper))
}
}
return nil
func (n *Nbi) ManageConfigmaps(module, configJson string, oper int) error {
log.Info("ManageConfig: module=%s configJson=%s", module, configJson)
-
+
if configJson == "" || module != "o-ran-sc-ric-ueec-config-v1" {
return nil
}
}
return v.GetArray(model, top, elem), nil
}
+
+//export nbiGnbStateCB
+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)
+
+ gnbs, err := xapp.Rnib.GetListGnbIds()
+ if err != nil || len(gnbs) == 0 {
+ log.Info("Rnib.GetListGnbIds() returned elementCount=%d err:%v", len(gnbs), err)
+ return C.SR_ERR_OK
+ }
+
+ for _, gnb := range gnbs {
+ ranName := gnb.GetInventoryName()
+ info, err := xapp.Rnib.GetNodeb(ranName)
+ if err != nil {
+ log.Error("GetNodeb() failed for ranName=%s: %v", ranName, err)
+ continue
+ }
+
+ prot := nbiClient.E2APProt2Str(int(info.E2ApplicationProtocol))
+ connStat := nbiClient.ConnStatus2Str(int(info.ConnectionStatus))
+ ntype := nbiClient.NodeType2Str(int(info.NodeType))
+
+ log.Info("gNB info: %s -> %s %s %s -> %s %s", ranName, prot, connStat, ntype, gnb.GetGlobalNbId().GetPlmnId(), gnb.GetGlobalNbId().GetNbId())
+
+ nbiClient.CreateNewElement(session, parent, ranName, "ran-name", ranName)
+ nbiClient.CreateNewElement(session, parent, ranName, "ip", info.Ip)
+ nbiClient.CreateNewElement(session, parent, ranName, "port", fmt.Sprintf("%d", info.Port))
+ nbiClient.CreateNewElement(session, parent, ranName, "plmn-id", gnb.GetGlobalNbId().GetPlmnId())
+ nbiClient.CreateNewElement(session, parent, ranName, "nb-id", gnb.GetGlobalNbId().GetNbId())
+ nbiClient.CreateNewElement(session, parent, ranName, "e2ap-protocol", prot)
+ nbiClient.CreateNewElement(session, parent, ranName, "connection-status", connStat)
+ nbiClient.CreateNewElement(session, parent, ranName, "node", ntype)
+ }
+ return C.SR_ERR_OK
+}
+
+func (n *Nbi) CreateNewElement(session *C.sr_session_ctx_t, parent **C.char, key, name, value string) {
+ basePath := fmt.Sprintf("/o-ran-sc-ric-gnb-status-v1:ric/nodes/node[ran-name='%s']/%s", key, name)
+ log.Info("%s -> %s", basePath, value)
+
+ cPath := C.CString(basePath)
+ defer C.free(unsafe.Pointer(cPath))
+ cValue := C.CString(value)
+ defer C.free(unsafe.Pointer(cValue))
+
+ C.create_new_path(session, parent, cPath, cValue)
+}
+
+func (n *Nbi) ConnStatus2Str(connStatus int) string {
+ switch connStatus {
+ case 0:
+ return "not-specified"
+ case 1:
+ return "connected"
+ case 2:
+ return "disconnected"
+ case 3:
+ return "setup-failed"
+ case 4:
+ return "connecting"
+ case 5:
+ return "shutting-down"
+ case 6:
+ return "shutdown"
+ }
+ return "not-specified"
+}
+
+func (n *Nbi) E2APProt2Str(prot int) string {
+ switch prot {
+ case 0:
+ return "not-specified"
+ case 1:
+ return "x2-setup-request"
+ case 2:
+ return "endc-x2-setup-request"
+ }
+ return "not-specified"
+}
+
+func (n *Nbi) NodeType2Str(ntype int) string {
+ switch ntype {
+ case 0:
+ return "not-specified"
+ case 1:
+ return "enb"
+ case 2:
+ return "gnb"
+ }
+ return "not-specified"
+}
assert.Equal(t, true, err != nil)
}
+func TestConnStatus2Str(t *testing.T) {
+ assert.Equal(t, n.ConnStatus2Str(0), "not-specified")
+ assert.Equal(t, n.ConnStatus2Str(1), "connected")
+ assert.Equal(t, n.ConnStatus2Str(2), "disconnected")
+ assert.Equal(t, n.ConnStatus2Str(3), "setup-failed")
+ assert.Equal(t, n.ConnStatus2Str(4), "connecting")
+ assert.Equal(t, n.ConnStatus2Str(5), "shutting-down")
+ assert.Equal(t, n.ConnStatus2Str(6), "shutdown")
+ assert.Equal(t, n.ConnStatus2Str(1234), "not-specified")
+}
+
+func TestE2APProt2Str(t *testing.T) {
+ assert.Equal(t, n.E2APProt2Str(0), "not-specified")
+ assert.Equal(t, n.E2APProt2Str(1), "x2-setup-request")
+ assert.Equal(t, n.E2APProt2Str(2), "endc-x2-setup-request")
+ assert.Equal(t, n.E2APProt2Str(1111), "not-specified")
+}
+
+func TestNodeType2Str(t *testing.T) {
+ assert.Equal(t, n.NodeType2Str(0), "not-specified")
+ assert.Equal(t, n.NodeType2Str(1), "enb")
+ assert.Equal(t, n.NodeType2Str(2), "gnb")
+ assert.Equal(t, n.NodeType2Str(1111), "not-specified")
+}
+
func TestTeardown(t *testing.T) {
n.Stop()
}
schemas []string
connection *C.sr_conn_ctx_t
session *C.sr_session_ctx_t
- subscription *C.sr_subscription_ctx_t
- oper C.sr_change_oper_t
+ subscription *C.sr_subscription_ctx_t
+ oper C.sr_change_oper_t
cleanupChan chan bool
}
package sbi
import (
- "time"
httptransport "github.com/go-openapi/runtime/client"
"github.com/go-openapi/strfmt"
-
+ "time"
+
"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
apiclient "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/appmgrclient"
apixapp "gerrit.oran-osc.org/r/ric-plt/o1mediator/pkg/appmgrclient/xapp"
func (s *SBIClient) BuildXappConfig(name, namespace string, configData interface{}) *apimodel.XAppConfig {
metadata := &apimodel.ConfigMetadata{
- XappName: &name,
+ XappName: &name,
Namespace: &namespace,
}
return &apimodel.XAppConfig{
Metadata: metadata,
- Config: configData,
+ Config: configData,
}
}
--- /dev/null
+module o-ran-sc-ric-gnb-status-v1 {
+ yang-version 1;
+ namespace "urn:o-ran:ric:gnb-status:1.0";
+ prefix rxad;
+
+ organization
+ "O-RAN Software Community";
+ contact
+ "www.o-ran.org";
+ description
+ "This module defines the gNB status and other information visible to operators
+
+ Copyright 2020 the O-RAN Alliance.
+
+ 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.";
+
+ revision 2020-01-29 {
+ description
+ "initial revision";
+ reference
+ "O-RAN-OAM-Interface-Specification (O1)";
+ }
+
+ typedef e2ap-protocol-type {
+ type enumeration {
+ enum not-specified {
+ description
+ "None";
+ }
+ enum x2-setup-request {
+ description
+ "X2 setup request";
+ }
+ enum endc-x2-setup-request {
+ description
+ "ENDC X2 setup request";
+ }
+ }
+ description
+ "The E2AP protocol setup types";
+ }
+
+ typedef connection-status-type {
+ type enumeration {
+ enum not-specified {
+ description
+ "None";
+ }
+ enum connected {
+ description
+ "Connected";
+ }
+ enum connecting {
+ description
+ "Connecting";
+ }
+ enum disconnected {
+ description
+ "Disconnected";
+ }
+ enum setup-failed {
+ description
+ "Setup failed";
+ }
+ enum shutting-down {
+ description
+ "Shutting down";
+ }
+ enum shutdown {
+ description
+ "Shutdown";
+ }
+ }
+ description
+ "The connection status of gNB";
+ }
+
+ typedef node-type {
+ type enumeration {
+ enum not-specified {
+ description
+ "None";
+ }
+ enum enb {
+ description
+ "eNB";
+ }
+ enum gnb {
+ description
+ "gNB";
+ }
+ }
+ description
+ "The connection status of gNB";
+ }
+
+ grouping nodeb-info {
+ leaf ran-name {
+ type string;
+ description
+ "The unique RAN name";
+ }
+ leaf ip {
+ type string;
+ description
+ "The IP address of the node";
+ }
+ leaf port {
+ type uint32;
+ description
+ "The port of the node";
+ }
+ leaf e2ap-protocol {
+ type e2ap-protocol-type;
+ description
+ "Specifies the protocol type of the connection";
+ }
+ leaf connection-status {
+ type connection-status-type;
+ description
+ "Specifies the connection type of the node";
+ }
+ leaf plmn-id {
+ type string;
+ description
+ "PLMN id";
+ }
+ leaf nb-id {
+ type string;
+ description
+ "eNB id";
+ }
+ leaf node {
+ type node-type;
+ description
+ "The type of the node: eNB or gNB";
+ }
+ }
+
+ container ric {
+ container nodes {
+ config false;
+ list node {
+ key "ran-name";
+ uses nodeb-info;
+ description
+ "The list of the gNBs currently discovered by RIC";
+ }
+ description
+ "State data container of the nodes";
+ }
+ }
+}
# By default this file is in the docker build directory,
# but the location can configured in the JJB template.
---
-tag: 0.3.1
+tag: 0.3.2