[RIC-298] Added handling for orphan cells and updated Swagger 83/3383/1
authoridanshal <idan.shalom@intl.att.com>
Wed, 22 Apr 2020 12:56:43 +0000 (15:56 +0300)
committeridanshal <idan.shalom@intl.att.com>
Wed, 22 Apr 2020 12:56:49 +0000 (15:56 +0300)
Change-Id: Id4d6cdc6aeafba948c7ac9aab93bd5cd7043d108
Signed-off-by: idanshal <idan.shalom@intl.att.com>
E2Manager/controllers/nodeb_controller_test.go
E2Manager/go.mod
E2Manager/go.sum
E2Manager/handlers/httpmsghandlers/update_gnb_request_handler.go
E2Manager/mocks/rnibWriterMock.go
E2Manager/rNibWriter/rNibWriter.go
E2Manager/rNibWriter/rNibWriter_test.go
E2Manager/services/rnib_data_service.go
Swagger/E2M_API_2020-04-22.yaml [moved from Swagger/E2Manager_API.yaml with 97% similarity, mode: 0755]

index 4bdfd2c..c61249e 100644 (file)
@@ -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,
                },
index 3fd0b4c..1195401 100644 (file)
@@ -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
 )
 
index 4dd7bc0..193bed0 100644 (file)
@@ -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=
index e22925f..5d9d2b2 100644 (file)
@@ -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)
index 8fb5403..5c602bb 100644 (file)
@@ -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)
+}
+
index f9f75bd..a44f388 100644 (file)
@@ -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())
 
index 9306b97..257bb85 100644 (file)
@@ -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")
index af329af..7235028 100644 (file)
@@ -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)
 
old mode 100644 (file)
new mode 100755 (executable)
similarity index 97%
rename from Swagger/E2Manager_API.yaml
rename to Swagger/E2M_API_2020-04-22.yaml
index 2b765a0..bcc1e84
@@ -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: