[RIC-587] Update E2 Setup existing nodeb behavior
[ric-plt/e2mgr.git] / E2Manager / handlers / httpmsghandlers / delete_all_request_handler.go
index eb238cc..e53c636 100644 (file)
 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
 //  platform project (RICP).
 
-
 package httpmsghandlers
 
 import "C"
 import (
+       "e2mgr/clients"
        "e2mgr/configuration"
        "e2mgr/e2managererrors"
        "e2mgr/logger"
+       "e2mgr/managers"
        "e2mgr/models"
        "e2mgr/rmrCgo"
        "e2mgr/services"
        "e2mgr/services/rmrsender"
-       "e2mgr/stateMachine"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "time"
 )
 
 type DeleteAllRequestHandler struct {
-       rnibDataService services.RNibDataService
-       rmrSender       *rmrsender.RmrSender
-       config          *configuration.Configuration
-       logger          *logger.Logger
+       rnibDataService               services.RNibDataService
+       rmrSender                     *rmrsender.RmrSender
+       config                        *configuration.Configuration
+       logger                        *logger.Logger
+       e2tInstancesManager           managers.IE2TInstancesManager
+       rmClient                      clients.IRoutingManagerClient
+       ranConnectStatusChangeManager managers.IRanConnectStatusChangeManager
+       ranListManager                managers.RanListManager
 }
 
-func NewDeleteAllRequestHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rnibDataService services.RNibDataService) *DeleteAllRequestHandler {
+const PartialSuccessDueToRmErrorMessage = "Operation succeeded except for routing manager outbound call"
+
+func NewDeleteAllRequestHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rnibDataService services.RNibDataService, e2tInstancesManager managers.IE2TInstancesManager, rmClient clients.IRoutingManagerClient, ranConnectStatusChangeManager managers.IRanConnectStatusChangeManager, ranListManager managers.RanListManager) *DeleteAllRequestHandler {
        return &DeleteAllRequestHandler{
-               logger:          logger,
-               rnibDataService: rnibDataService,
-               rmrSender:       rmrSender,
-               config:          config,
+               logger:                        logger,
+               rnibDataService:               rnibDataService,
+               rmrSender:                     rmrSender,
+               config:                        config,
+               e2tInstancesManager:           e2tInstancesManager,
+               rmClient:                      rmClient,
+               ranConnectStatusChangeManager: ranConnectStatusChangeManager,
+               ranListManager:                ranListManager,
        }
 }
 
