[RICPLT-2590] US completion........
[ric-plt/e2mgr.git] / E2Manager / handlers / httpmsghandlers / delete_all_request_handler.go
index 6e70deb..975640a 100644 (file)
 // 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.
-//
+
+//  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/rNibWriter"
        "e2mgr/rmrCgo"
        "e2mgr/services"
-       "e2mgr/stateMachine"
+       "e2mgr/services/rmrsender"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
        "time"
 )
 
 type DeleteAllRequestHandler struct {
-       readerProvider func() reader.RNibReader
-       writerProvider func() rNibWriter.RNibWriter
-       rmrService *services.RmrService
-       config *configuration.Configuration
+       rnibDataService     services.RNibDataService
+       rmrSender           *rmrsender.RmrSender
+       config              *configuration.Configuration
+       logger              *logger.Logger
+       e2tInstancesManager managers.IE2TInstancesManager
+       rmClient            clients.IRoutingManagerClient
 }
 
-func NewDeleteAllRequestHandler(rmrService *services.RmrService, config *configuration.Configuration, writerProvider func() rNibWriter.RNibWriter, readerProvider func() reader.RNibReader) *DeleteAllRequestHandler {
-       return &DeleteAllRequestHandler {
-               readerProvider: readerProvider,
-               writerProvider: writerProvider,
-               rmrService: rmrService,
-               config: config,
+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) *DeleteAllRequestHandler {
+       return &DeleteAllRequestHandler{
+               logger:              logger,
+               rnibDataService:     rnibDataService,
+               rmrSender:           rmrSender,
+               config:              config,
+               e2tInstancesManager: e2tInstancesManager,
+               rmClient:            rmClient,
        }
 }
 
-func (handler *DeleteAllRequestHandler) Handle(logger *logger.Logger, request models.Request) 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(logger, false)
        if err != nil {
-               return err
+               return nil, err
        }
 
-       if continueFlow == false{
-               return nil
+       if len(e2tAddresses) == 0 {
+               err, _ = h.updateNodebs(h.updateNodebInfoForceShutdown)
+               return nil, err
        }
 
-       //TODO change to rmr_request
-       response := models.NotificationResponse{MgsType: rmrCgo.RIC_SCTP_CLEAR_ALL}
-       if err:= handler.rmrService.SendRmrMessage(&response); err != nil {
-               logger.Errorf("#DeleteAllRequestHandler.Handle - failed to send sctp clear all message to RMR: %s", err)
-               return  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)
-       logger.Infof("#DeleteAllRequestHandler.Handle - timer expired")
+       err, updatedAtLeastOnce := h.updateNodebs(h.updateNodebInfoShuttingDown)
 
-       err, _ = handler.updateNodebStates(logger, true)
        if err != nil {
-               return err
+               return nil, err
        }
 
-       return nil
-}
+       err = h.e2tInstancesManager.ClearRansOfAllE2TInstances()
 
-func (handler *DeleteAllRequestHandler) updateNodebStates(logger *logger.Logger, timeoutExpired bool) (error, bool){
-       nbIdentityList, err := handler.readerProvider().GetListNodebIds()
+       if err != nil {
+               return nil, err
+       }
+
+       rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
+
+       err = h.rmrSender.Send(&rmrMessage)
 
        if err != nil {
-               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
+       }
+
+       time.Sleep(time.Duration(h.config.BigRedButtonTimeoutSec) * time.Second)
+       h.logger.Infof("#DeleteAllRequestHandler.Handle - timer expired")
+
+       err, _ = h.updateNodebs(h.updateNodebInfoShutDown)
+
+       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, err := h.rnibDataService.GetListNodebIds()
+
+       if err != nil {
+               h.logger.Errorf("#DeleteAllRequestHandler.updateNodebs - failed to get nodes list from rNib. Error: %s", err)
+               return e2managererrors.NewRnibDbError(), false
        }
 
-       numOfRanToShutDown := 0
-       for _,nbIdentity := range nbIdentityList{
+       updatedAtLeastOnce := false
 
-               node, err := handler.readerProvider().GetNodeb((*nbIdentity).GetInventoryName())
+       for _, nbIdentity := range nbIdentityList {
+               node, err := h.rnibDataService.GetNodeb(nbIdentity.InventoryName)
 
                if err != nil {
-                       logger.Errorf("#DeleteAllRequestHandler.updateNodebStates - failed to get nodeB entity for ran name: %v from RNIB. Error: %s",
-                               (*nbIdentity).GetInventoryName(), err.Error())
+                       _, ok := err.(*common.ResourceNotFoundError)
+
+                       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 timeoutExpired{
+               err, updated := updateCb(node)
 
-                       if handler.saveNodebShutDownState(logger, nbIdentity, node){
-                               numOfRanToShutDown++
-                       }
-                       continue
+               if err != nil {
+                       return err, false
                }
-               if handler.saveNodebNextState(logger, nbIdentity, node){
-                       numOfRanToShutDown++
+
+               if updated {
+                       updatedAtLeastOnce = true
                }
        }
 
-       if numOfRanToShutDown > 0{
-               logger.Infof("#DeleteAllRequestHandler.updateNodebStates - update nodebs states in RNIB completed")
-       }else {
-               logger.Infof("#DeleteAllRequestHandler.updateNodebStates - nodebs states are not updated ")
-               return nil, false
+       return nil, updatedAtLeastOnce
+}
+
+func (h *DeleteAllRequestHandler) updateNodebInfoForceShutdown(node *entities.NodebInfo) (error, bool) {
+       err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUT_DOWN, true)
+
+       if err != nil {
+               return err, false
        }
 
        return nil, true
 }
 
-func (handler *DeleteAllRequestHandler) saveNodebNextState(logger *logger.Logger, nbIdentity *entities.NbIdentity, node *entities.NodebInfo) bool{
+func (h *DeleteAllRequestHandler) updateNodebInfoShuttingDown(node *entities.NodebInfo) (error, bool) {
+       if node.ConnectionStatus == entities.ConnectionStatus_SHUT_DOWN {
+               return nil, false
+       }
+
+       err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUTTING_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
+}
+
+func (h *DeleteAllRequestHandler) updateNodebInfoShutDown(node *entities.NodebInfo) (error, bool) {
+       if node.ConnectionStatus == entities.ConnectionStatus_SHUT_DOWN {
+               return nil, false
        }
 
-       node.ConnectionStatus = nextStatus
+       if node.ConnectionStatus != entities.ConnectionStatus_SHUTTING_DOWN {
+               h.logger.Warnf("#DeleteAllRequestHandler.updateNodebInfoShutDown - RAN name: %s - ignore, status is not Shutting Down", node.RanName)
+               return nil, false
+       }
 
-       err := handler.writerProvider().SaveNodeb(nbIdentity, node)
+       err :=  h.updateNodebInfo(node, entities.ConnectionStatus_SHUT_DOWN, false)
 
        if err != nil {
-               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 logger.DebugEnabled() {
-               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(logger *logger.Logger, nbIdentity *entities.NbIdentity, node *entities.NodebInfo) bool{
-
-       if node.ConnectionStatus == entities.ConnectionStatus_SHUT_DOWN{
-               return false
-       }
+func (h *DeleteAllRequestHandler) updateNodebInfo(node *entities.NodebInfo, connectionStatus entities.ConnectionStatus, resetAssociatedE2TAddress bool) error {
+       node.ConnectionStatus = connectionStatus
 
-       if node.ConnectionStatus != entities.ConnectionStatus_SHUTTING_DOWN {
-               logger.Errorf("#DeleteAllRequestHandler.saveNodebShutDownState - ignore, status is not Shutting Down, inventory name: %v ", (*nbIdentity).GetInventoryName())
-               return false
+       if resetAssociatedE2TAddress {
+               node.AssociatedE2TInstanceAddress = ""
        }
 
-       node.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
-
-       err := handler.writerProvider().SaveNodeb(nbIdentity, node)
+       err := h.rnibDataService.UpdateNodebInfo(node)
 
        if err != nil {
-               logger.Errorf("#DeleteAllRequestHandler.saveNodebShutDownState - failed to save nodeB entity for inventory name: %v to RNIB. Error: %s",
-                       (*nbIdentity).GetInventoryName(), err.Error())
-               return false
+               h.logger.Errorf("#DeleteAllRequestHandler.updateNodebInfo - RAN name: %s - failed updating nodeB entity in rNib. error: %s", node.RanName, err)
+               return e2managererrors.NewRnibDbError()
        }
 
-       logger.Errorf("#DeleteAllRequestHandler.saveNodebShutDownState - Shut Down , inventory name: %v ", (*nbIdentity).GetInventoryName())
-       return true
+       h.logger.Infof("#DeleteAllRequestHandler.updateNodebInfo - RAN name: %s, connection status: %s", node.RanName, connectionStatus)
+       return nil
+
 }