[RIC-587] Update E2 Setup existing nodeb behavior 59/4459/1
authoridanshal <idan.shalom@intl.att.com>
Mon, 27 Jul 2020 14:58:18 +0000 (14:58 +0000)
committeridanshal <idan.shalom@intl.att.com>
Mon, 27 Jul 2020 14:58:23 +0000 (14:58 +0000)
Change-Id: If89b0c4dd7a9b034d510ca1e24ad1349e2004334
Signed-off-by: idanshal <idan.shalom@intl.att.com>
13 files changed:
E2Manager/container-tag.yaml
E2Manager/handlers/httpmsghandlers/delete_all_request_handler.go
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go
E2Manager/managers/e2t_association_manager.go
E2Manager/managers/e2t_association_manager_test.go
E2Manager/managers/e2t_shutdown_manager.go
E2Manager/managers/ran_connect_status_change_manager.go
E2Manager/managers/ran_connect_status_change_manager_test.go
E2Manager/managers/ran_disconnection_manager.go
E2Manager/mocks/rnibWriterMock.go
E2Manager/rNibWriter/rNibWriter.go
E2Manager/services/rnib_data_service.go

index 45daa1d..b2f762c 100644 (file)
@@ -1,4 +1,4 @@
 # The Jenkins job requires a tag to build the Docker image.
 # Global-JJB script assumes this file is in the repo root.
 ---
-tag: 5.2.21
\ No newline at end of file
+tag: 5.2.22
\ No newline at end of file
index 80f1a04..e53c636 100644 (file)
@@ -204,7 +204,7 @@ func (h *DeleteAllRequestHandler) updateNodebInfoShutDown(node *entities.NodebIn
 
 func (h *DeleteAllRequestHandler) updateNodebInfo(node *entities.NodebInfo, connectionStatus entities.ConnectionStatus, resetAssociatedE2TAddress bool) error {
 
-       err := h.ranConnectStatusChangeManager.ChangeStatus(node, connectionStatus)
+       _, err := h.ranConnectStatusChangeManager.ChangeStatus(node, connectionStatus)
        if err != nil {
                return e2managererrors.NewRnibDbError()
        }
index 5565513..259dcc3 100644 (file)
@@ -42,17 +42,17 @@ var (
        emptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "transport-resource-unavailable", "om-intervention", "request-id-unknown",
                "v60s", "v20s", "v10s", "v5s", "v2s", "v1s"}
        gnbTypesMap = map[string]entities.GnbType{
-               "gnb":entities.GnbType_GNB,
-               "en_gnb":entities.GnbType_EN_GNB,
+               "gnb":    entities.GnbType_GNB,
+               "en_gnb": entities.GnbType_EN_GNB,
        }
        enbTypesMap = map[string]entities.EnbType{
-               "enB_macro":entities.EnbType_MACRO_ENB,
-               "enB_home":entities.EnbType_HOME_ENB,
-               "enB_shortmacro":entities.EnbType_SHORT_MACRO_ENB,
-               "enB_longmacro":entities.EnbType_LONG_MACRO_ENB,
-               "ng_enB_macro":entities.EnbType_MACRO_NG_ENB,
-               "ng_enB_shortmacro":entities.EnbType_SHORT_MACRO_NG_ENB,
-               "ng_enB_longmacro":entities.EnbType_LONG_MACRO_NG_ENB,
+               "enB_macro":         entities.EnbType_MACRO_ENB,
+               "enB_home":          entities.EnbType_HOME_ENB,
+               "enB_shortmacro":    entities.EnbType_SHORT_MACRO_ENB,
+               "enB_longmacro":     entities.EnbType_LONG_MACRO_ENB,
+               "ng_enB_macro":      entities.EnbType_MACRO_NG_ENB,
+               "ng_enB_shortmacro": entities.EnbType_SHORT_MACRO_NG_ENB,
+               "ng_enB_longmacro":  entities.EnbType_LONG_MACRO_NG_ENB,
        }
 )
 
@@ -64,7 +64,7 @@ type E2SetupRequestNotificationHandler struct {
        rNibDataService               services.RNibDataService
        e2tAssociationManager         *managers.E2TAssociationManager
        ranConnectStatusChangeManager managers.IRanConnectStatusChangeManager
-       ranListManager managers.RanListManager
+       ranListManager                managers.RanListManager
 }
 
 func NewE2SetupRequestNotificationHandler(logger *logger.Logger, config *configuration.Configuration, e2tInstancesManager managers.IE2TInstancesManager, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, e2tAssociationManager *managers.E2TAssociationManager, ranConnectStatusChangeManager managers.IRanConnectStatusChangeManager, ranListManager managers.RanListManager) *E2SetupRequestNotificationHandler {
@@ -76,7 +76,7 @@ func NewE2SetupRequestNotificationHandler(logger *logger.Logger, config *configu
                rNibDataService:               rNibDataService,
                e2tAssociationManager:         e2tAssociationManager,
                ranConnectStatusChangeManager: ranConnectStatusChangeManager,
-               ranListManager: ranListManager,
+               ranListManager:                ranListManager,
        }
 }
 
@@ -117,12 +117,13 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR
 
        nodebInfo, err := h.rNibDataService.GetNodeb(ranName)
 
+       var functionsModified bool
+
        if err != nil {
 
                if _, ok := err.(*common.ResourceNotFoundError); !ok {
                        h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to retrieve nodebInfo entity. Error: %s", ranName, err)
                        return
-
                }
 
                if nodebInfo, err = h.handleNewRan(ranName, e2tIpAddress, setupRequest); err != nil {
@@ -134,26 +135,56 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR
                }
 
        } else {
-               if err = h.handleExistingRan(ranName, nodebInfo, setupRequest); err != nil {
+
+               functionsModified, err = h.handleExistingRan(ranName, nodebInfo, setupRequest)
+
+               if err != nil {
                        return
                }
        }
 
-       err = h.e2tAssociationManager.AssociateRan(e2tIpAddress, nodebInfo)
+       ranStatusChangePublished, err := h.e2tAssociationManager.AssociateRan(e2tIpAddress, nodebInfo)
 
        if err != nil {
 
                h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to associate E2T to nodeB entity. Error: %s", ranName, err)
                if _, ok := err.(*e2managererrors.RoutingManagerError); ok {
+
+                       if err = h.handleUpdateAndPublishNodebInfo(functionsModified, ranStatusChangePublished, nodebInfo); err != nil {
+                               return
+                       }
+
                        cause := models.Cause{Transport: &models.CauseTransport{TransportResourceUnavailable: &struct{}{}}}
                        h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause)
                }
                return
        }
 
+       if err = h.handleUpdateAndPublishNodebInfo(functionsModified, ranStatusChangePublished, nodebInfo); err != nil {
+               return
+       }
+
        h.handleSuccessfulResponse(ranName, request, setupRequest)
 }
 
