"e2tRecvMsgTimeout_ms": 2000
"e2tMaxSubReqTryCount": 2
"e2tMaxSubDelReqTryCount": 2
+ "checkE2State:" "true"
"readSubsFromDb": "true"
"dbTryCount": 200
"dbRetryForever": "true"
# 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"
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:
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
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
-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=
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=
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=
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=
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=
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=
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=
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=
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=
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=
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=
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=
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=
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=
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=
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=
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
registry *Registry
tracker *Tracker
restDuplicateCtrl *DuplicateCtrl
+ e2IfState *E2IfState
+ e2IfStateDb XappRnibInterface
e2SubsDb Sdlnterface
restSubsDb Sdlnterface
CntRecvMsg uint64
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
//-------------------------------------------------------------------
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)
}
//-------------------------------------------------------------------
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)
//
// 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, "")
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)
+ }
}
//-------------------------------------------------------------------
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)
+ }
}
//-------------------------------------------------------------------
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
}
}
}()
c.UpdateCounter(cRestSubDelRespToXapp)
-
return common.UnsubscribeNoContentCode
}
//
// 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))
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))
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) {
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))
//
// 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))
--- /dev/null
+/*
+==================================================================================
+ 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
+}
--- /dev/null
+/*
+==================================================================================
+ 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
+}
cSubRespToXapp string = "SubRespToXapp"
cRestSubRespToXapp string = "RestSubRespToXapp"
cRestSubFailToXapp string = "RestSubFailToXapp"
+ cRestReqRejDueE2Down string = "RestReqRejDueE2Down"
cRestSubNotifToXapp string = "RestSubNotifToXapp"
cRestSubFailNotifToXapp string = "RestSubFailNotifToXapp"
cSubReqToE2 string = "SubReqToE2"
cSubDelRespToXapp string = "SubDelRespToXapp"
cRestSubDelReqFromXapp string = "RestSubDelReqFromXapp"
cRestSubDelRespToXapp string = "RestSubDelRespToXapp"
+ cRestSubDelFailToXapp string = "RestSubDelFailToXapp"
cSubDelReqToE2 string = "SubDelReqToE2"
cSubDelReReqToE2 string = "SubDelReReqToE2"
cSubDelRespFromE2 string = "SubDelRespFromE2"
cSDLWriteFailure string = "SDLWriteFailure"
cSDLReadFailure string = "SDLReadFailure"
cSDLRemoveFailure string = "SDLRemoveFailure"
+ cE2StateChangedToUp string = "E2StateChangedToUp"
+ cE2StateChangedToDown string = "E2StateChangedToDown"
)
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"},
{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"},
{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()
}
Meid: trans.Meid,
RMRRouteCreated: rmrRoutecreated,
SubReqMsg: subReqMsg,
+ OngoingReqCount: 0,
+ OngoingDelCount: 0,
valid: true,
PolicyUpdate: false,
RetryFromXapp: false,
delStatus := subs.EpList.DelEndpoint(trans.GetEndpoint())
epamount := subs.EpList.Size()
subId := subs.ReqId.InstanceId
-
if delStatus == false {
return nil
}
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)
+ }
+ }
+}
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
"time"
"gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
+ "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
)
//-----------------------------------------------------------------------------
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)
+}
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()
}
}
- // 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 {
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)
+ }
+}
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
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)
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
}
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 {
// }
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
ref: 6c63019f4daa458507decc19f2d742681e2053b4
containers:
- name: ric-plt-submgr
- version: 0.7.1
+ version: 0.7.2