From d916e2aef4c415d9865643fafa8c181a9fdfd65b Mon Sep 17 00:00:00 2001 From: idanshal Date: Wed, 22 Apr 2020 15:56:43 +0300 Subject: [PATCH 1/1] [RIC-298] Added handling for orphan cells and updated Swagger Change-Id: Id4d6cdc6aeafba948c7ac9aab93bd5cd7043d108 Signed-off-by: idanshal --- E2Manager/controllers/nodeb_controller_test.go | 78 +++++++++++++- E2Manager/go.mod | 5 +- E2Manager/go.sum | 18 ++-- .../httpmsghandlers/update_gnb_request_handler.go | 47 ++++++--- E2Manager/mocks/rnibWriterMock.go | 6 ++ E2Manager/rNibWriter/rNibWriter.go | 35 ++++++ E2Manager/rNibWriter/rNibWriter_test.go | 23 +++- E2Manager/services/rnib_data_service.go | 11 +- ...{E2Manager_API.yaml => E2M_API_2020-04-22.yaml} | 117 ++++++++------------- 9 files changed, 239 insertions(+), 101 deletions(-) rename Swagger/{E2Manager_API.yaml => E2M_API_2020-04-22.yaml} (97%) mode change 100644 => 100755 diff --git a/E2Manager/controllers/nodeb_controller_test.go b/E2Manager/controllers/nodeb_controller_test.go index 4bdfd2c..c61249e 100644 --- a/E2Manager/controllers/nodeb_controller_test.go +++ b/E2Manager/controllers/nodeb_controller_test.go @@ -90,14 +90,41 @@ type updateGnbCellsParams struct { err error } +type removeServedNrCellsParams struct { + servedNrCells []*entities.ServedNRCell + err error +} + type controllerUpdateGnbTestContext struct { getNodebInfoResult *getNodebInfoResult + removeServedNrCellsParams *removeServedNrCellsParams updateGnbCellsParams *updateGnbCellsParams requestBody map[string]interface{} expectedStatusCode int expectedJsonResponse string } +func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell { + + servedNrCells := []*entities.ServedNRCell{} + + for _, v := range cellIds { + servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{ + CellId: v, + ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{ + Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{ + + }, + }, + NrMode: entities.Nr_FDD, + NrPci: 5, + ServedPlmns: []string{"whatever"}, + }}) + } + + return servedNrCells +} + func buildNrNeighbourInformation(propToOmit string) map[string]interface{} { ret := map[string]interface{}{ "nrCgi": "whatever", @@ -278,11 +305,16 @@ func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, r readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError) } + if context.removeServedNrCellsParams != nil { + writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err) + } + if context.updateGnbCellsParams != nil { updatedNodebInfo := *context.getNodebInfoResult.nodebInfo gnb := entities.Gnb{} _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb) - updatedNodebInfo.GetGnb().ServedNrCells = gnb.ServedNrCells + updatedGnb := *updatedNodebInfo.GetGnb() + updatedGnb.ServedNrCells = gnb.ServedNrCells writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err) } } @@ -301,6 +333,10 @@ func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestCon if context.updateGnbCellsParams != nil { writerMock.AssertNotCalled(t, "UpdateGnb") } + + if context.removeServedNrCellsParams != nil { + writerMock.AssertNotCalled(t, "RemoveServedNrCells") + } } func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request { @@ -508,8 +544,46 @@ func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) controllerUpdateGnbTestExecuter(t, &context) } +func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) { + oldServedNrCells := generateServedNrCells("whatever1","whatever2") + context := controllerUpdateGnbTestContext{ + removeServedNrCellsParams: &removeServedNrCellsParams{ + err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")), + servedNrCells: oldServedNrCells, + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}}, + }, + rnibError: nil, + }, + requestBody: map[string]interface{}{ + "servedNrCells": []interface{}{ + map[string]interface{}{ + "servedNrCellInformation": buildServedNrCellInformation(""), + "nrNeighbourInfos": []interface{}{ + buildNrNeighbourInformation(""), + }, + }, + }, + }, + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerUpdateGnbTestExecuter(t, &context) +} + func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) { + oldServedNrCells := generateServedNrCells("whatever1","whatever2") context := controllerUpdateGnbTestContext{ + removeServedNrCellsParams: &removeServedNrCellsParams{ + err: nil, + servedNrCells: oldServedNrCells, + }, updateGnbCellsParams: &updateGnbCellsParams{ err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")), }, @@ -518,7 +592,7 @@ func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) { RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, - Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}}, + Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}}, }, rnibError: nil, }, diff --git a/E2Manager/go.mod b/E2Manager/go.mod index 3fd0b4c..1195401 100644 --- a/E2Manager/go.mod +++ b/E2Manager/go.mod @@ -9,7 +9,6 @@ require ( github.com/go-ozzo/ozzo-validation v3.5.0+incompatible github.com/golang/protobuf v1.3.4 github.com/gorilla/mux v1.7.0 - github.com/imdario/mergo v0.3.9 // indirect github.com/magiconair/properties v1.8.1 github.com/pelletier/go-toml v1.5.0 // indirect github.com/pkg/errors v0.8.1 @@ -20,10 +19,10 @@ require ( go.uber.org/multierr v1.2.0 // indirect go.uber.org/zap v1.11.0 golang.org/x/net v0.0.0-20191021144547-ec77196f6094 // indirect + golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd // indirect + google.golang.org/appengine v1.6.1 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.8 - k8s.io/api v0.17.0 - k8s.io/apimachinery v0.17.0 k8s.io/client-go v0.17.0 ) diff --git a/E2Manager/go.sum b/E2Manager/go.sum index 4dd7bc0..193bed0 100644 --- a/E2Manager/go.sum +++ b/E2Manager/go.sum @@ -1,16 +1,10 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.34 h1:d53dCN59dZftx847pzyo/zIKk0XJjOqMAx4VwxJHO10= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.34/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.35 h1:TGXHb4DNY8on+ej4S9VUnk2HibIC/5chDy64OE+bQBQ= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.35/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.34 h1:7jxKtb+VPgwHKxQuWne1mG09rsi330erwb1u4OsWEaA= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.34/go.mod h1:G+4sUBMbLfQ+RrGS65U15tKmbnP+/1b5oLTPmMfyfT4= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.35 h1:tkM3yE8UzmuH4nf9TqAmiNBSuIZ2CtcMRH2eBIYIzpQ= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.35/go.mod h1:G+4sUBMbLfQ+RrGS65U15tKmbnP+/1b5oLTPmMfyfT4= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.34 h1:niBDUlmhq+8dhXt7z8KW+ZBq/0XlnM4FzvrLYlub1co= -gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.34/go.mod h1:tcc2L3Fb7hTvxK+QVTCbWjBX//078qOgPMwA9ZyCxY4= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.35 h1:LcxnUUDwsCzYEISKmkjkyYfg/lnLt8ofkPiGK69vNIA= gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.35/go.mod h1:2bSaXTpECbZieB8bMnubTqMwF3n+mMBxlTaAXvcduNg= gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.2 h1:UK7awyRKIkVdokWvvkYvazlg3EWIfMnIqCcJxTnLlDA= @@ -100,6 +94,7 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +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/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= @@ -119,8 +114,6 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= -github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= @@ -243,6 +236,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586 h1:7KByu05hhLed2MO29w7p1XfZvZ13m8mub3shuVftRs0= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -262,6 +256,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/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 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191021144547-ec77196f6094 h1:5O4U9trLjNpuhpynaDsqwCk+Tw6seqJz1EbqbnzHrc8= golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -274,6 +269,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ 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-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -285,8 +281,11 @@ golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd h1:3x5uuvBgE6oaXJjCOvpCC1IpgJogqQ+PqGGU3ZxAgII= +golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -304,11 +303,14 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= diff --git a/E2Manager/handlers/httpmsghandlers/update_gnb_request_handler.go b/E2Manager/handlers/httpmsghandlers/update_gnb_request_handler.go index e22925f..5d9d2b2 100644 --- a/E2Manager/handlers/httpmsghandlers/update_gnb_request_handler.go +++ b/E2Manager/handlers/httpmsghandlers/update_gnb_request_handler.go @@ -68,27 +68,48 @@ func (h *UpdateGnbRequestHandler) Handle(request models.Request) (models.IRespon return nil, e2managererrors.NewResourceNotFoundError() } - ranName:= nodebInfo.RanName + err = h.updateGnbCells(nodebInfo, updateGnbRequest) + + if err != nil { + return nil, err + } + + return models.NewUpdateGnbResponse(nodebInfo), nil +} + +func (h *UpdateGnbRequestHandler) updateGnbCells(nodebInfo *entities.NodebInfo, updateGnbRequest models.UpdateGnbRequest) error { + + ranName := nodebInfo.RanName gnb := nodebInfo.GetGnb() if gnb == nil { - h.logger.Errorf("#UpdateGnbRequestHandler.Handle - RAN name: %s - nodeb missing gnb configuration", ranName) - return nil, e2managererrors.NewInternalError() + h.logger.Errorf("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - nodeb missing gnb configuration", ranName) + return e2managererrors.NewInternalError() + } + + if len(gnb.ServedNrCells) != 0 { + err := h.rNibDataService.RemoveServedNrCells(ranName, gnb.ServedNrCells) + + if err != nil { + h.logger.Errorf("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - Failed removing served nr cells", ranName) + return e2managererrors.NewRnibDbError() + } } gnb.ServedNrCells = updateGnbRequest.ServedNrCells - err = h.rNibDataService.UpdateGnbCells(nodebInfo, updateGnbRequest.ServedNrCells) + err := h.rNibDataService.UpdateGnbCells(nodebInfo, updateGnbRequest.ServedNrCells) if err != nil { - h.logger.Errorf("#UpdateGnbRequestHandler.Handle - RAN name: %s - Failed updating GNB cells. Error: %s", ranName, err) - return nil, e2managererrors.NewRnibDbError() + h.logger.Errorf("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - Failed updating GNB cells. Error: %s", ranName, err) + return e2managererrors.NewRnibDbError() } - return models.NewUpdateGnbResponse(nodebInfo), nil + h.logger.Infof("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - Successfully updated GNB cells", ranName) + return nil } -func (h *UpdateGnbRequestHandler) validateRequestBody(updateGnbRequest models.UpdateGnbRequest) (error) { +func (h *UpdateGnbRequestHandler) validateRequestBody(updateGnbRequest models.UpdateGnbRequest) error { if len(updateGnbRequest.ServedNrCells) == 0 { h.logger.Errorf(VALIDATION_FAILURE_MESSAGE+" and cannot be empty", "servedCells") @@ -129,23 +150,23 @@ func (h *UpdateGnbRequestHandler) validateRequestBody(updateGnbRequest models.Up func isServedNrCellInformationValid(servedNrCellInformation *entities.ServedNRCellInformation) error { if servedNrCellInformation.CellId == "" { - return errors.New("cellId"); + return errors.New("cellId") } if servedNrCellInformation.ChoiceNrMode == nil { - return errors.New("choiceNrMode"); + return errors.New("choiceNrMode") } if servedNrCellInformation.NrMode == entities.Nr_UNKNOWN { - return errors.New("nrMode"); + return errors.New("nrMode") } if servedNrCellInformation.NrPci == 0 { - return errors.New("nrPci"); + return errors.New("nrPci") } if len(servedNrCellInformation.ServedPlmns) == 0 { - return errors.New("servedPlmns"); + return errors.New("servedPlmns") } return isServedNrCellInfoChoiceNrModeValid(servedNrCellInformation.ChoiceNrMode) diff --git a/E2Manager/mocks/rnibWriterMock.go b/E2Manager/mocks/rnibWriterMock.go index 8fb5403..5c602bb 100644 --- a/E2Manager/mocks/rnibWriterMock.go +++ b/E2Manager/mocks/rnibWriterMock.go @@ -86,3 +86,9 @@ func (rnibWriterMock *RnibWriterMock) UpdateGnbCells(nodebInfo *entities.NodebIn args := rnibWriterMock.Called(nodebInfo, servedNrCells) return args.Error(0) } + +func (rnibWriterMock *RnibWriterMock) RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error { + args := rnibWriterMock.Called(inventoryName, servedNrCells) + return args.Error(0) +} + diff --git a/E2Manager/rNibWriter/rNibWriter.go b/E2Manager/rNibWriter/rNibWriter.go index f9f75bd..a44f388 100644 --- a/E2Manager/rNibWriter/rNibWriter.go +++ b/E2Manager/rNibWriter/rNibWriter.go @@ -44,6 +44,7 @@ type RNibWriter interface { SaveE2TAddresses(addresses []string) error RemoveE2TInstance(e2tAddress string) error UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error + RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error } /* @@ -54,6 +55,18 @@ func GetRNibWriter(sdl common.ISdlInstance) RNibWriter { return &rNibWriterInstance{sdl: sdl} } + +func (w *rNibWriterInstance) RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error { + cellKeysToRemove := buildCellKeysToRemove(inventoryName, servedNrCells) + err := w.sdl.Remove(cellKeysToRemove) + + if err != nil { + return common.NewInternalError(err) + } + + return nil +} + /* SaveNodeb saves nodeB entity data in the redis DB according to the specified data model */ @@ -148,6 +161,28 @@ func (w *rNibWriterInstance) UpdateGnbCells(nodebInfo *entities.NodebInfo, serve return nil } +func buildCellKeysToRemove(inventoryName string, servedNrCellsToRemove []*entities.ServedNRCell) []string { + + cellKeysToRemove := []string{} + + for _, cell := range servedNrCellsToRemove { + + key, _ := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId()) + + if len(key) != 0 { + cellKeysToRemove = append(cellKeysToRemove, key) + } + + key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci()) + + if len(key) != 0 { + cellKeysToRemove = append(cellKeysToRemove, key) + } + } + + return cellKeysToRemove +} + func buildUpdateNodebInfoPairs(nodebInfo *entities.NodebInfo) ([]interface{}, error) { nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName()) diff --git a/E2Manager/rNibWriter/rNibWriter_test.go b/E2Manager/rNibWriter/rNibWriter_test.go index 9306b97..257bb85 100644 --- a/E2Manager/rNibWriter/rNibWriter_test.go +++ b/E2Manager/rNibWriter/rNibWriter_test.go @@ -33,6 +33,9 @@ import ( ) var namespace = "namespace" +const ( + RanName = "test" +) func initSdlInstanceMock(namespace string) (w RNibWriter, sdlInstanceMock *mocks.MockSdlInstance) { sdlInstanceMock = new(mocks.MockSdlInstance) @@ -65,7 +68,7 @@ func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell { servedNrCells := []*entities.ServedNRCell{} - for _, v := range cellIds { + for i, v := range cellIds { servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{ CellId: v, ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{ @@ -74,7 +77,7 @@ func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell { }, }, NrMode: entities.Nr_FDD, - NrPci: 5, + NrPci: uint32(i + 1), ServedPlmns: []string{"whatever"}, }}) } @@ -82,6 +85,22 @@ func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell { return servedNrCells } +func TestRemoveServedNrCellsSuccess(t *testing.T) { + w, sdlInstanceMock := initSdlInstanceMock(namespace) + servedNrCellsToRemove := generateServedNrCells("whatever1", "whatever2") + sdlInstanceMock.On("Remove", buildCellKeysToRemove(RanName, servedNrCellsToRemove)).Return(nil) + err := w.RemoveServedNrCells(RanName, servedNrCellsToRemove) + assert.Nil(t, err) +} + +func TestRemoveServedNrCellsFailure(t *testing.T) { + w, sdlInstanceMock := initSdlInstanceMock(namespace) + servedNrCellsToRemove := generateServedNrCells("whatever1", "whatever2") + sdlInstanceMock.On("Remove", buildCellKeysToRemove(RanName, servedNrCellsToRemove)).Return(errors.New("expected error")) + err := w.RemoveServedNrCells(RanName, servedNrCellsToRemove) + assert.IsType(t, &common.InternalError{}, err) +} + func TestUpdateGnbCellsInvalidNodebInfoFailure(t *testing.T) { w, sdlInstanceMock := initSdlInstanceMock(namespace) servedNrCells := generateServedNrCells("test1", "test2") diff --git a/E2Manager/services/rnib_data_service.go b/E2Manager/services/rnib_data_service.go index af329af..7235028 100644 --- a/E2Manager/services/rnib_data_service.go +++ b/E2Manager/services/rnib_data_service.go @@ -17,7 +17,6 @@ // This source code is part of the near-RT RIC (RAN Intelligent Controller) // platform project (RICP). - package services import ( @@ -49,6 +48,7 @@ type RNibDataService interface { GetE2TAddressesNoLogs() ([]string, error) RemoveE2TInstance(e2tAddress string) error UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error + RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error } type rNibDataService struct { @@ -69,6 +69,15 @@ func NewRnibDataService(logger *logger.Logger, config *configuration.Configurati } } +func (w *rNibDataService) RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error { + err := w.retry("RemoveServedNrCells", func() (err error) { + err = w.rnibWriter.RemoveServedNrCells(inventoryName, servedNrCells) + return + }) + + return err +} + func (w *rNibDataService) UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error { w.logger.Infof("#RnibDataService.UpdateGnbCells - nodebInfo: %s, servedNrCells: %s", nodebInfo, servedNrCells) diff --git a/Swagger/E2Manager_API.yaml b/Swagger/E2M_API_2020-04-22.yaml old mode 100644 new mode 100755 similarity index 97% rename from Swagger/E2Manager_API.yaml rename to Swagger/E2M_API_2020-04-22.yaml index 2b765a0..bcc1e84 --- a/Swagger/E2Manager_API.yaml +++ b/Swagger/E2M_API_2020-04-22.yaml @@ -1,25 +1,3 @@ -# ========================LICENSE_START================================= -# O-RAN-SC -# -# Copyright (C) 2019 AT&T Intellectual Property and 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. -# ========================LICENSE_END=================================== - -# This source code is part of the near-RT RIC (RAN Intelligent Controller) -# platform project (RICP). - - openapi: 3.0.0 info: title: E2 Manager Service @@ -32,87 +10,83 @@ servers: default: 'localhost:3800' paths: '/nodeb/{ranName}': - put: - summary: Update GNB + get: tags: - nodeb - operationId: UpdateGnb + summary: Get RAN by name + operationId: getNb parameters: - name: ranName in: path required: true - description: Name of GNB RAN to update + description: Name of RAN to return schema: type: string - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/UpdateGnbRequest' - required: true responses: '200': description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/UpdateGnbResponse' + $ref: '#/components/schemas/GetNodebResponse' '400': - description: Invalid input + description: The specified RAN name is invalid content: - application/problem+json: + application/json: schema: $ref: '#/components/schemas/ErrorResponse' - '500': - description: Internal error + '404': + description: A RAN with the specified name was not found content: application/problem+json: schema: $ref: '#/components/schemas/ErrorResponse' - '503': - description: Routing Manager Unavailable + '500': + description: Internal Error content: application/problem+json: schema: $ref: '#/components/schemas/ErrorResponse' - get: + '/nodeb/{ranName}/update': + put: + summary: Update GNB tags: - nodeb - summary: Get RAN by name - operationId: getNb + operationId: UpdateGnb parameters: - name: ranName in: path required: true - description: Name of RAN to return + description: Name of GNB RAN to update schema: type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateGnbRequest' + required: true responses: '200': description: Successful operation content: application/json: schema: - $ref: '#/components/schemas/GetNodebResponse' + $ref: '#/components/schemas/UpdateGnbResponse' '400': - description: The specified RAN name is invalid - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '404': - description: A RAN with the specified name was not found + description: Invalid input content: application/problem+json: schema: $ref: '#/components/schemas/ErrorResponse' '500': - description: Internal Error + description: Internal error content: application/problem+json: schema: $ref: '#/components/schemas/ErrorResponse' - /nodeb/shutdown: + + '/nodeb/shutdown': put: tags: - nodeb @@ -132,7 +106,7 @@ paths: application/problem+json: schema: $ref: '#/components/schemas/ErrorResponse' - /nodeb/ids: + '/nodeb/ids': get: tags: - nodeb @@ -153,7 +127,7 @@ paths: application/problem+json: schema: $ref: '#/components/schemas/ErrorResponse' - /health: + '/health': get: tags: - Health Check @@ -161,7 +135,7 @@ paths: responses: '200': description: OK - /e2t/list: + '/e2t/list': get: tags: - e2t @@ -185,14 +159,21 @@ components: schemas: UpdateGnbRequest: type: object + required: + - servedNrCells properties: - gnb: - properties: servedNrCells: items: + required: + - servedNrCellInformation properties: nrNeighbourInfos: items: + required: + - choiceNrMode + - nrCgi + - nrMode + - nrPci properties: choiceNrMode: properties: @@ -336,6 +317,12 @@ components: type: object type: array servedNrCellInformation: + required: + - cellId + - choiceNrMode + - nrMode + - nrPci + - servedPlmns properties: cellId: type: string @@ -520,20 +507,6 @@ components: additionalProperties: false type: object type: array - ranFunctions: - items: - properties: - ranFunctionId: - type: integer - ranFunctionDefinition: - type: string - ranFunctionRevision: - type: integer - additionalProperties: false - type: object - type: array - additionalProperties: false - type: object additionalProperties: false UpdateGnbResponse: properties: -- 2.16.6