+func (h *E2SetupRequestNotificationHandler) handleUpdateAndPublishNodebInfo(functionsModified bool, ranStatusChangePublished bool, nodebInfo *entities.NodebInfo) error {
+
+       if ranStatusChangePublished || !functionsModified {
+               return nil
+       }
+
+       err := h.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
+
+       if err != nil {
+               h.logger.Errorf("#E2SetupRequestNotificationHandler.handleUpdateAndPublishNodebInfo - RAN name: %s - Failed at UpdateNodebInfoAndPublish. error: %s", nodebInfo.RanName, err)
+               return err
+       }
+
+       h.logger.Infof("#E2SetupRequestNotificationHandler.handleUpdateAndPublishNodebInfo - RAN name: %s - Successfully executed UpdateNodebInfoAndPublish", nodebInfo.RanName)
+       return nil
+
+}
+
 func (h *E2SetupRequestNotificationHandler) handleNewRan(ranName string, e2tIpAddress string, setupRequest *models.E2SetupRequestMessage) (*entities.NodebInfo, error) {
 
        nodebInfo, err := h.buildNodebInfo(ranName, e2tIpAddress, setupRequest)
@@ -179,26 +210,24 @@ func (h *E2SetupRequestNotificationHandler) handleNewRan(ranName string, e2tIpAd
        return nodebInfo, nil
 }
 
-func (h *E2SetupRequestNotificationHandler) setGnbFunctions(nodebInfo *entities.NodebInfo, setupRequest *models.E2SetupRequestMessage) {
-       if nodebInfo.GetNodeType() == entities.Node_ENB {
-               return
+func (h *E2SetupRequestNotificationHandler) handleExistingRan(ranName string, nodebInfo *entities.NodebInfo, setupRequest *models.E2SetupRequestMessage) (bool, error) {
+       if nodebInfo.GetConnectionStatus() == entities.ConnectionStatus_SHUTTING_DOWN {
+               h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s, connection status: %s - nodeB entity in incorrect state", ranName, nodebInfo.ConnectionStatus)
+               return false, errors.New("nodeB entity in incorrect state")
        }
 
-       ranFunctions := setupRequest.ExtractRanFunctionsList()
-       if ranFunctions != nil {
-               nodebInfo.GetGnb().RanFunctions = ranFunctions
+       if nodebInfo.NodeType == entities.Node_ENB {
+               return false, nil
        }
-}
 
-func (h *E2SetupRequestNotificationHandler) handleExistingRan(ranName string, nodebInfo *entities.NodebInfo, setupRequest *models.E2SetupRequestMessage) error {
-       if nodebInfo.GetConnectionStatus() == entities.ConnectionStatus_SHUTTING_DOWN {
-               h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s, connection status: %s - nodeB entity in incorrect state", ranName, nodebInfo.ConnectionStatus)
-               return errors.New("nodeB entity in incorrect state")
-       }
+       setupMessageRanFuncs := setupRequest.ExtractRanFunctionsList()
 
-       h.setGnbFunctions(nodebInfo, setupRequest)
+       if setupMessageRanFuncs == nil || (len(setupMessageRanFuncs) == 0 && len(nodebInfo.GetGnb().RanFunctions) == 0) {
+               return false, nil
+       }
 
-       return h.rNibDataService.UpdateNodebInfo(nodebInfo)
+       nodebInfo.GetGnb().RanFunctions = setupMessageRanFuncs
+       return true, nil
 }
 
 func (h *E2SetupRequestNotificationHandler) handleUnsuccessfulResponse(ranName string, req *models.NotificationRequest, cause models.Cause) {
@@ -318,13 +347,23 @@ func (h *E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAd
                AssociatedE2TInstanceAddress: e2tAddress,
                RanName:                      ranName,
                GlobalNbId:                   h.buildGlobalNbId(request),
-               SetupFromNetwork:                         true,
+               SetupFromNetwork:             true,
        }
        err := h.setNodeTypeAndConfiguration(nodebInfo)
        if err != nil {
                return nil, err
        }
-       h.setGnbFunctions(nodebInfo, request)
+
+       if nodebInfo.NodeType == entities.Node_ENB {
+               return nodebInfo, nil
+       }
+
+       ranFuncs := request.ExtractRanFunctionsList()
+
+       if ranFuncs != nil {
+               nodebInfo.GetGnb().RanFunctions = ranFuncs
+       }
+
        return nodebInfo, nil
 }
 
index f0af881..77ffe7a 100644 (file)
@@ -51,7 +51,7 @@ const (
        GnbWithoutFunctionsSetupRequestXmlPath   = "../../tests/resources/setupRequest_gnb_without_functions.xml"
        E2SetupFailureResponseWithMiscCause      = "<E2AP-PDU><unsuccessfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupFailure><protocolIEs><E2setupFailureIEs><id>1</id><criticality><ignore/></criticality><value><Cause><misc><om-intervention/></misc></Cause></value></E2setupFailureIEs><E2setupFailureIEs><id>31</id><criticality><ignore/></criticality><value><TimeToWait><v60s/></TimeToWait></value></E2setupFailureIEs></protocolIEs></E2setupFailure></value></unsuccessfulOutcome></E2AP-PDU>"
        E2SetupFailureResponseWithTransportCause = "<E2AP-PDU><unsuccessfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupFailure><protocolIEs><E2setupFailureIEs><id>1</id><criticality><ignore/></criticality><value><Cause><transport><transport-resource-unavailable/></transport></Cause></value></E2setupFailureIEs><E2setupFailureIEs><id>31</id><criticality><ignore/></criticality><value><TimeToWait><v60s/></TimeToWait></value></E2setupFailureIEs></protocolIEs></E2setupFailure></value></unsuccessfulOutcome></E2AP-PDU>"
-       E2SetupFailureResponseWithRicCause      = "<E2AP-PDU><unsuccessfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupFailure><protocolIEs><E2setupFailureIEs><id>1</id><criticality><ignore/></criticality><value><Cause><ricRequest><request-id-unknown/></ricRequest></Cause></value></E2setupFailureIEs><E2setupFailureIEs><id>31</id><criticality><ignore/></criticality><value><TimeToWait><v60s/></TimeToWait></value></E2setupFailureIEs></protocolIEs></E2setupFailure></value></unsuccessfulOutcome></E2AP-PDU>"
+       E2SetupFailureResponseWithRicCause       = "<E2AP-PDU><unsuccessfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupFailure><protocolIEs><E2setupFailureIEs><id>1</id><criticality><ignore/></criticality><value><Cause><ricRequest><request-id-unknown/></ricRequest></Cause></value></E2setupFailureIEs><E2setupFailureIEs><id>31</id><criticality><ignore/></criticality><value><TimeToWait><v60s/></TimeToWait></value></E2setupFailureIEs></protocolIEs></E2setupFailure></value></unsuccessfulOutcome></E2AP-PDU>"
        StateChangeMessageChannel                = "RAN_CONNECTION_STATUS_CHANGE"
 )
 
@@ -274,14 +274,14 @@ func TestE2SetupRequestNotificationHandler_HandleNewNgEnbSuccess(t *testing.T) {
 
 func TestExtractionOfNodeTypeFromRanName(t *testing.T) {
        handler, _, _, _, _, _ := initMocks(t)
-       validRanNames := []string {"gnb_P310_410_b5c67788","en_gnb_P310_410_b5c67788","ng_enB_macro_P310_410_b5c67788","ng_enB_shortmacro_P310_410_b5c67788","ng_enB_longmacro_P310_410_b5c67788","enB_macro_P310_410_b5c67788","enB_home_P310_410_b5c67788","enB_shortmacro_P310_410_b5c67788","enB_longmacro_P310_410_b5c67788"}
-       for _,v := range validRanNames {
+       validRanNames := []string{"gnb_P310_410_b5c67788", "en_gnb_P310_410_b5c67788", "ng_enB_macro_P310_410_b5c67788", "ng_enB_shortmacro_P310_410_b5c67788", "ng_enB_longmacro_P310_410_b5c67788", "enB_macro_P310_410_b5c67788", "enB_home_P310_410_b5c67788", "enB_shortmacro_P310_410_b5c67788", "enB_longmacro_P310_410_b5c67788"}
+       for _, v := range validRanNames {
                nodeb := &entities.NodebInfo{RanName: v}
                err := handler.setNodeTypeAndConfiguration(nodeb)
                assert.Nil(t, err)
        }
-       inValidRanNames := []string {"P310_410_b5c67788","blabla_P310_410_b5c67788","ng_enB-macro_P310_410_b5c67788","ng_enb_shortmacro_P310_410_b5c67788","ng_enB-longmacro_P310_410_b5c67788","enB_new_macro_P310_410_b5c67788"}
-       for _,v := range inValidRanNames {
+       inValidRanNames := []string{"P310_410_b5c67788", "blabla_P310_410_b5c67788", "ng_enB-macro_P310_410_b5c67788", "ng_enb_shortmacro_P310_410_b5c67788", "ng_enB-longmacro_P310_410_b5c67788", "enB_new_macro_P310_410_b5c67788"}
+       for _, v := range inValidRanNames {
                nodeb := &entities.NodebInfo{RanName: v}
                err := handler.setNodeTypeAndConfiguration(nodeb)
                assert.NotNil(t, err, v)
@@ -289,7 +289,14 @@ func TestExtractionOfNodeTypeFromRanName(t *testing.T) {
 }
 
 func testE2SetupRequestNotificationHandler_HandleExistingConnectedGnbSuccess(t *testing.T, withFunctions bool) {
-       xmlGnb := readXmlFile(t, GnbSetupRequestXmlPath)
+       var xmlGnb []byte
+
+       if withFunctions {
+               xmlGnb = readXmlFile(t, GnbSetupRequestXmlPath)
+
+       } else {
+               xmlGnb = readXmlFile(t, GnbWithoutFunctionsSetupRequestXmlPath)
+       }
        handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t)
        readerMock.On("GetGeneralConfiguration").Return(&entities.GeneralConfiguration{EnableRic: true}, nil)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceFullAddress).Return(&entities.E2TInstance{}, nil)
@@ -311,14 +318,17 @@ func testE2SetupRequestNotificationHandler_HandleExistingConnectedGnbSuccess(t *
 
        notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)}
        gnbToUpdate := getExpectedNodebForExistingRan(*nodebInfo, notificationRequest.Payload)
+
        writerMock.On("UpdateNodebInfo", gnbToUpdate).Return(nil)
+       if withFunctions {
+               writerMock.On("UpdateNodebInfoAndPublish", gnbToUpdate).Return(nil)
+       }
        e2tInstancesManagerMock.On("AddRansToInstance", e2tInstanceFullAddress, []string{gnbNodebRanName}).Return(nil)
        var errEmpty error
        rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(&rmrCgo.MBuf{}, errEmpty)
        handler.Handle(notificationRequest)
        readerMock.AssertExpectations(t)
        writerMock.AssertExpectations(t)
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 3)
        e2tInstancesManagerMock.AssertExpectations(t)
        rmrMessengerMock.AssertCalled(t, "SendMsg", mock.Anything, true)
 }
@@ -349,7 +359,6 @@ func TestE2SetupRequestNotificationHandler_HandleExistingDisconnectedGnbSuccess(
 
        notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(e2SetupMsgPrefix), xmlGnb...)}
        gnbToUpdate := getExpectedNodebForExistingRan(*nodebInfo, notificationRequest.Payload)
-       writerMock.On("UpdateNodebInfo", gnbToUpdate).Return(nil)
        gnbToUpdate2 := *gnbToUpdate
        gnbToUpdate2.ConnectionStatus = entities.ConnectionStatus_CONNECTED
        writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &gnbToUpdate2, gnbNodebRanName+"_CONNECTED").Return(nil)
@@ -363,7 +372,6 @@ func TestE2SetupRequestNotificationHandler_HandleExistingDisconnectedGnbSuccess(
        handler.Handle(notificationRequest)
        readerMock.AssertExpectations(t)
        writerMock.AssertExpectations(t)
-       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
        e2tInstancesManagerMock.AssertExpectations(t)
 }
 
@@ -371,7 +379,9 @@ func getExpectedNodebForExistingRan(nodeb entities.NodebInfo, payload []byte) *e
        pipInd := bytes.IndexByte(payload, '|')
        setupRequest := &models.E2SetupRequestMessage{}
        _ = xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
-       nodeb.GetGnb().RanFunctions = setupRequest.ExtractRanFunctionsList()
+       if ranFuncs := setupRequest.ExtractRanFunctionsList(); ranFuncs != nil {
+               nodeb.GetGnb().RanFunctions = ranFuncs
+       }
        return &nodeb
 }
 
@@ -412,7 +422,7 @@ func getExpectedEnbNodebForNewRan(payload []byte) *entities.NodebInfo {
                NodeType:                     entities.Node_ENB,
                Configuration: &entities.NodebInfo_Enb{
                        Enb: &entities.Enb{
-                               EnbType:      entities.EnbType_MACRO_ENB,
+                               EnbType: entities.EnbType_MACRO_ENB,
                        },
                },
                GlobalNbId: &entities.GlobalNbId{
index dfcaa3d..9ebdd60 100644 (file)
@@ -45,37 +45,37 @@ func NewE2TAssociationManager(logger *logger.Logger, rnibDataService services.RN
        }
 }
 
-func (m *E2TAssociationManager) AssociateRan(e2tAddress string, nodebInfo *entities.NodebInfo) error {
+func (m *E2TAssociationManager) AssociateRan(e2tAddress string, nodebInfo *entities.NodebInfo) (bool, error) {
        ranName := nodebInfo.RanName
        m.logger.Infof("#E2TAssociationManager.AssociateRan - Associating RAN %s to E2T Instance address: %s", ranName, e2tAddress)
 
-       err := m.associateRanAndUpdateNodeb(e2tAddress, nodebInfo)
+       ranStatusChangePublished, err := m.associateRanAndUpdateNodeb(e2tAddress, nodebInfo)
        if err != nil {
                m.logger.Errorf("#E2TAssociationManager.AssociateRan - RoutingManager failure: Failed to associate RAN %s to E2T %s. Error: %s", nodebInfo, e2tAddress, err)
-               return err
+               return ranStatusChangePublished, err
        }
        err = m.e2tInstanceManager.AddRansToInstance(e2tAddress, []string{ranName})
        if err != nil {
                m.logger.Errorf("#E2TAssociationManager.AssociateRan - RAN name: %s - Failed to add RAN to E2T instance %s. Error: %s", ranName, e2tAddress, err)
-               return e2managererrors.NewRnibDbError()
+               return ranStatusChangePublished, e2managererrors.NewRnibDbError()
        }
        m.logger.Infof("#E2TAssociationManager.AssociateRan - successfully associated RAN %s with E2T %s", ranName, e2tAddress)
-       return nil
+       return ranStatusChangePublished, nil
 }
 
-func (m *E2TAssociationManager) associateRanAndUpdateNodeb(e2tAddress string, nodebInfo *entities.NodebInfo) error {
+func (m *E2TAssociationManager) associateRanAndUpdateNodeb(e2tAddress string, nodebInfo *entities.NodebInfo) (bool, error) {
 
        rmErr := m.rmClient.AssociateRanToE2TInstance(e2tAddress, nodebInfo.RanName)
 
        if rmErr != nil {
-               _ =  m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_DISCONNECTED)
-               return e2managererrors.NewRoutingManagerError()
+               ranStatusChangePublished, _ := m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_DISCONNECTED)
+               return ranStatusChangePublished, e2managererrors.NewRoutingManagerError()
        }
 
-       rnibErr := m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_CONNECTED)
+       ranStatusChangePublished, rnibErr := m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_CONNECTED)
 
        if rnibErr != nil {
-               return e2managererrors.NewRnibDbError()
+               return ranStatusChangePublished, e2managererrors.NewRnibDbError()
        }
 
        nodebInfo.AssociatedE2TInstanceAddress = e2tAddress
@@ -83,10 +83,10 @@ func (m *E2TAssociationManager) associateRanAndUpdateNodeb(e2tAddress string, no
 
        if rnibErr != nil {
                m.logger.Errorf("#E2TAssociationManager.associateRanAndUpdateNodeb - RAN name: %s - Failed updating nodeb. Error: %s", nodebInfo.RanName, rnibErr)
-               return e2managererrors.NewRnibDbError()
+               return ranStatusChangePublished, e2managererrors.NewRnibDbError()
        }
 
-       return nil
+       return ranStatusChangePublished, nil
 }
 
 func (m *E2TAssociationManager) DissociateRan(e2tAddress string, ranName string) error {
index bc17295..5a3a114 100644 (file)
@@ -92,7 +92,7 @@ func TestAssociateRanSuccess(t *testing.T) {
        updatedE2tInstance.AssociatedRanList = append(updatedE2tInstance.AssociatedRanList, RanName)
        writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
 
-       err := manager.AssociateRan(E2TAddress, nb)
+       _, err := manager.AssociateRan(E2TAddress, nb)
 
        assert.Nil(t, err)
        readerMock.AssertExpectations(t)
@@ -108,7 +108,7 @@ func TestAssociateRan_RnibError(t *testing.T) {
        updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
        writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNb, RanName+"_CONNECTED").Return(common.NewInternalError(fmt.Errorf("for tests")))
 
-       err := manager.AssociateRan(E2TAddress, nb)
+       _, err := manager.AssociateRan(E2TAddress, nb)
 
        assert.NotNil(t, err)
        assert.IsType(t, &e2managererrors.RnibDbError{}, err)
@@ -123,7 +123,7 @@ func TestAssociateRanRoutingManagerError(t *testing.T) {
        nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
        writerMock.On("UpdateNodebInfo", nb).Return(nil)
 
-       err := manager.AssociateRan(E2TAddress, nb)
+       _, err := manager.AssociateRan(E2TAddress, nb)
 
        assert.NotNil(t, err)
        assert.IsType(t, &e2managererrors.RoutingManagerError{}, err)
@@ -144,7 +144,7 @@ func TestAssociateRanUpdateNodebError(t *testing.T) {
        updatedNb2.AssociatedE2TInstanceAddress = E2TAddress
        writerMock.On("UpdateNodebInfo", &updatedNb2).Return(e2managererrors.NewRnibDbError())
 
-       err := manager.AssociateRan(E2TAddress, nb)
+       _, err := manager.AssociateRan(E2TAddress, nb)
 
        assert.NotNil(t, err)
        assert.IsType(t, &e2managererrors.RnibDbError{}, err)
@@ -169,7 +169,7 @@ func TestAssociateRanGetE2tInstanceError(t *testing.T) {
        var e2tInstance *entities.E2TInstance
        readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, errors.New("test"))
 
-       err := manager.AssociateRan(E2TAddress, nb)
+       _, err := manager.AssociateRan(E2TAddress, nb)
 
        assert.NotNil(t, err)
        assert.IsType(t, &e2managererrors.RnibDbError{}, err)
@@ -197,7 +197,7 @@ func TestAssociateRanSaveE2tInstanceError(t *testing.T) {
        updatedE2tInstance.AssociatedRanList = append(updatedE2tInstance.AssociatedRanList, RanName)
        writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(errors.New("test"))
 
-       err := manager.AssociateRan(E2TAddress, nb)
+       _, err := manager.AssociateRan(E2TAddress, nb)
 
        assert.NotNil(t, err)
        assert.IsType(t, &e2managererrors.RnibDbError{}, err)
index 61761f2..3c88dbd 100644 (file)
@@ -96,7 +96,7 @@ func (m E2TShutdownManager) clearNodebsAssociation(ranNamesToBeDissociated []str
                        return err
                }
 
-               err = m.ranConnectStatusChangeManager.ChangeStatus(nodeb, entities.ConnectionStatus_DISCONNECTED)
+               _, err = m.ranConnectStatusChangeManager.ChangeStatus(nodeb, entities.ConnectionStatus_DISCONNECTED)
                if err != nil {
                        return err
                }
index ecb645c..138f089 100644 (file)
@@ -32,7 +32,7 @@ const (
 )
 
 type IRanConnectStatusChangeManager interface {
-       ChangeStatus(nodebInfo *entities.NodebInfo, nextStatus entities.ConnectionStatus) error
+       ChangeStatus(nodebInfo *entities.NodebInfo, nextStatus entities.ConnectionStatus) (bool, error)
 }
 
 type RanConnectStatusChangeManager struct {
@@ -51,9 +51,11 @@ func NewRanConnectStatusChangeManager(logger *logger.Logger, rnibDataService ser
        }
 }
 
-func (m *RanConnectStatusChangeManager) ChangeStatus(nodebInfo *entities.NodebInfo, nextStatus entities.ConnectionStatus) error {
+func (m *RanConnectStatusChangeManager) ChangeStatus(nodebInfo *entities.NodebInfo, nextStatus entities.ConnectionStatus) (bool, error) {
        m.logger.Infof("#RanConnectStatusChangeManager.ChangeStatus - RAN name: %s, currentStatus: %s, nextStatus: %s", nodebInfo.RanName, nodebInfo.GetConnectionStatus(), nextStatus)
 
+       var ranStatusChangePublished bool
+
        // set the proper event
        event := m.setEvent(nodebInfo, nextStatus)
        isConnectivityEvent := event != NONE_RAW_EVENT
@@ -63,13 +65,14 @@ func (m *RanConnectStatusChangeManager) ChangeStatus(nodebInfo *entities.NodebIn
        if !isConnectivityEvent {
                err := m.updateNodebInfo(nodebInfo)
                if err != nil {
-                       return err
+                       return ranStatusChangePublished, err
                }
        } else {
                err := m.updateNodebInfoOnConnectionStatusInversion(nodebInfo, event)
                if err != nil {
-                       return err
+                       return ranStatusChangePublished, err
                }
+               ranStatusChangePublished = true
        }
 
        // in any case, update RanListManager
@@ -89,7 +92,7 @@ func (m *RanConnectStatusChangeManager) ChangeStatus(nodebInfo *entities.NodebIn
                }
        }
 
-       return nil
+       return ranStatusChangePublished, nil
 }
 
 func (m *RanConnectStatusChangeManager) updateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, event string) error {
index 53921a1..a35e71e 100644 (file)
@@ -62,7 +62,7 @@ func TestChangeStatusSuccessNewRan(t *testing.T) {
        writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, RanName+"_"+CONNECTED_RAW_EVENT).Return(nil)
        ranListManagerMock.On("UpdateRanState", &updatedNodebInfo).Return(nil)
        ranAlarmServiceMock.On("SetConnectivityChangeAlarm", &updatedNodebInfo).Return(nil)
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
        assert.Nil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -77,7 +77,7 @@ func TestChangeStatusSuccessEventNone1(t *testing.T) {
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(nil)
        ranListManagerMock.On("UpdateRanState", &updatedNodebInfo).Return(nil)
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
        assert.Nil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -92,7 +92,7 @@ func TestChangeStatusSuccessEventNone2(t *testing.T) {
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(nil)
        ranListManagerMock.On("UpdateRanState", &updatedNodebInfo).Return(nil)
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
        assert.Nil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -108,7 +108,7 @@ func TestChangeStatusSuccessEventConnected(t *testing.T) {
        writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, RanName+"_"+CONNECTED_RAW_EVENT).Return(nil)
        ranListManagerMock.On("UpdateRanState", &updatedNodebInfo).Return(nil)
        ranAlarmServiceMock.On("SetConnectivityChangeAlarm", &updatedNodebInfo).Return(nil)
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
        assert.Nil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -124,7 +124,7 @@ func TestChangeStatusSuccessEventDisconnected(t *testing.T) {
        writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, RanName+"_"+DISCONNECTED_RAW_EVENT).Return(nil)
        ranListManagerMock.On("UpdateRanState", &updatedNodebInfo).Return(nil)
        ranAlarmServiceMock.On("SetConnectivityChangeAlarm", &updatedNodebInfo).Return(nil)
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_DISCONNECTED)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_DISCONNECTED)
        assert.Nil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -138,7 +138,7 @@ func TestChangeStatusRnibErrorEventNone(t *testing.T) {
        updatedNodebInfo := *origNodebInfo
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(common.NewInternalError(errors.New("Error")))
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
        assert.NotNil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -152,7 +152,7 @@ func TestChangeStatusRnibErrorEventConnected(t *testing.T) {
        updatedNodebInfo := *origNodebInfo
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTED
        writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, RanName+"_"+CONNECTED_RAW_EVENT).Return(common.NewInternalError(errors.New("Error")))
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
        assert.NotNil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -167,7 +167,7 @@ func TestChangeStatusRanListManagerError(t *testing.T) {
        updatedNodebInfo.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
        writerMock.On("UpdateNodebInfo", &updatedNodebInfo).Return(nil)
        ranListManagerMock.On("UpdateRanState", &updatedNodebInfo).Return(common.NewInternalError(errors.New("Error")))
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_SHUT_DOWN)
        assert.Nil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
@@ -183,7 +183,7 @@ func TestChangeStatusRanAlarmServiceErrorEventConnected(t *testing.T) {
        writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &updatedNodebInfo, RanName+"_"+CONNECTED_RAW_EVENT).Return(nil)
        ranListManagerMock.On("UpdateRanState", &updatedNodebInfo).Return(nil)
        ranAlarmServiceMock.On("SetConnectivityChangeAlarm", &updatedNodebInfo).Return(common.NewInternalError(errors.New("Error")))
-       err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
+       _, err := ranConnectStatusChangeManager.ChangeStatus(origNodebInfo, entities.ConnectionStatus_CONNECTED)
        assert.Nil(t, err)
        writerMock.AssertExpectations(t)
        ranListManagerMock.AssertExpectations(t)
index f07e8fd..8d30eec 100644 (file)
@@ -65,10 +65,11 @@ func (m *RanDisconnectionManager) DisconnectRan(inventoryName string) error {
        }
 
        if connectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
-               return m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+               _, err = m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_SHUT_DOWN)
+               return err
        }
 
-       err = m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_DISCONNECTED)
+       _, err = m.ranConnectStatusChangeManager.ChangeStatus(nodebInfo, entities.ConnectionStatus_DISCONNECTED)
 
        if err != nil {
                return err
index 35a255a..02237a4 100644 (file)
@@ -52,6 +52,18 @@ func (rnibWriterMock *RnibWriterMock) UpdateNodebInfo(nodebInfo *entities.NodebI
        return nil
 }
 
+func (rnibWriterMock *RnibWriterMock) UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error {
+       args := rnibWriterMock.Called(nodebInfo)
+
+       errArg := args.Get(0)
+
+       if errArg != nil {
+               return errArg.(error)
+       }
+
+       return nil
+}
+
 func (rnibWriterMock *RnibWriterMock) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error {
        args := rnibWriterMock.Called(inventoryName, ranLoadInformation)
 
@@ -134,4 +146,4 @@ func (rnibWriterMock *RnibWriterMock) RemoveNbIdentity(nodeType entities.Node_Ty
 func (rnibWriterMock *RnibWriterMock) AddEnb(nodebInfo *entities.NodebInfo) error {
        args := rnibWriterMock.Called(nodebInfo)
        return args.Error(0)
-}
\ No newline at end of file
+}
index 7678fb3..670ee6b 100644 (file)
@@ -46,6 +46,7 @@ RNibWriter interface allows saving data to the redis DB
 type RNibWriter interface {
        SaveNodeb(nodebInfo *entities.NodebInfo) error
        UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
+       UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error
        SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error
        SaveE2TInstance(e2tInstance *entities.E2TInstance) error
        SaveE2TAddresses(addresses []string) error
@@ -340,10 +341,7 @@ func (w *rNibWriterInstance) RemoveNbIdentity(nodeType entities.Node_Type, nbIde
        return nil
 }
 
-/*
-UpdateNodebInfo...
-*/
-func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
+func (w *rNibWriterInstance) updateNodebInfo(nodebInfo *entities.NodebInfo, publish bool) error {
 
        pairs, err := buildUpdateNodebInfoPairs(nodebInfo)
 
@@ -351,7 +349,12 @@ func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) erro
                return err
        }
 
-       err = w.sdl.Set(pairs)
+       if publish {
+               channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent)
+               err = w.sdl.SetAndPublish(channelsAndEvents, pairs)
+       } else {
+               err = w.sdl.Set(pairs)
+       }
 
        if err != nil {
                return common.NewInternalError(err)
@@ -360,6 +363,21 @@ func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) erro
        return nil
 }
 
+/*
+UpdateNodebInfo...
+*/
+func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
+       return w.updateNodebInfo(nodebInfo, false)
+}
+
+/*
+UpdateNodebInfoAndPublish...
+*/
+func (w *rNibWriterInstance) UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error {
+       return w.updateNodebInfo(nodebInfo, true)
+}
+
+
 /*
 SaveRanLoadInformation stores ran load information for the provided ran
 */
index 7d3d6c5..e2b5dc4 100644 (file)
@@ -33,6 +33,7 @@ import (
 type RNibDataService interface {
        SaveNodeb(nodebInfo *entities.NodebInfo) error
        UpdateNodebInfo(nodebInfo *entities.NodebInfo) error
+       UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error
        SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error
        GetNodeb(ranName string) (*entities.NodebInfo, error)
        GetListNodebIds() ([]*entities.NbIdentity, error)
@@ -142,6 +143,17 @@ func (w *rNibDataService) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error {
        return err
 }
 
+func (w *rNibDataService) UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error {
+       w.logger.Infof("#RnibDataService.UpdateNodebInfoAndPublish - nodebInfo: %s", nodebInfo)
+
+       err := w.retry("UpdateNodebInfoAndPublish", func() (err error) {
+               err = w.rnibWriter.UpdateNodebInfoAndPublish(nodebInfo)
+               return
+       })
+
+       return err
+}
+
 func (w *rNibDataService) SaveNodeb(nodebInfo *entities.NodebInfo) error {
        w.logger.Infof("#RnibDataService.SaveNodeb - nodebInfo: %s", nodebInfo)