From c7da4ee19c2b2a96c1eeccd8da944902fcd9323f Mon Sep 17 00:00:00 2001 From: Anssi Mannila Date: Fri, 22 Oct 2021 09:52:02 +0300 Subject: [PATCH] E2 restart handling added - Implementation and unit test are ready Change-Id: I7b5c52826910a4dcafff8938d414d7e9f57fa2ed Signed-off-by: Anssi Mannila --- config/submgr-config.yaml | 1 + container-tag.yaml | 2 +- docs/user-guide.rst | 6 + go.mod | 3 +- go.sum | 78 ------- pkg/control/control.go | 96 +++++++-- pkg/control/e2if_state.go | 176 ++++++++++++++++ pkg/control/e2if_state_test.go | 247 ++++++++++++++++++++++ pkg/control/metrics.go | 11 + pkg/control/registry.go | 49 ++++- pkg/control/subscription.go | 2 + pkg/control/types.go | 8 + pkg/control/ut_ctrl_submgr_test.go | 17 +- pkg/control/ut_messaging_test.go | 277 ++++++++++++++++++++++++- pkg/teststube2ap/stubE2.go | 22 +- releases/container-release-ric-plt-submgr.yaml | 2 +- 16 files changed, 886 insertions(+), 111 deletions(-) create mode 100644 pkg/control/e2if_state.go create mode 100644 pkg/control/e2if_state_test.go diff --git a/config/submgr-config.yaml b/config/submgr-config.yaml index 53d2161..4851734 100644 --- a/config/submgr-config.yaml +++ b/config/submgr-config.yaml @@ -22,6 +22,7 @@ "e2tRecvMsgTimeout_ms": 2000 "e2tMaxSubReqTryCount": 2 "e2tMaxSubDelReqTryCount": 2 + "checkE2State:" "true" "readSubsFromDb": "true" "dbTryCount": 200 "dbRetryForever": "true" diff --git a/container-tag.yaml b/container-tag.yaml index 1f7b321..8832f84 100644 --- a/container-tag.yaml +++ b/container-tag.yaml @@ -2,4 +2,4 @@ # By default this file is in the docker build directory, # but the location can configured in the JJB template. --- -tag: "0.7.1" +tag: "0.7.2" diff --git a/docs/user-guide.rst b/docs/user-guide.rst index b376654..2fc08ec 100755 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -358,6 +358,12 @@ Architecture Restoring subscriptions from db can be disable via submgr-config.yaml file by setting "readSubsFromDb": "false". + * E2 connection break + + Subscription Manager subscribes E2 connection status notifications from RNIB. Whenever E2 interface goes up or down Subscription Manager gets notifies. When interface is down + subscription is not possible. Subscription Manager rejects new request for the E2 node. Http Reject cause is 503 Subscribe Service Unavailable. When interface goes down + Subscription Manager deletes all subscriptions related to the RanName from its memory and database. E2 node and XApp are expected to do the same. + Metrics ------- Subscription Manager adds following statistic counters: diff --git a/go.mod b/go.mod index 62a10a5..c8f8b02 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gerrit.o-ran-sc.org/r/ric-plt/submgr -go 1.12 +go 1.14 replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.8.0 @@ -12,6 +12,7 @@ replace gerrit.o-ran-sc.org/r/ric-plt/e2ap => ./e2ap/ require ( gerrit.o-ran-sc.org/r/ric-plt/e2ap v0.0.0-00010101000000-000000000000 + gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.1 gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.8.0 gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.0-00010101000000-000000000000 github.com/go-openapi/errors v0.19.3 diff --git a/go.sum b/go.sum index a0fa7a9..c36348a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= gerrit.o-ran-sc.org/r/com/golog.git v0.0.2 h1:Ix6SgFuzd6yW6Ur6+qDlGhDO65UYs8PiIkeAL1VaQ2o= gerrit.o-ran-sc.org/r/com/golog.git v0.0.2/go.mod h1:A7hUL52YQSO4dFIZNcj76XQ09C9PftAe3LyL7kqBnok= @@ -16,22 +15,16 @@ gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.3 h1:JokT2aaJkKjYFMayvZHvGb+/I gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.3/go.mod h1:foKMPQZ+RlM0Pos2GlEPAg6ux7Y9PRQmCUglYM7/Qt8= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= 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 h1:3oJU7J3FGFmyhn8KHjmVaZCN5hxTr7GxgRue+sxIXdQ= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= 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= @@ -39,45 +32,30 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l 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/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954 h1:RMLoZVzv4GliuWafOuPuQDKSm1SJph7uCRnnS61JAn4= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -87,7 +65,6 @@ github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOX github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= 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= @@ -137,13 +114,9 @@ github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8w github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -154,13 +127,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -169,36 +139,24 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU= github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -214,11 +172,9 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j 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/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -227,7 +183,6 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -248,21 +203,14 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af h1:gu+uRPtBe88sKxUCEXRoeCvVG90TJmwhiqRpvdhQFng= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/segmentio/ksuid v1.0.3 h1:FoResxvleQwYiPAVKe1tMUlEirodZqlqglIuFsdDntY= github.com/segmentio/ksuid v1.0.3/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -285,36 +233,25 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/vektah/gqlparser v1.1.2 h1:ZsyLGn7/7jDNI+y4SEhI4yAxRChlv15pUHMjijT+e68= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= 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 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56 h1:ZpKuNIejY8P0ExLOVyKhb0WsgG8UdvHXe6TWjY7eL6k= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -326,16 +263,13 @@ golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -345,7 +279,6 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f h1:25KHgbfyiSm6vwQLbM3zZIe1v9p/3ea4Rz+nnM5K/i4= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -356,7 +289,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= @@ -364,16 +296,12 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm 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 h1:CQVOmarCBFzTx0kbOU0ru54Cvot8SdSrNYjZPhQl+gk= golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -382,27 +310,21 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099 h1:XJP7lxbSxWLOMNdBE4B/STaqVy6L73o0knwj2vIlxnw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/klog/v2 v2.0.0 h1:Foj74zO6RbjjP4hBEKjnYtjjAhGg4jNynUdYF6fJrok= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= diff --git a/pkg/control/control.go b/pkg/control/control.go index 848b916..87c81ff 100755 --- a/pkg/control/control.go +++ b/pkg/control/control.go @@ -71,6 +71,7 @@ var e2tRecvMsgTimeout time.Duration var waitRouteCleanup_ms time.Duration var e2tMaxSubReqTryCount uint64 // Initial try + retry var e2tMaxSubDelReqTryCount uint64 // Initial try + retry +var checkE2State string var readSubsFromDb string var dbRetryForever string var dbTryCount int @@ -81,6 +82,8 @@ type Control struct { registry *Registry tracker *Tracker restDuplicateCtrl *DuplicateCtrl + e2IfState *E2IfState + e2IfStateDb XappRnibInterface e2SubsDb Sdlnterface restSubsDb Sdlnterface CntRecvMsg uint64 @@ -136,15 +139,21 @@ func NewControl() *Control { restDuplicateCtrl := new(DuplicateCtrl) restDuplicateCtrl.Init() + e2IfState := new(E2IfState) + c := &Control{e2ap: new(E2ap), registry: registry, tracker: tracker, restDuplicateCtrl: restDuplicateCtrl, + e2IfState: e2IfState, + e2IfStateDb: CreateXappRnibIfInstance(), e2SubsDb: CreateSdl(), restSubsDb: CreateRESTSdl(), Counters: xapp.Metric.RegisterCounterGroup(GetMetricsOpts(), "SUBMGR"), LoggerLevel: 4, } + + e2IfState.Init(c) c.ReadConfigParameters("") // Register REST handler for testing support @@ -229,64 +238,83 @@ func (c *Control) ReadRESTSubscriptions() error { //------------------------------------------------------------------- func (c *Control) ReadConfigParameters(f string) { + xapp.Logger.Debug("ReadConfigParameters") + c.LoggerLevel = int(xapp.Logger.GetLevel()) - xapp.Logger.Debug("LoggerLevel %v", c.LoggerLevel) + xapp.Logger.Debug("LoggerLevel= %v", c.LoggerLevel) // viper.GetDuration returns nanoseconds e2tSubReqTimeout = viper.GetDuration("controls.e2tSubReqTimeout_ms") * 1000000 if e2tSubReqTimeout == 0 { e2tSubReqTimeout = 2000 * 1000000 + xapp.Logger.Debug("WARNING: Using hard coded default value for e2tSubReqTimeout") } - xapp.Logger.Debug("e2tSubReqTimeout %v", e2tSubReqTimeout) + xapp.Logger.Debug("e2tSubReqTimeout= %v", e2tSubReqTimeout) e2tSubDelReqTime = viper.GetDuration("controls.e2tSubDelReqTime_ms") * 1000000 if e2tSubDelReqTime == 0 { e2tSubDelReqTime = 2000 * 1000000 + xapp.Logger.Debug("WARNING: Using hard coded default value for e2tSubDelReqTime") } - xapp.Logger.Debug("e2tSubDelReqTime %v", e2tSubDelReqTime) + xapp.Logger.Debug("e2tSubDelReqTime= %v", e2tSubDelReqTime) + e2tRecvMsgTimeout = viper.GetDuration("controls.e2tRecvMsgTimeout_ms") * 1000000 if e2tRecvMsgTimeout == 0 { e2tRecvMsgTimeout = 2000 * 1000000 + xapp.Logger.Debug("WARNING: Using hard coded default value for e2tRecvMsgTimeout") } - xapp.Logger.Debug("e2tRecvMsgTimeout %v", e2tRecvMsgTimeout) + xapp.Logger.Debug("e2tRecvMsgTimeout= %v", e2tRecvMsgTimeout) e2tMaxSubReqTryCount = viper.GetUint64("controls.e2tMaxSubReqTryCount") if e2tMaxSubReqTryCount == 0 { e2tMaxSubReqTryCount = 1 + xapp.Logger.Debug("WARNING: Using hard coded default value for e2tMaxSubReqTryCount") } - xapp.Logger.Debug("e2tMaxSubReqTryCount %v", e2tMaxSubReqTryCount) + xapp.Logger.Debug("e2tMaxSubReqTryCount= %v", e2tMaxSubReqTryCount) e2tMaxSubDelReqTryCount = viper.GetUint64("controls.e2tMaxSubDelReqTryCount") if e2tMaxSubDelReqTryCount == 0 { e2tMaxSubDelReqTryCount = 1 + xapp.Logger.Debug("WARNING: Using hard coded default value for e2tMaxSubDelReqTryCount") + } + xapp.Logger.Debug("e2tMaxSubDelReqTryCount= %v", e2tMaxSubDelReqTryCount) + + checkE2State = viper.GetString("controls.checkE2State") + if checkE2State == "" { + checkE2State = "true" + xapp.Logger.Debug("WARNING: Using hard coded default value for checkE2State") } - xapp.Logger.Debug("e2tMaxSubDelReqTryCount %v", e2tMaxSubDelReqTryCount) + xapp.Logger.Debug("checkE2State= %v", checkE2State) readSubsFromDb = viper.GetString("controls.readSubsFromDb") if readSubsFromDb == "" { readSubsFromDb = "true" + xapp.Logger.Debug("WARNING: Using hard coded default value for readSubsFromDb") } - xapp.Logger.Debug("readSubsFromDb %v", readSubsFromDb) + xapp.Logger.Debug("readSubsFromDb= %v", readSubsFromDb) dbTryCount = viper.GetInt("controls.dbTryCount") if dbTryCount == 0 { dbTryCount = 200 + xapp.Logger.Debug("WARNING: Using hard coded default value for dbTryCount") } - xapp.Logger.Debug("dbTryCount %v", dbTryCount) + xapp.Logger.Debug("dbTryCount= %v", dbTryCount) dbRetryForever = viper.GetString("controls.dbRetryForever") if dbRetryForever == "" { dbRetryForever = "true" + xapp.Logger.Debug("WARNING: Using hard coded default value for dbRetryForever") } - xapp.Logger.Debug("dbRetryForever %v", dbRetryForever) + xapp.Logger.Debug("dbRetryForever= %v", dbRetryForever) // Internal cfg parameter, used to define a wait time for RMR route clean-up. None default // value 100ms used currently only in unittests. waitRouteCleanup_ms = viper.GetDuration("controls.waitRouteCleanup_ms") * 1000000 if waitRouteCleanup_ms == 0 { waitRouteCleanup_ms = 5000 * 1000000 + xapp.Logger.Debug("WARNING: Using hard coded default value for waitRouteCleanup_ms") } - xapp.Logger.Debug("waitRouteCleanup %v", waitRouteCleanup_ms) + xapp.Logger.Debug("waitRouteCleanup= %v", waitRouteCleanup_ms) } //------------------------------------------------------------------- @@ -389,6 +417,12 @@ func (c *Control) RESTSubscriptionHandler(params interface{}) (*models.Subscript c.PrintRESTSubscriptionRequest(p) } + if c.e2IfState.IsE2ConnectionUp(p.Meid) == false { + xapp.Logger.Error("No E2 connection for ranName %v", *p.Meid) + c.UpdateCounter(cRestReqRejDueE2Down) + return nil, common.SubscribeServiceUnavailableCode + } + if p.ClientEndpoint == nil { err := fmt.Errorf("ClientEndpoint == nil") xapp.Logger.Error("%v", err) @@ -566,15 +600,25 @@ func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e // // Wake subs request // + subs.OngoingReqCount++ go c.handleSubscriptionCreate(subs, trans, e2SubscriptionDirectives) event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side + subs.OngoingReqCount-- err = nil if event != nil { switch themsg := event.(type) { case *e2ap.E2APSubscriptionResponse: trans.Release() - return themsg, &errorInfo, nil + if c.e2IfState.IsE2ConnectionUp(meid) == true { + return themsg, &errorInfo, nil + } else { + c.registry.RemoveFromSubscription(subs, trans, waitRouteCleanup_ms, c) + c.RemoveSubscriptionFromDb(subs) + err = fmt.Errorf("E2 interface down") + errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "") + return nil, &errorInfo, err + } case *e2ap.E2APSubscriptionFailure: err = fmt.Errorf("E2 SubscriptionFailure received") errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "") @@ -638,6 +682,11 @@ func (c *Control) sendUnsuccesfullResponseNotification(restSubId *string, restSu c.UpdateCounter(cRestSubFailNotifToXapp) xapp.Subscription.Notify(resp, *clientEndpoint) + + if c.e2IfState.IsE2ConnectionUp(&restSubscription.Meid) == false && restSubscription.SubReqOngoing == false { + c.registry.DeleteRESTSubscription(restSubId) + c.RemoveRESTSubscriptionFromDb(*restSubId) + } } //------------------------------------------------------------------- @@ -667,6 +716,11 @@ func (c *Control) sendSuccesfullResponseNotification(restSubId *string, restSubs c.UpdateCounter(cRestSubNotifToXapp) xapp.Subscription.Notify(resp, *clientEndpoint) + + if c.e2IfState.IsE2ConnectionUp(&restSubscription.Meid) == false && restSubscription.SubReqOngoing == false { + c.registry.DeleteRESTSubscription(restSubId) + c.RemoveRESTSubscriptionFromDb(*restSubId) + } } //------------------------------------------------------------------- @@ -684,14 +738,17 @@ func (c *Control) RESTSubscriptionDeleteHandler(restSubId string) int { xapp.Logger.Error("%s", err.Error()) if restSubscription == nil { // Subscription was not found + c.UpdateCounter(cRestSubDelRespToXapp) return common.UnsubscribeNoContentCode } else { if restSubscription.SubReqOngoing == true { err := fmt.Errorf("Handling of the REST Subscription Request still ongoing %s", restSubId) xapp.Logger.Error("%s", err.Error()) + c.UpdateCounter(cRestSubDelFailToXapp) return common.UnsubscribeBadRequestCode } else if restSubscription.SubDelReqOngoing == true { // Previous request for same restSubId still ongoing + c.UpdateCounter(cRestSubDelFailToXapp) return common.UnsubscribeBadRequestCode } } @@ -716,7 +773,6 @@ func (c *Control) RESTSubscriptionDeleteHandler(restSubId string) int { }() c.UpdateCounter(cRestSubDelRespToXapp) - return common.UnsubscribeNoContentCode } @@ -750,8 +806,10 @@ func (c *Control) SubscriptionDeleteHandler(restSubId *string, endPoint *string, // // Wake subs delete // + subs.OngoingDelCount++ go c.handleSubscriptionDelete(subs, trans) trans.WaitEvent(0) //blocked wait as timeout is handled in subs side + subs.OngoingDelCount-- xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs)) @@ -891,6 +949,11 @@ func (c *Control) handleXAPPSubscriptionRequest(params *xapp.RMRParams) { xapp.Logger.Debug("MSG from XAPP: %s", params.String()) c.UpdateCounter(cSubReqFromXapp) + if c.e2IfState.IsE2ConnectionUp(¶ms.Meid.RanName) == false { + xapp.Logger.Error("No E2 connection for ranName %v", params.Meid.RanName) + return + } + subReqMsg, err := c.e2ap.UnpackSubscriptionRequest(params.Payload) if err != nil { xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, params)) @@ -925,8 +988,10 @@ func (c *Control) handleXAPPSubscriptionRequest(params *xapp.RMRParams) { func (c *Control) wakeSubscriptionRequest(subs *Subscription, trans *TransactionXapp) { e2SubscriptionDirectives, _ := c.GetE2SubscriptionDirectives(nil) + subs.OngoingReqCount++ go c.handleSubscriptionCreate(subs, trans, e2SubscriptionDirectives) event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side + subs.OngoingReqCount-- var err error if event != nil { switch themsg := event.(type) { @@ -961,6 +1026,11 @@ func (c *Control) handleXAPPSubscriptionDeleteRequest(params *xapp.RMRParams) { xapp.Logger.Debug("MSG from XAPP: %s", params.String()) c.UpdateCounter(cSubDelReqFromXapp) + if c.e2IfState.IsE2ConnectionUp(¶ms.Meid.RanName) == false { + xapp.Logger.Error("No E2 connection for ranName %v", params.Meid.RanName) + return + } + subDelReqMsg, err := c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload) if err != nil { xapp.Logger.Error("XAPP-SubDelReq %s", idstring(err, params)) @@ -989,8 +1059,10 @@ func (c *Control) handleXAPPSubscriptionDeleteRequest(params *xapp.RMRParams) { // // Wake subs delete // + subs.OngoingDelCount++ go c.handleSubscriptionDelete(subs, trans) trans.WaitEvent(0) //blocked wait as timeout is handled in subs side + subs.OngoingDelCount-- xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs)) diff --git a/pkg/control/e2if_state.go b/pkg/control/e2if_state.go new file mode 100644 index 0000000..0f43056 --- /dev/null +++ b/pkg/control/e2if_state.go @@ -0,0 +1,176 @@ +/* +================================================================================== + Copyright (c) 2019 AT&T Intellectual Property. + Copyright (c) 2019 Nokia + + 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. +================================================================================== +*/ + +package control + +import ( + "fmt" + "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" + "strings" + "sync" +) + +type XappRnibIf struct { + XappRnibInterface +} + +func (x *XappRnibIf) XappRnibSubscribe(NotificationCb func(string, ...string), channel string) error { + return xapp.Rnib.Subscribe(NotificationCb, channel) +} + +func (x *XappRnibIf) XappRnibGetListGnbIds() ([]*xapp.RNIBNbIdentity, xapp.RNIBIRNibError) { + return xapp.Rnib.GetListGnbIds() +} +func (x *XappRnibIf) XappRnibGetNodeb(inventoryName string) (*xapp.RNIBNodebInfo, xapp.RNIBIRNibError) { + nodeInfo, err := xapp.Rnib.GetNodeb(inventoryName) + return nodeInfo, err +} + +func CreateXappRnibIfInstance() XappRnibInterface { + return new(XappRnibIf) +} + +type E2IfState struct { + mutex sync.Mutex + control *Control + NbIdMap map[string]string +} + +func (e *E2IfState) Init(c *Control) { + e.control = c + e.NbIdMap = make(map[string]string, 0) + e.ReadE2ConfigurationFromRnib() + e.SubscribeChannels() +} + +func (e *E2IfState) NotificationCb(ch string, events ...string) { + + xapp.Logger.Debug("SDL notification received from channel=%s, event=%v", ch, events[0]) + if len(events) == 0 { + xapp.Logger.Error("Invalid SDL notification received: %d", len(events)) + return + } + + if strings.Contains(events[0], "_CONNECTED") { + nbId, err := ExtractNbiIdFromString(events[0]) + if err != nil { + xapp.Logger.Error("NotificationCb CONNECTED len(nbId) == 0 ") + return + } + xapp.Logger.Debug("E2 CONNECTED. NbId=%s", nbId) + e.NbIdMap[nbId] = nbId + } else if strings.Contains(events[0], "_DISCONNECTED") { + nbId, err := ExtractNbiIdFromString(events[0]) + if err != nil { + xapp.Logger.Error("NotificationCb DISCONNECTED len(nbId) == 0 ") + return + } + xapp.Logger.Debug("E2 DISCONNECTED. NbId=%s", nbId) + if _, ok := e.NbIdMap[nbId]; ok { + delete(e.NbIdMap, nbId) + e.control.registry.DeleteAllE2Subscriptions(nbId, e.control) + } + } +} + +func (e *E2IfState) SubscribeChannels() error { + + if err := e.control.e2IfStateDb.XappRnibSubscribe(e.NotificationCb, "RAN_CONNECTION_STATUS_CHANGE"); err != nil { + xapp.Logger.Error("Sdl.SubscribeChannel failed: %v", err) + return err + } + xapp.Logger.Debug("Subscription to RAN state changes done!") + return nil +} + +func (e *E2IfState) ReadE2ConfigurationFromRnib() { + + xapp.Logger.Debug("ReadE2ConfigurationFromRnib()") + nbIdentities, err := e.control.e2IfStateDb.XappRnibGetListGnbIds() + if err != nil || len(nbIdentities) == 0 { + xapp.Logger.Debug("There are no active NodeBs available: %v", err) + e.NbIdMap = make(map[string]string, 0) + return + } + + for _, nbIdentity := range nbIdentities { + if e.isNodeBActive(nbIdentity.InventoryName) == false { + if _, ok := e.NbIdMap[nbIdentity.InventoryName]; ok { + delete(e.NbIdMap, nbIdentity.InventoryName) + e.control.UpdateCounter(cE2StateChangedToDown) + xapp.Logger.Debug("E2 connection DISCONNETED: %v", nbIdentity.InventoryName) + + // Delete all subscriptions related to InventoryName/nbId + e.control.registry.DeleteAllE2Subscriptions(nbIdentity.InventoryName, e.control) + } + continue + } + + if _, ok := e.NbIdMap[nbIdentity.InventoryName]; !ok { + e.NbIdMap[nbIdentity.InventoryName] = nbIdentity.InventoryName + e.control.UpdateCounter(cE2StateChangedToDown) + xapp.Logger.Debug("E2 connection CONNECTED: %v", nbIdentity.InventoryName) + } + } +} + +func (e *E2IfState) isNodeBActive(inventoryName string) bool { + nodeInfo, err := e.control.e2IfStateDb.XappRnibGetNodeb(inventoryName) + if err != nil { + xapp.Logger.Error("GetNodeb() failed for inventoryName=%s: %v", inventoryName, err) + return false + } + xapp.Logger.Debug("NodeB['%s'] connection status = %d", inventoryName, nodeInfo.ConnectionStatus) + return nodeInfo.ConnectionStatus == 1 +} + +func (e *E2IfState) IsE2ConnectionUp(nbId *string) bool { + + if checkE2State == "false" { + return true + } + + if _, ok := e.NbIdMap[*nbId]; ok { + return true + } else { + return false + } +} + +func ExtractNbiIdFromString(s string) (string, error) { + + // Expected string formats are below + // gnb_208_092_303030_CONNECTED + // gnb_208_092_303030_DISCONNECTED + // ... + + var nbId string + var err error + if strings.Contains(s, "_CONNECTED") { + splitStringTbl := strings.Split(s, "_CONNECTED") + nbId = splitStringTbl[0] + } else if strings.Contains(s, "_DISCONNECTED") { + splitStringTbl := strings.Split(s, "_DISCONNECTED") + nbId = splitStringTbl[0] + } + if len(nbId) == 0 { + return "", fmt.Errorf("ExtractNbiIdFromString(): len(nbId) == 0 ") + } + return nbId, err +} diff --git a/pkg/control/e2if_state_test.go b/pkg/control/e2if_state_test.go new file mode 100644 index 0000000..e4ee848 --- /dev/null +++ b/pkg/control/e2if_state_test.go @@ -0,0 +1,247 @@ +/* +================================================================================== + Copyright (c) 2019 AT&T Intellectual Property. + Copyright (c) 2019 Nokia + + 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. +================================================================================== +*/ + +package control + +import ( + "fmt" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" + "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" + "strings" + "sync" + "testing" +) + +var xappRnibMock *XappRnibMock + +type XappRnibMock struct { + Mutex sync.Mutex + nbIdentityMap map[string]xapp.RNIBNbIdentity + RNIBNodebInfoMap map[string]xapp.RNIBNodebInfo + RnibSubscription RnibSubscription // Submgr can have only one subscription +} + +type RnibSubscription struct { + Channel string // Subscribed channel/topic "RAN_CONNECTION_STATUS_CHANGE" + cb func(ch string, events ...string) // Submgr's call back function +} + +func CreateXappRnibIfMock() *XappRnibMock { + fmt.Println("XappRnibMock: CreateXappRnibIfMock()") + xappRnibMock = new(XappRnibMock) + xappRnibMock.Init() + return xappRnibMock +} + +func (x *XappRnibMock) Init() { + x.nbIdentityMap = make(map[string]xapp.RNIBNbIdentity, 0) + x.RNIBNodebInfoMap = make(map[string]xapp.RNIBNodebInfo, 0) +} + +func TestMock(t *testing.T) { + + // Current UT test cases use these ran names + xappRnibMock.CreateGnb("RAN_NAME_1", entities.ConnectionStatus_CONNECTED) + xappRnibMock.CreateGnb("RAN_NAME_11", entities.ConnectionStatus_CONNECTED) + xappRnibMock.CreateGnb("RAN_NAME_2", entities.ConnectionStatus_CONNECTED) + + xappRnibMock.CreateGnb("gnb_208_092_303030", entities.ConnectionStatus_CONNECTED) // This same value is used in gnb simulator! + xappRnibMock.CreateGnb("gnb_208_092_303030", entities.ConnectionStatus_DISCONNECTED) + + xappRnibMock.CreateGnb("gnb_369_11105_aaaaa3", entities.ConnectionStatus_UNKNOWN_CONNECTION_STATUS) + xappRnibMock.CreateGnb("gnb_369_11105_aaaaa3", entities.ConnectionStatus_CONNECTED_SETUP_FAILED) + xappRnibMock.CreateGnb("gnb_369_11105_aaaaa3", entities.ConnectionStatus_CONNECTING) + xappRnibMock.CreateGnb("gnb_369_11105_aaaaa3", entities.ConnectionStatus_CONNECTED) + xappRnibMock.CreateGnb("gnb_369_11105_aaaaa3", entities.ConnectionStatus_SHUTTING_DOWN) + xappRnibMock.CreateGnb("gnb_369_11105_aaaaa3", entities.ConnectionStatus_SHUT_DOWN) + xappRnibMock.CreateGnb("gnb_369_11105_aaaaa3", entities.ConnectionStatus_DISCONNECTED) + + mainCtrl.c.e2IfState.ReadE2ConfigurationFromRnib() + mainCtrl.c.e2IfState.SubscribeChannels() + if err := xappRnibMock.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", "gnb_369_11105_aaaaa3_UNKNOWN_CONNECTION_STATUS", "key1", "data1"); err != nil { + t.Errorf("XappRnibStoreAndPublish failed: %v", err) + } + if err := xappRnibMock.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", "gnb_369_11105_aaaaa3_CONNECTED_SETUP_FAILED", "key1", "data1"); err != nil { + t.Errorf("XappRnibStoreAndPublish failed: %v", err) + } + if err := xappRnibMock.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", "gnb_369_11105_aaaaa3_CONNECTING", "key1", "data1"); err != nil { + t.Errorf("XappRnibStoreAndPublish failed: %v", err) + } + if err := xappRnibMock.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", "gnb_369_11105_aaaaa3_CONNECTED", "key1", "data1"); err != nil { + t.Errorf("XappRnibStoreAndPublish failed: %v", err) + } + if err := xappRnibMock.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", "gnb_369_11105_aaaaa3_SHUTTING_DOWN", "key1", "data1"); err != nil { + t.Errorf("XappRnibStoreAndPublish failed: %v", err) + } + if err := xappRnibMock.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", "gnb_369_11105_aaaaa3_DISCONNECTED", "key1", "data1"); err != nil { + t.Errorf("XappRnibStoreAndPublish failed: %v", err) + } +} + +func (x *XappRnibMock) CreateGnb(gnbId string, connectionStatus entities.ConnectionStatus) { + + xapp.Logger.Debug("XappRnibMock: CreateGnb() gnbId=%v, ConnectionStatus=%v", gnbId, connectionStatus) + nb := xapp.RNIBNodebInfo{} + nb.NodeType = xapp.RNIBNodeGNB + nb.ConnectionStatus = connectionStatus + if nb.ConnectionStatus < 0 || nb.ConnectionStatus > 6 { + xapp.Logger.Error("XappRnibMock: CreateGnb() Incorrect connectionStatus=%v", nb.ConnectionStatus) + return + } + nb.Ip = "localhost" + nb.Port = 5656 + gnb := xapp.RNIBGnb{} + + gnb.ServedNrCells = nil + nb.Configuration = &xapp.RNIBNodebInfoGnb{Gnb: &gnb} + nbIdentity := &xapp.RNIBNbIdentity{ + InventoryName: gnbId, + GlobalNbId: &xapp.RNIBGlobalNbId{ + PlmnId: "001EF5", + NbId: "0045FE50", + }, + } + + err := xappRnibMock.XappRnibSaveNodeb(nbIdentity, &nb) + if err != nil { + xapp.Logger.Error("XappRnibMock: XappRnibSaveNodeb() failed. Error: %v", err) + } +} + +func (x *XappRnibMock) XappRnibSaveNodeb(nbIdentity *xapp.RNIBNbIdentity, nodeb *xapp.RNIBNodebInfo) xapp.RNIBIRNibError { + + xapp.Logger.Debug("XappRnibMock: XappRnibSaveNodeb() inventoryName=%v, ConnectionStatus=%v", nbIdentity.InventoryName, nodeb.ConnectionStatus) + x.Mutex.Lock() + defer x.Mutex.Unlock() + x.nbIdentityMap[nbIdentity.InventoryName] = *nbIdentity + x.RNIBNodebInfoMap[nbIdentity.InventoryName] = *nodeb + return nil +} + +func (x *XappRnibMock) XappRnibGetNodeb(inventoryName string) (*xapp.RNIBNodebInfo, xapp.RNIBIRNibError) { + + x.Mutex.Lock() + defer x.Mutex.Unlock() + xapp.Logger.Debug("XappRnibMock: XappRnibGetNodeb() inventoryName=%v", inventoryName) + nodebInfo, ok := x.RNIBNodebInfoMap[inventoryName] + if ok { + return &nodebInfo, nil + } else { + return nil, fmt.Errorf("XappRnibMock: XappRnibGetNodeb() failed: inventoryName=%s:", inventoryName) + } +} + +func (x *XappRnibMock) XappRnibSubscribe(cb func(string, ...string), channel string) error { + + if x.RnibSubscription.Channel == "RAN_CONNECTION_STATUS_CHANGE" { + xapp.Logger.Debug("XappRnibMock: RAN_CONNECTION_STATUS_CHANGE channel already subscribed") + return nil + } + if x.RnibSubscription.Channel == "" { + x.RnibSubscription.cb = cb + x.RnibSubscription.Channel = channel + xapp.Logger.Debug("XappRnibMock: RAN_CONNECTION_STATUS_CHANGE subscribed") + return nil + } else { + return fmt.Errorf("XappRnibMock: Invalid channel/topic to subscribe: channel = %s", channel) + } +} + +func (x *XappRnibMock) XappRnibGetListGnbIds() ([]*xapp.RNIBNbIdentity, xapp.RNIBIRNibError) { + + xapp.Logger.Debug("XappRnibMock: XappRnibGetListGnbIds()") + x.Mutex.Lock() + defer x.Mutex.Unlock() + var nbIdentities []*xapp.RNIBNbIdentity + for _, nbIdentity := range x.nbIdentityMap { + newNbIdentity := entities.NbIdentity{} + newNbIdentity = nbIdentity + nbIdentities = append(nbIdentities, &newNbIdentity) + } + xapp.Logger.Debug("XappRnibMock: XappRnibGetListGnbIds(). len(nbIdentities) = %v", len(nbIdentities)) + return nbIdentities, nil +} + +func (x *XappRnibMock) XappRnibStoreAndPublish(channel string, event string, pairs ...interface{}) error { + + x.Mutex.Lock() + defer x.Mutex.Unlock() + xapp.Logger.Debug("XappRnibMock: Change published. channel=%s, event=%s", channel, event) + if channel != "RAN_CONNECTION_STATUS_CHANGE" || channel == "" || event == "" { + xapp.Logger.Debug("XappRnibMock: Invalid change published. channel=%s, event=%s", channel, event) + } + + nbId, connectionStatus, err := ExtratNbIdAndConnectionStatus(event) + if err != nil { + xapp.Logger.Error("XappRnibMock: ExtratNbIdAndConnectionStatus. Err=%s", err) + } + + nbIdentity, ok := x.nbIdentityMap[nbId] + if ok { + nbIdentity.ConnectionStatus = connectionStatus + } + + if x.RnibSubscription.cb != nil { + x.RnibSubscription.cb(channel, event) + } else { + xapp.Logger.Error("XappRnibMock: x.RnibSubscription.cb == nil") + } + return nil +} + +func ExtratNbIdAndConnectionStatus(s string) (string, entities.ConnectionStatus, error) { + + var connectionStatus entities.ConnectionStatus + var nbId string + if strings.Contains(s, "_UNKNOWN_CONNECTION_STATUS") { + connectionStatus = entities.ConnectionStatus_UNKNOWN_CONNECTION_STATUS + splitStringTbl := strings.Split(s, "_UNKNOWN_CONNECTION_STATUS") + nbId = splitStringTbl[0] + } else if strings.Contains(s, "_CONNECTED") { + connectionStatus = entities.ConnectionStatus_CONNECTED + splitStringTbl := strings.Split(s, "_CONNECTED") + nbId = splitStringTbl[0] + } else if strings.Contains(s, "_DISCONNECTED") { + connectionStatus = entities.ConnectionStatus_DISCONNECTED + splitStringTbl := strings.Split(s, "_DISCONNECTED") + nbId = splitStringTbl[0] + } else if strings.Contains(s, "_CONNECTED_SETUP_FAILED") { + connectionStatus = entities.ConnectionStatus_CONNECTED_SETUP_FAILED + splitStringTbl := strings.Split(s, "_CONNECTED_SETUP_FAILED") + nbId = splitStringTbl[0] + } else if strings.Contains(s, "_CONNECTING") { + connectionStatus = entities.ConnectionStatus_CONNECTING + splitStringTbl := strings.Split(s, "_CONNECTING") + nbId = splitStringTbl[0] + } else if strings.Contains(s, "_SHUTTING_DOWN") { + connectionStatus = entities.ConnectionStatus_SHUTTING_DOWN + splitStringTbl := strings.Split(s, "_SHUTTING_DOWN") + nbId = splitStringTbl[0] + } else if strings.Contains(s, "_SHUT_DOWN") { + connectionStatus = entities.ConnectionStatus_SHUT_DOWN + splitStringTbl := strings.Split(s, "_SHUT_DOWN") + nbId = splitStringTbl[0] + } else { + return "", 0, fmt.Errorf("XappRnibMock: Invalid connection status. %s", s) + } + if len(nbId) == 0 { + return "", 0, fmt.Errorf("ExtractNbiIdFromString(): len(nbId) == 0 ") + } + return nbId, connectionStatus, nil +} diff --git a/pkg/control/metrics.go b/pkg/control/metrics.go index 0f514b4..8493379 100644 --- a/pkg/control/metrics.go +++ b/pkg/control/metrics.go @@ -11,6 +11,7 @@ const ( cSubRespToXapp string = "SubRespToXapp" cRestSubRespToXapp string = "RestSubRespToXapp" cRestSubFailToXapp string = "RestSubFailToXapp" + cRestReqRejDueE2Down string = "RestReqRejDueE2Down" cRestSubNotifToXapp string = "RestSubNotifToXapp" cRestSubFailNotifToXapp string = "RestSubFailNotifToXapp" cSubReqToE2 string = "SubReqToE2" @@ -26,6 +27,7 @@ const ( cSubDelRespToXapp string = "SubDelRespToXapp" cRestSubDelReqFromXapp string = "RestSubDelReqFromXapp" cRestSubDelRespToXapp string = "RestSubDelRespToXapp" + cRestSubDelFailToXapp string = "RestSubDelFailToXapp" cSubDelReqToE2 string = "SubDelReqToE2" cSubDelReReqToE2 string = "SubDelReReqToE2" cSubDelRespFromE2 string = "SubDelRespFromE2" @@ -37,6 +39,8 @@ const ( cSDLWriteFailure string = "SDLWriteFailure" cSDLReadFailure string = "SDLReadFailure" cSDLRemoveFailure string = "SDLRemoveFailure" + cE2StateChangedToUp string = "E2StateChangedToUp" + cE2StateChangedToDown string = "E2StateChangedToDown" ) func GetMetricsOpts() []xapp.CounterOpts { @@ -49,6 +53,7 @@ func GetMetricsOpts() []xapp.CounterOpts { {Name: cRestSubReqFromXapp, Help: "The total number of Rest SubscriptionRequest messages received from xApp"}, {Name: cRestSubRespToXapp, Help: "The total number of Rest SubscriptionResponse messages sent to xApp"}, {Name: cRestSubFailToXapp, Help: "The total number of Rest SubscriptionFailure messages sent to xApp"}, + {Name: cRestReqRejDueE2Down, Help: "The total number of Rest SubscriptionRequest messages rejected due E2 Interface down"}, {Name: cRestSubNotifToXapp, Help: "The total number of successful Rest SubscriptionNotification messages sent to xApp"}, {Name: cRestSubFailNotifToXapp, Help: "The total number of failure Rest SubscriptionNotification messages sent to xApp"}, {Name: cSubReqToE2, Help: "The total number of SubscriptionRequest messages sent to E2Term"}, @@ -66,6 +71,7 @@ func GetMetricsOpts() []xapp.CounterOpts { {Name: cSubDelRespToXapp, Help: "The total number of SubscriptionDeleteResponse messages sent to xApp"}, {Name: cRestSubDelReqFromXapp, Help: "The total number of Rest SubscriptionDeleteRequest messages received from xApp"}, {Name: cRestSubDelRespToXapp, Help: "The total number of Rest SubscriptionDeleteResponse messages sent to xApp"}, + {Name: cRestSubDelFailToXapp, Help: "The total number of Rest SubscriptionDeleteFailure messages sent to xApp"}, {Name: cSubDelReqToE2, Help: "The total number of SubscriptionDeleteRequest messages sent to E2Term"}, {Name: cSubDelReReqToE2, Help: "The total number of SubscriptionDeleteRequest messages resent to E2Term"}, {Name: cSubDelRespFromE2, Help: "The total number of SubscriptionDeleteResponse messages from E2Term"}, @@ -79,9 +85,14 @@ func GetMetricsOpts() []xapp.CounterOpts { {Name: cSDLWriteFailure, Help: "The total number of SDL write failures"}, {Name: cSDLReadFailure, Help: "The total number of SDL read failures"}, {Name: cSDLRemoveFailure, Help: "The total number of SDL read failures"}, + + // E2 interface state counters + {Name: cE2StateChangedToUp, Help: "The total number of E2 interface change connected state"}, + {Name: cE2StateChangedToDown, Help: "The total number of E2 interface change disconnected state"}, } } func (c *Control) UpdateCounter(counterName string) { + xapp.Logger.Debug("Add counterName=%v", counterName) c.Counters[counterName].Inc() } diff --git a/pkg/control/registry.go b/pkg/control/registry.go index 4b48687..8c79540 100644 --- a/pkg/control/registry.go +++ b/pkg/control/registry.go @@ -181,6 +181,8 @@ func (r *Registry) allocateSubs(trans *TransactionXapp, subReqMsg *e2ap.E2APSubs Meid: trans.Meid, RMRRouteCreated: rmrRoutecreated, SubReqMsg: subReqMsg, + OngoingReqCount: 0, + OngoingDelCount: 0, valid: true, PolicyUpdate: false, RetryFromXapp: false, @@ -405,7 +407,6 @@ func (r *Registry) RemoveFromSubscription(subs *Subscription, trans *Transaction delStatus := subs.EpList.DelEndpoint(trans.GetEndpoint()) epamount := subs.EpList.Size() subId := subs.ReqId.InstanceId - if delStatus == false { return nil } @@ -518,3 +519,49 @@ func (r *Registry) SetResetTestFlag(resetTestFlag bool, subs *Subscription) { xapp.Logger.Debug("resetTestFlag == false") } } + +func (r *Registry) DeleteAllE2Subscriptions(ranName string, c *Control) { + + xapp.Logger.Debug("Registry: DeleteAllE2Subscriptions()") + for subId, subs := range r.register { + if subs.Meid.RanName == ranName { + if subs.OngoingReqCount != 0 || subs.OngoingDelCount != 0 { + // Subscription creation or deletion processes need to be processed gracefully till the end. + // Subscription is deleted at end of the process in both cases. + xapp.Logger.Debug("Registry: E2 subscription under prosessing ongoing cannot delete it yet. subId=%v, OngoingReqCount=%v, OngoingDelCount=%v", subId, subs.OngoingReqCount, subs.OngoingDelCount) + continue + } else { + // Delete route + if subs.RMRRouteCreated == true { + for _, ep := range subs.EpList.Endpoints { + tmpList := xapp.RmrEndpointList{} + tmpList.AddEndpoint(&ep) + subRouteAction := SubRouteInfo{tmpList, uint16(subs.ReqId.InstanceId)} + if err := r.rtmgrClient.SubscriptionRequestDelete(subRouteAction); err != nil { + c.UpdateCounter(cRouteDeleteFail) + } + } + } + // Delete E2 subscription from registry and db + xapp.Logger.Debug("Registry: Subscription delete. subId=%v", subId) + delete(r.register, subId) + r.subIds = append(r.subIds, subId) + c.RemoveSubscriptionFromDb(subs) + } + } + } + + // Delete REST subscription from registry and db + for restSubId, restSubs := range r.restSubscriptions { + if restSubs.Meid == ranName && restSubs.SubReqOngoing == true || restSubs.SubDelReqOngoing == true { + // Subscription creation or deletion processes need to be processed gracefully till the end. + // Subscription is deleted at end of the process in both cases. + xapp.Logger.Debug("Registry: REST subscription under prosessing ongoing cannot delete it yet. RestSubId=%v, SubReqOngoing=%v, SubDelReqOngoing=%v", restSubId, restSubs.SubReqOngoing, restSubs.SubDelReqOngoing) + continue + } else { + xapp.Logger.Debug("Registry: REST subscription delete. subId=%v", restSubId) + delete(r.restSubscriptions, restSubId) + c.RemoveRESTSubscriptionFromDb(restSubId) + } + } +} diff --git a/pkg/control/subscription.go b/pkg/control/subscription.go index 1152520..58f0adf 100644 --- a/pkg/control/subscription.go +++ b/pkg/control/subscription.go @@ -41,6 +41,8 @@ type Subscription struct { TheTrans TransactionIf // Ongoing transaction SubReqMsg *e2ap.E2APSubscriptionRequest // Subscription information SubRFMsg interface{} // Subscription information + OngoingReqCount int // Subscription create process is ongoing. In merge case it can ongoing for more than one endpoint + OngoingDelCount int // Subscription delete process is ongoing. In merge case it can ongoing for more than one endpoint PolicyUpdate bool // This is true when policy subscrition is being updated. Used not to send delete for update after timeout or restart RetryFromXapp bool // Retry form xApp for subscription that already exist SubRespRcvd bool // Subscription response received diff --git a/pkg/control/types.go b/pkg/control/types.go index 93cddb0..22c8bc4 100644 --- a/pkg/control/types.go +++ b/pkg/control/types.go @@ -23,6 +23,7 @@ import ( "time" "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap" + "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" ) //----------------------------------------------------------------------------- @@ -71,3 +72,10 @@ func (e *ErrorInfo) SetInfo(errorCause string, errorSource string, timeoutType s e.ErrorSource = errorSource e.TimeoutType = timeoutType } + +type XappRnibInterface interface { + XappRnibSubscribe(cb func(string, ...string), channel string) error + XappRnibGetListGnbIds() ([]*xapp.RNIBNbIdentity, xapp.RNIBIRNibError) + XappRnibStoreAndPublish(channel string, event string, pairs ...interface{}) error + XappRnibGetNodeb(inventoryName string) (*xapp.RNIBNodebInfo, xapp.RNIBIRNibError) +} diff --git a/pkg/control/ut_ctrl_submgr_test.go b/pkg/control/ut_ctrl_submgr_test.go index e514cb0..8d559bd 100644 --- a/pkg/control/ut_ctrl_submgr_test.go +++ b/pkg/control/ut_ctrl_submgr_test.go @@ -59,8 +59,9 @@ func createSubmgrControl(srcId teststub.RmrSrcId, rtgSvc teststub.RmrRtgSvc) *te mainCtrl.c.LoggerLevel = int(xapp.Logger.GetLevel()) xapp.Logger.Debug("Test: LoggerLevel %v", mainCtrl.c.LoggerLevel) xapp.Logger.Debug("Replacing real db with test db") - mainCtrl.c.e2SubsDb = CreateMock() // This overrides real E2 Subscription database for testing - mainCtrl.c.restSubsDb = CreateRestSubsDbMock() // This overrides real REST Subscription database for testing + mainCtrl.c.e2SubsDb = CreateMock() // This overrides real E2 Subscription database for testing + mainCtrl.c.restSubsDb = CreateRestSubsDbMock() // This overrides real REST Subscription database for testing + mainCtrl.c.e2IfStateDb = CreateXappRnibIfMock() // This overrides real RNIB database for testing xapp.SetReadyCB(mainCtrl.ReadyCB, nil) go xapp.RunWithParams(mainCtrl.c, false) mainCtrl.WaitCB() @@ -337,7 +338,7 @@ func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) { } } - // Check that not any unexpected counter are added + // Check that not any unexpected counter are added (this is not working correctly!) for _, currentCounter := range currentCountersMap { if _, ok := toBeAddedCountersMap[currentCounter.Name]; ok == false { if beforeCounter, ok := countersBeforeMap[currentCounter.Name]; ok == true { @@ -455,3 +456,13 @@ func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path mc.TestLog(t, "%s", respBody) return } + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +func (mc *testingSubmgrControl) SetE2State(t *testing.T, ranNameState string) { + + if err := mc.c.e2IfStateDb.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", ranNameState, "key1", "data1"); err != nil { + t.Errorf("XappRnibStoreAndPublish failed: %v", err) + } +} diff --git a/pkg/control/ut_messaging_test.go b/pkg/control/ut_messaging_test.go index e10cdff..fd411bf 100644 --- a/pkg/control/ut_messaging_test.go +++ b/pkg/control/ut_messaging_test.go @@ -20,28 +20,299 @@ package control import ( + //"os" "strings" "testing" "time" "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap" "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap_wrapper" + "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities" "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststube2ap" "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp" "github.com/stretchr/testify/assert" ) func TestSuiteSetup(t *testing.T) { - // The effect of this call shall endure thgough the UT suite! - // If this causes any issues, the previout interface can be restored + // The effect of this call shall endure though the UT suite! + // If this causes any issues, the previous interface can be restored // like this:git log // SetPackerIf(e2ap_wrapper.NewAsn1E2APPacker()) SetPackerIf(e2ap_wrapper.NewUtAsn1E2APPacker()) - mainCtrl.c.restDuplicateCtrl.Init() } +func TestRanStatusChangeViaSDLNotification(t *testing.T) { + + // Current UT test cases use these ran names + xappRnibMock.CreateGnb("RAN_NAME_1", entities.ConnectionStatus_DISCONNECTED) + xappRnibMock.CreateGnb("RAN_NAME_11", entities.ConnectionStatus_DISCONNECTED) + xappRnibMock.CreateGnb("RAN_NAME_2", entities.ConnectionStatus_DISCONNECTED) + + mainCtrl.c.e2IfState.ReadE2ConfigurationFromRnib() + mainCtrl.c.e2IfState.SubscribeChannels() + + mainCtrl.SetE2State(t, "RAN_NAME_1_CONNECTED") + mainCtrl.SetE2State(t, "RAN_NAME_2_CONNECTED") + mainCtrl.SetE2State(t, "RAN_NAME_11_CONNECTED") +} + +//----------------------------------------------------------------------------- +// TestRESTSubReqAfterE2ConnBreak +// +// stub stub +// +-------+ +---------+ +---------+ +// | xapp | | submgr | | e2term | +// +-------+ +---------+ +---------+ +// | | | +// | [E2 Conn. DOWN] | +// | | | +// | RESTSubReq | | +// |---------------->| | +// | RESTSubFail | | +// |<----------------| | +// | | | +// +//----------------------------------------------------------------------------- + +func TestRESTSubReqAfterE2ConnBreak(t *testing.T) { + CaseBegin("TestRESTSubReqAfterE2ConnBreak") + + mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{ + Counter{cRestSubReqFromXapp, 1}, + Counter{cRestReqRejDueE2Down, 1}, + }) + + // E2 disconnect after E2term has received response + mainCtrl.SetE2State(t, "RAN_NAME_1_DISCONNECTED") + // Req + const subReqCount int = 1 + params := xappConn1.GetRESTSubsReqReportParams(subReqCount) + xappConn1.SendRESTSubsReq(t, params) + + // Restore E2 connection for following test cases + mainCtrl.SetE2State(t, "RAN_NAME_1_CONNECTED") + + mainCtrl.VerifyCounterValues(t) +} + +//----------------------------------------------------------------------------- +// TestRESTSubReqE2ConnBreak +// +// stub stub +// +-------+ +---------+ +---------+ +// | xapp | | submgr | | e2term | +// +-------+ +---------+ +---------+ +// | | | +// | RESTSubReq | | +// |---------------->| | +// | RESTSubResp | | +// |<----------------| | +// | | SubReq | +// | |------------->| +// | | SubResp | +// | |<-------------| +// | | | +// | [E2 Conn. DOWN] | +// | [Int. SUBS DELETE] | +// | | | +// | RESTNotif(unsuccessful) | +// |<----------------| | +// | | | +// | | | +// +//----------------------------------------------------------------------------- +func TestRESTSubReqE2ConnBreak(t *testing.T) { + CaseBegin("TestRESTSubReqE2ConnBreak") + + mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{ + Counter{cRestSubReqFromXapp, 1}, + Counter{cRestSubRespToXapp, 1}, + Counter{cSubReqToE2, 1}, + Counter{cSubRespFromE2, 1}, + Counter{cRestSubFailNotifToXapp, 1}, + }) + + // Req + const subReqCount int = 1 + params := xappConn1.GetRESTSubsReqReportParams(subReqCount) + restSubId := xappConn1.SendRESTSubsReq(t, params) + + crereq, cremsg := e2termConn1.RecvSubsReq(t) + xappConn1.ExpectRESTNotification(t, restSubId) + + // E2 disconnect after E2term has received response + mainCtrl.SetE2State(t, "RAN_NAME_1_DISCONNECTED") + + e2termConn1.SendSubsResp(t, crereq, cremsg) + e2SubsId := xappConn1.WaitRESTNotification(t, restSubId) + + <-time.After(time.Second * 1) + assert.Equal(t, 0, len(mainCtrl.c.registry.register)) + assert.Equal(t, 0, len(mainCtrl.c.registry.restSubscriptions)) + + subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl() + if err != nil { + xapp.Logger.Error("%v", err) + } else { + assert.Equal(t, 65534, len(subIds)) // range 1-65535 , FFFF = 65535 + assert.Equal(t, 0, len(register)) + } + + restSubscriptions, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl() + if err != nil { + xapp.Logger.Error("%v", err) + } else { + assert.Equal(t, 0, len(restSubscriptions)) + } + + // Restore E2 connection for following test cases + mainCtrl.SetE2State(t, "RAN_NAME_1_CONNECTED") + + // Wait that subs is cleaned + waitSubsCleanup(t, e2SubsId, 10) + mainCtrl.VerifyCounterValues(t) +} + +//----------------------------------------------------------------------------- +// TestRESTSubscriptionDeleteAfterE2ConnectionBreak +// +// stub stub +// +-------+ +---------+ +---------+ +// | xapp | | submgr | | e2term | +// +-------+ +---------+ +---------+ +// | | | +// | [SUBS CREATE] | +// | | | +// | [E2 Conn. DOWN] | +// | | | +// | RESTSubDelReq | | +// |---------------->| | +// | | | +// | RESTSubDelResp | | +// |<----------------| | +// | | | +// | [No valid subscription found] | +// | | | +// +//----------------------------------------------------------------------------- +func TestRESTSubscriptionDeleteAfterE2ConnectionBreak(t *testing.T) { + xapp.Logger.Debug("TEST: TestRESTSubscriptionDeleteAfterE2ConnectionBreak") + + mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{ + Counter{cRestSubReqFromXapp, 1}, + Counter{cRestSubRespToXapp, 1}, + Counter{cSubReqToE2, 1}, + Counter{cSubRespFromE2, 1}, + Counter{cRestSubNotifToXapp, 1}, + Counter{cRestSubDelReqFromXapp, 1}, + Counter{cRestSubDelRespToXapp, 1}, + }) + + // Req + var params *teststube2ap.RESTSubsReqParams = nil + restSubId, e2SubsId := createSubscription(t, xappConn1, e2termConn1, params) + + // E2 disconnect after E2term has received response + mainCtrl.SetE2State(t, "RAN_NAME_1_DISCONNECTED") + + // Del + xappConn1.SendRESTSubsDelReq(t, &restSubId) + + <-time.After(time.Second * 1) + assert.Equal(t, 0, len(mainCtrl.c.registry.register)) + assert.Equal(t, 0, len(mainCtrl.c.registry.restSubscriptions)) + + subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl() + if err != nil { + xapp.Logger.Error("%v", err) + } else { + assert.Equal(t, 65534, len(subIds)) // range 1-65535 , FFFF = 65535 + assert.Equal(t, 0, len(register)) + } + + restSubscriptions, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl() + if err != nil { + xapp.Logger.Error("%v", err) + } else { + assert.Equal(t, 0, len(restSubscriptions)) + } + + // Restore E2 connection for following test cases + mainCtrl.SetE2State(t, "RAN_NAME_1_CONNECTED") + + // Wait that subs is cleaned + mainCtrl.wait_subs_clean(t, e2SubsId, 10) + + xappConn1.TestMsgChanEmpty(t) + e2termConn1.TestMsgChanEmpty(t) + mainCtrl.wait_registry_empty(t, 10) + mainCtrl.VerifyCounterValues(t) +} + +//----------------------------------------------------------------------------- +// TestRESTOtherE2ConnectionChanges +// + +// stub stub +// +-------+ +---------+ +---------+ +// | xapp | | submgr | | e2term | +// +-------+ +---------+ +---------+ +// | | | +// | [SUBS CREATE] | +// | | | +// | [E2 CONNECTED_SETUP_FAILED] | +// | [E2 CONNECTING] | +// | [E2 SHUTTING_DOWN] | +// | [E2 SHUT_DOWN] | +// | | | +// | [SUBS DELETE] | +// | | | +// +//----------------------------------------------------------------------------- +func TestRESTOtherE2ConnectionChanges(t *testing.T) { + xapp.Logger.Debug("TEST: TestRESTOtherE2ConnectionChanges") + + mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{ + Counter{cRestSubReqFromXapp, 1}, + Counter{cRestSubRespToXapp, 1}, + Counter{cSubReqToE2, 1}, + Counter{cSubRespFromE2, 1}, + Counter{cRestSubNotifToXapp, 1}, + Counter{cRestSubDelReqFromXapp, 1}, + Counter{cSubDelReqToE2, 1}, + Counter{cSubDelRespFromE2, 1}, + Counter{cRestSubDelRespToXapp, 1}, + }) + + // Req + params := xappConn1.GetRESTSubsReqReportParams(subReqCount) + restSubId := xappConn1.SendRESTSubsReq(t, params) + + crereq, cremsg := e2termConn1.RecvSubsReq(t) + xappConn1.ExpectRESTNotification(t, restSubId) + e2termConn1.SendSubsResp(t, crereq, cremsg) + e2SubsId := xappConn1.WaitRESTNotification(t, restSubId) + + // Submgr should not react any other connection state changes than CONNECTED and DISCONNECTED + mainCtrl.SetE2State(t, "RAN_NAME_1_CONNECTED_SETUP_FAILED") + mainCtrl.SetE2State(t, "RAN_NAME_1_CONNECTING") + mainCtrl.SetE2State(t, "RAN_NAME_1_SHUTTING_DOWN") + mainCtrl.SetE2State(t, "RAN_NAME_1_SHUT_DOWN") + + // Del + xappConn1.SendRESTSubsDelReq(t, &restSubId) + delreq, delmsg := e2termConn1.RecvSubsDelReq(t) + e2termConn1.SendSubsDelResp(t, delreq, delmsg) + + // Restore E2 connection for following test cases + mainCtrl.SetE2State(t, "RAN_NAME_1_CONNECTED") + + // Wait that subs is cleaned + waitSubsCleanup(t, e2SubsId, 10) + mainCtrl.VerifyCounterValues(t) +} //----------------------------------------------------------------------------- // TestRESTSubReqAndDeleteOkWithE2apUtWrapper diff --git a/pkg/teststube2ap/stubE2.go b/pkg/teststube2ap/stubE2.go index 719f214..d6421e5 100644 --- a/pkg/teststube2ap/stubE2.go +++ b/pkg/teststube2ap/stubE2.go @@ -705,25 +705,25 @@ func (tc *E2Stub) expectNotification(t *testing.T, restSubsId string, expectErro tc.restSubsIdList = []string{restSubsId} xapp.Subscription.SetResponseCB(tc.ListedRestNotifHandler) if tc.requestCount == 0 { - tc.TestError(t, "### NO REST notifications SET received for endpoint=%s, request zount ZERO! (%v)", tc.clientEndpoint, tc) + tc.TestError(t, "### NO REST notifications SET received for endpoint=%s, request zount ZERO! (%v)", tc.clientEndpoint, *tc) } go func() { select { case e2Ids := <-tc.CallBackListedNotifications: if tc.requestCount == 0 { - tc.TestError(t, "### REST notification count unexpectedly ZERO for %s (%v)", restSubsId, tc) + tc.TestError(t, "### REST notification count unexpectedly ZERO for %s (%v)", restSubsId, *tc) } else if e2Ids.RestSubsId != restSubsId { - tc.TestError(t, "### Unexpected REST notifications received, expected %s bunt got %s instead| (%v)", e2Ids.RestSubsId, restSubsId, tc) + tc.TestError(t, "### Unexpected REST notifications received, expected %s bunt got %s instead| (%v)", e2Ids.RestSubsId, restSubsId, *tc) } else if e2Ids.ErrorCause == "" && expectError == "allFail" { - tc.TestError(t, "### Unexpected ok cause received from REST notifications |%s:%s| (%v)", e2Ids.RestSubsId, restSubsId, tc) + tc.TestError(t, "### Unexpected ok cause received from REST notifications |%s:%s| (%v)", e2Ids.RestSubsId, restSubsId, *tc) } else if e2Ids.ErrorCause != "" && expectError == "allOk" { - tc.TestError(t, "### Unexpected ErrorCause: (%s), ErrorSource: (%s), TimeoutType: (%s) received from REST notifications |%s:%s| (%v)", e2Ids.ErrorCause, e2Ids.ErrorSource, e2Ids.TimeoutType, e2Ids.RestSubsId, restSubsId, tc) + tc.TestError(t, "### Unexpected ErrorCause: (%s), ErrorSource: (%s), TimeoutType: (%s) received from REST notifications |%s:%s| (%v)", e2Ids.ErrorCause, e2Ids.ErrorSource, e2Ids.TimeoutType, e2Ids.RestSubsId, restSubsId, *tc) } else { tc.requestCount-- if tc.requestCount == 0 { - tc.Debug("### All expected REST notifications received for %s (%v)", e2Ids.RestSubsId, tc) + tc.Debug("### All expected REST notifications received for %s (%v)", e2Ids.RestSubsId, *tc) } else { - tc.Debug("### Expected REST notifications received for %s, (%v)", e2Ids.RestSubsId, tc) + tc.Debug("### Expected REST notifications received for %s, (%v)", e2Ids.RestSubsId, *tc) } if e2Ids.ErrorCause != "" && expectError == "allFail" { tc.Debug("### REST Notification: RestSubsId: %s, ErrorCause: %s, ErrorSource: (%s), TimeoutType: (%s)", e2Ids.RestSubsId, e2Ids.ErrorCause, e2Ids.ErrorSource, e2Ids.TimeoutType) @@ -748,10 +748,10 @@ func (tc *E2Stub) WaitRESTNotification(t *testing.T, restSubsId string) uint32 { select { case e2SubsId := <-tc.ListedRESTNotifications: if e2SubsId.RestSubsId == restSubsId { - tc.Debug("### Expected REST notifications received %s, e2SubsId %v for endpoint=%s, (%v)", e2SubsId.RestSubsId, e2SubsId.E2SubsId, tc.clientEndpoint, tc) + tc.Debug("### Expected REST notifications received %s, e2SubsId %v for endpoint=%v, (%v)", e2SubsId.RestSubsId, e2SubsId.E2SubsId, tc.clientEndpoint, *tc) return e2SubsId.E2SubsId } else { - tc.TestError(t, "### Unexpected REST notification %s received, expected %s for endpoint=%s, (%v)", e2SubsId.RestSubsId, restSubsId, tc.clientEndpoint, tc) + tc.TestError(t, "### Unexpected REST notification %s received, expected %v for endpoint=%v, (%v)", e2SubsId.RestSubsId, restSubsId, tc.clientEndpoint, *tc) xapp.Logger.Debug("CALL STACK:\n %s", stack) return 0 } @@ -796,7 +796,7 @@ func (tc *E2Stub) WaitAnyRESTNotification(t *testing.T) uint32 { func (tc *E2Stub) ListedRestNotifHandler(resp *clientmodel.SubscriptionResponse) { if len(tc.restSubsIdList) == 0 { - tc.Error("Unexpected listed REST notifications received for endpoint=%s, expected restSubsId list size was ZERO!", tc.clientEndpoint) + tc.Error("Unexpected listed REST notifications received for endpoint=%v, expected restSubsId list size was ZERO!", tc.clientEndpoint) } else { for i, subsId := range tc.restSubsIdList { if *resp.SubscriptionID == subsId { @@ -813,7 +813,7 @@ func (tc *E2Stub) ListedRestNotifHandler(resp *clientmodel.SubscriptionResponse) // } if len(tc.restSubsIdList) == 0 { - tc.Debug("All listed REST notifications received for endpoint=%s", tc.clientEndpoint) + tc.Debug("All listed REST notifications received for endpoint=%v", tc.clientEndpoint) } return diff --git a/releases/container-release-ric-plt-submgr.yaml b/releases/container-release-ric-plt-submgr.yaml index 3afa1fc..5c2143e 100644 --- a/releases/container-release-ric-plt-submgr.yaml +++ b/releases/container-release-ric-plt-submgr.yaml @@ -7,4 +7,4 @@ project: ric-plt/submgr ref: 6c63019f4daa458507decc19f2d742681e2053b4 containers: - name: ric-plt-submgr - version: 0.7.1 + version: 0.7.2 -- 2.16.6