-func (handler *DeleteAllRequestHandler) Handle(request models.Request) (models.IResponse, error) {
+func (h *DeleteAllRequestHandler) Handle(request models.Request) (models.IResponse, error) {
+       h.logger.Infof("#DeleteAllRequestHandler.Handle - handling shutdown request")
+
+       e2tAddresses, err := h.e2tInstancesManager.GetE2TAddresses()
 
-       err, continueFlow := handler.updateNodebStates(false)
        if err != nil {
                return nil, err
        }
 
-       if continueFlow == false {
-               return nil, nil
+       if len(e2tAddresses) == 0 {
+               err, _ = h.updateNodebs(h.updateNodebInfoForceShutdown)
+               return nil, err
        }
 
-       response := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
-       if err := handler.rmrSender.Send(&response); err != nil {
-               handler.logger.Errorf("#DeleteAllRequestHandler.Handle - failed to send sctp clear all message to RMR: %s", err)
-               return nil, e2managererrors.NewRmrError()
+       dissocErr := h.rmClient.DissociateAllRans(e2tAddresses)
+
+       if dissocErr != nil {
+               h.logger.Warnf("#DeleteAllRequestHandler.Handle - routing manager failure. continue flow.")
        }
 
-       time.Sleep(time.Duration(handler.config.BigRedButtonTimeoutSec) * time.Second)
-       handler.logger.Infof("#DeleteAllRequestHandler.Handle - timer expired")
+       err, updatedAtLeastOnce := h.updateNodebs(h.updateNodebInfoShuttingDown)
 
-       err, _ = handler.updateNodebStates(true)
        if err != nil {
                return nil, err
        }
 
-       return nil, nil
-}
+       err = h.e2tInstancesManager.ClearRansOfAllE2TInstances()
 
-func (handler *DeleteAllRequestHandler) updateNodebStates(timeoutExpired bool) (error, bool) {
-       nbIdentityList, err := handler.rnibDataService.GetListNodebIds()
+       if err != nil {
+               return nil, err
+       }
+
+       rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
+
+       err = h.rmrSender.Send(&rmrMessage)
 
        if err != nil {
-               handler.logger.Errorf("#DeleteAllRequestHandler.updateNodebStates - failed to get nodes list from RNIB. Error: %s", err.Error())
-               return e2managererrors.NewRnibDbError(), false
+               h.logger.Errorf("#DeleteAllRequestHandler.Handle - failed to send sctp clear all message to RMR: %s", err)
+               return nil, e2managererrors.NewRmrError()
        }
 
-       if len(nbIdentityList) == 0 {
-               return nil, false
+       if !updatedAtLeastOnce {
+               h.logger.Infof("#DeleteAllRequestHandler.Handle - DB wasn't updated, not activating timer")
+
+               if dissocErr != nil {
+                       return models.NewRedButtonPartialSuccessResponseModel(PartialSuccessDueToRmErrorMessage), nil
+               }
+
+               return nil, nil
        }
 
-       numOfRanToShutDown := 0
-       for _, nbIdentity := range nbIdentityList {
+       time.Sleep(time.Duration(h.config.BigRedButtonTimeoutSec) * time.Second)
+       h.logger.Infof("#DeleteAllRequestHandler.Handle - timer expired")
 
-               node, err := handler.rnibDataService.GetNodeb((*nbIdentity).GetInventoryName())
+       err, _ = h.updateNodebs(h.updateNodebInfoShutDown)
 
-               if err != nil {
-                       handler.logger.Errorf("#DeleteAllRequestHandler.updateNodebStates - failed to get nodeB entity for ran name: %v from RNIB. Error: %s",
-                               (*nbIdentity).GetInventoryName(), err.Error())
-                       continue
-               }
+       if err != nil {
+               return nil, err
+       }
+
+       if dissocErr != nil {
+               return models.NewRedButtonPartialSuccessResponseModel(PartialSuccessDueToRmErrorMessage), nil
+       }
+
+       return nil, nil
+}
+
+func (h *DeleteAllRequestHandler) updateNodebs(updateCb func(node *entities.NodebInfo) (error, bool)) (error, bool) {
+       nbIdentityList := h.ranListManager.GetNbIdentityList()
+       updatedAtLeastOnce := false
 
-               if timeoutExpired {
+       for _, nbIdentity := range nbIdentityList {
+               node, err := h.rnibDataService.GetNodeb(nbIdentity.InventoryName)
+
+               if err != nil {
+                       _, ok := err.(*common.ResourceNotFoundError)
 
-                       if handler.saveNodebShutDownState(nbIdentity, node) {
-                               numOfRanToShutDown++
+                       if !ok {
+                               h.logger.Errorf("#DeleteAllRequestHandler.updateNodebs - failed to get nodeB entity for ran name: %s from rNib. error: %s", nbIdentity.InventoryName, err)
+                               return e2managererrors.NewRnibDbError(), false
                        }
                        continue
                }
-               if handler.saveNodebNextState(nbIdentity, node) {
-                       numOfRanToShutDown++
+
+               err, updated := updateCb(node)
+
+               if err != nil {
+                       return err, false
                }
-       }
 
-       if numOfRanToShutDown > 0 {
-               handler.logger.Infof("#DeleteAllRequestHandler.updateNodebStates - update nodebs states in RNIB completed")
-       } else {
-               handler.logger.Infof("#DeleteAllRequestHandler.updateNodebStates - nodebs states are not updated ")
-               return nil, false
+               if updated {
+                       updatedAtLeastOnce = true
+               }
        }
 
-       return nil, true
+       return nil, updatedAtLeastOnce
 }
 
-func (handler *DeleteAllRequestHandler) saveNodebNextState(nbIdentity *entities.NbIdentity, node *entities.NodebInfo) bool {
+func (h *DeleteAllRequestHandler) updateNodebInfoForceShutdown(node *entities.NodebInfo) (error, bool) {
+       err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUT_DOWN, true)
 
-       if node.ConnectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
-               return true
+       if err != nil {
+               return err, false
        }
 
-       nextStatus, res := stateMachine.NodeNextStateDeleteAll(node.ConnectionStatus)
-       if res == false {
-               return false
-       }
+       return nil, true
+}
 
-       node.ConnectionStatus = nextStatus
+func (h *DeleteAllRequestHandler) updateNodebInfoShuttingDown(node *entities.NodebInfo) (error, bool) {
+       if node.ConnectionStatus == entities.ConnectionStatus_SHUT_DOWN {
+               return nil, false
+       }
 
-       err := handler.rnibDataService.SaveNodeb(nbIdentity, node)
+       err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUTTING_DOWN, true)
 
        if err != nil {
-               handler.logger.Errorf("#DeleteAllRequestHandler.saveNodebNextState - failed to save nodeB entity for inventory name: %v to RNIB. Error: %s",
-                       (*nbIdentity).GetInventoryName(), err.Error())
-               return false
+               return err, false
        }
 
-       if handler.logger.DebugEnabled() {
-               handler.logger.Debugf("#DeleteAllRequestHandler.saveNodebNextState - connection status of inventory name: %v changed to %v",
-                       (*nbIdentity).GetInventoryName(), nextStatus.String())
-       }
-       return true
+       return nil, true
 }
 
-func (handler *DeleteAllRequestHandler) saveNodebShutDownState(nbIdentity *entities.NbIdentity, node *entities.NodebInfo) bool {
-
+func (h *DeleteAllRequestHandler) updateNodebInfoShutDown(node *entities.NodebInfo) (error, bool) {
        if node.ConnectionStatus == entities.ConnectionStatus_SHUT_DOWN {
-               return false
+               return nil, false
        }
 
        if node.ConnectionStatus != entities.ConnectionStatus_SHUTTING_DOWN {
-               handler.logger.Errorf("#DeleteAllRequestHandler.saveNodebShutDownState - ignore, status is not Shutting Down, inventory name: %v ", (*nbIdentity).GetInventoryName())
-               return false
+               h.logger.Warnf("#DeleteAllRequestHandler.updateNodebInfoShutDown - RAN name: %s - ignore, status is not Shutting Down", node.RanName)
+               return nil, false
+       }
+
+       err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUT_DOWN, false)
+
+       if err != nil {
+               return err, false
        }
 
-       node.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
+       return nil, true
+}
 
-       err := handler.rnibDataService.SaveNodeb(nbIdentity, node)
+func (h *DeleteAllRequestHandler) updateNodebInfo(node *entities.NodebInfo, connectionStatus entities.ConnectionStatus, resetAssociatedE2TAddress bool) error {
 
+       _, err := h.ranConnectStatusChangeManager.ChangeStatus(node, connectionStatus)
        if err != nil {
-               handler.logger.Errorf("#DeleteAllRequestHandler.saveNodebShutDownState - failed to save nodeB entity for inventory name: %v to RNIB. Error: %s",
-                       (*nbIdentity).GetInventoryName(), err.Error())
-               return false
+               return e2managererrors.NewRnibDbError()
+       }
+
+       if resetAssociatedE2TAddress {
+               node.AssociatedE2TInstanceAddress = ""
+
+               err = h.rnibDataService.UpdateNodebInfo(node)
+               if err != nil {
+                       h.logger.Errorf("#DeleteAllRequestHandler.updateNodebInfo - RAN name: %s - failed updating nodeB entity in rNib. error: %s", node.RanName, err)
+                       return e2managererrors.NewRnibDbError()
+               }
        }
+       h.logger.Infof("#DeleteAllRequestHandler.updateNodebInfo - RAN name: %s, connection status: %s", node.RanName, connectionStatus)
+       return nil
 
-       handler.logger.Errorf("#DeleteAllRequestHandler.saveNodebShutDownState - Shut Down , inventory name: %v ", (*nbIdentity).GetInventoryName())
-       return true
 }