RIC-997: ErrorIndication handling in e2mgr 66/12566/1
authorpkranthi <p.kiran@nokia.com>
Fri, 23 Feb 2024 11:13:25 +0000 (16:43 +0530)
committerpkranthi <p.kiran@nokia.com>
Fri, 23 Feb 2024 11:14:29 +0000 (16:44 +0530)
Change-Id: I355b1ca452d00ce461c306c0178c8aa5c498c5bc
Signed-off-by: pkranthi <p.kiran@nokia.com>
25 files changed:
E2Manager/app/main.go
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go
E2Manager/handlers/rmrmsghandlers/error_indication_notification_handler.go [new file with mode: 0644]
E2Manager/handlers/rmrmsghandlers/error_indication_notification_handler_test.go [new file with mode: 0644]
E2Manager/handlers/rmrmsghandlers/ric_service_update_handler.go
E2Manager/handlers/rmrmsghandlers/ric_service_update_handler_test.go
E2Manager/managers/notificationmanager/notification_manager_test.go
E2Manager/managers/ric_service_update_manager.go [new file with mode: 0644]
E2Manager/managers/ric_service_update_manager_test.go [new file with mode: 0644]
E2Manager/mocks/logger_mock.go [new file with mode: 0644]
E2Manager/mocks/ricServiceUpdate_manager_mock.go [new file with mode: 0644]
E2Manager/models/e2_error_indication_message.go [new file with mode: 0644]
E2Manager/models/e2_error_indication_message_test.go [new file with mode: 0644]
E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go
E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go
E2Manager/rmrCgo/rmrCgoApi.go
E2Manager/rmrCgo/rmrCgoTypes.go
E2Manager/rmrCgo/rmrCgoUtils.go
E2Manager/services/rmrreceiver/rmr_receiver_test.go
E2Manager/tests/resources/errorIndication/errorIndicationForDefault.xml [new file with mode: 0644]
E2Manager/tests/resources/errorIndication/errorIndicationForServiceUpdate.xml [new file with mode: 0644]
E2Manager/tests/resources/errorIndication/errorIndicationForSetupRequest.xml [new file with mode: 0644]
E2Manager/tests/resources/errorIndication/errorIndicationInvalid.xml [new file with mode: 0644]
E2Manager/tests/resources/errorIndication/errorIndicationUnsuccessfulOutcome.xml [new file with mode: 0644]
E2Manager/tests/resources/errorIndication/errorIndicationWithoutCD.xml [new file with mode: 0644]

index 58d20b5..dc2ff87 100644 (file)
@@ -35,12 +35,12 @@ import (
        "e2mgr/services/rmrreceiver"
        "e2mgr/services/rmrsender"
        //"fmt"
-        "flag"
+    "flag"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
-       "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
-        "github.com/spf13/viper"
-        "github.com/fsnotify/fsnotify"
+    "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
+    "github.com/spf13/viper"
+    "github.com/fsnotify/fsnotify"
        "os"
        "strconv"
 )
@@ -141,6 +141,7 @@ func main() {
        rnibDataService := services.NewRnibDataService(Log, config, reader.GetNewRNibReader(sdl), rNibWriter.GetRNibWriter(sdl, config.RnibWriter))
 
        ranListManager := managers.NewRanListManager(Log, rnibDataService)
+       RicServiceUpdateManager := managers.NewRicServiceUpdateManager(Log, rnibDataService)
 
        err = ranListManager.InitNbIdentityMap()
 
@@ -160,7 +161,7 @@ func main() {
        e2tShutdownManager := managers.NewE2TShutdownManager(Log, config, rnibDataService, e2tInstancesManager, e2tAssociationManager, ranConnectStatusChangeManager)
        e2tKeepAliveWorker := managers.NewE2TKeepAliveWorker(Log, rmrSender, e2tInstancesManager, e2tShutdownManager, config)
        rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider()
-       rmrNotificationHandlerProvider.Init(Log, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
+       rmrNotificationHandlerProvider.Init(Log, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager)
 
        notificationManager := notificationmanager.NewNotificationManager(Log, rmrNotificationHandlerProvider)
        rmrReceiver := rmrreceiver.NewRmrReceiver(Log, rmrMessenger, notificationManager)
index 9dde134..3f93c58 100644 (file)
@@ -90,6 +90,7 @@ func NewE2SetupRequestNotificationHandler(logger *logger.Logger, config *configu
 
 func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationRequest) {
        ranName := request.RanName
+       models.UpdateProcedureType(ranName, models.E2SetupProcedureNotInitiated)
        h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - received E2_SETUP_REQUEST. Payload: %x", ranName, request.Payload)
 
        generalConfiguration, err := h.rNibDataService.GetGeneralConfiguration()
@@ -113,6 +114,7 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR
        if !generalConfiguration.EnableRic {
                cause := models.Cause{Misc: &models.CauseMisc{OmIntervention: &struct{}{}}}
                h.handleUnsuccessfulResponse(ranName, request, cause, setupRequest)
+               models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure)
                return
        }
 
@@ -138,6 +140,7 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR
                        if _, ok := err.(*e2managererrors.UnknownSetupRequestRanNameError); ok {
                                cause := models.Cause{RicRequest: &models.CauseRic{RequestIdUnknown: &struct{}{}}}
                                h.handleUnsuccessfulResponse(ranName, request, cause, setupRequest)
+                               models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure)
                        }
                        return
                }
@@ -148,9 +151,11 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR
 
                if err != nil {
                        h.fillCauseAndSendUnsuccessfulResponse(nodebInfo, request, setupRequest)
+                       models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure)
                        return
                }
        }
+       models.UpdateProcedureType(ranName, models.E2SetupProcedureOngoing)
 
        ranStatusChangePublished, err := h.e2tAssociationManager.AssociateRan(e2tIpAddress, nodebInfo)
 
@@ -165,6 +170,7 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR
 
                        cause := models.Cause{Transport: &models.CauseTransport{TransportResourceUnavailable: &struct{}{}}}
                        h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause, setupRequest)
+                       models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure)
                }
                return
        }
@@ -174,6 +180,8 @@ func (h *E2SetupRequestNotificationHandler) Handle(request *models.NotificationR
        }
 
        h.handleSuccessfulResponse(ranName, request, setupRequest)
+       models.UpdateProcedureType(ranName, models.E2SetupProcedureCompleted)
+       h.logger.Debugf("#E2SetupRequestNotificationHandler.Handle - updating the enum value to e2setup request completed")
 }
 
 func (h *E2SetupRequestNotificationHandler) handleUpdateAndPublishNodebInfo(functionsModified bool, ranStatusChangePublished bool, nodebInfo *entities.NodebInfo) error {
@@ -459,8 +467,10 @@ func (h *E2SetupRequestNotificationHandler) buildNbIdentity(ranName string, setu
 }
 
 func (h *E2SetupRequestNotificationHandler) fillCauseAndSendUnsuccessfulResponse(nodebInfo *entities.NodebInfo, request *models.NotificationRequest, setupRequest *models.E2SetupRequestMessage) {
+       ranName := request.RanName
        if nodebInfo.GetConnectionStatus() == entities.ConnectionStatus_DISCONNECTED {
                cause := models.Cause{Misc: &models.CauseMisc{ControlProcessingOverload: &struct{}{}}}
                h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause, setupRequest)
+               models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure)
        }
 }
diff --git a/E2Manager/handlers/rmrmsghandlers/error_indication_notification_handler.go b/E2Manager/handlers/rmrmsghandlers/error_indication_notification_handler.go
new file mode 100644 (file)
index 0000000..321563f
--- /dev/null
@@ -0,0 +1,156 @@
+// Copyright 2023 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.
+
+//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
+//  platform project (RICP)
+
+package rmrmsghandlers
+
+import (
+       "bytes"
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/models"
+       "e2mgr/utils"
+       "encoding/xml"
+       "fmt"
+
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+       "sync"
+)
+
+var e2ErrorIndicationMessage = models.ErrorIndicationMessage{}
+
+var E2SETUP_PROCEDURE string = "1"
+var RICSERVICEUPDATE_PROCEDURE string = "7"
+
+type ErrorIndicationHandler struct {
+       logger                  *logger.Logger
+       ranDisconnectionManager managers.IRanDisconnectionManager
+       RicServiceUpdateManager managers.IRicServiceUpdateManager
+       procedureMapMutex       sync.RWMutex
+}
+
+
+func ErrorIndicationNotificationHandler(logger *logger.Logger, ranDisconnectionManager managers.IRanDisconnectionManager, RicServiceUpdateManager managers.IRicServiceUpdateManager) *ErrorIndicationHandler {
+       return &ErrorIndicationHandler{
+               logger:                  logger,
+               ranDisconnectionManager: ranDisconnectionManager,
+               RicServiceUpdateManager: RicServiceUpdateManager,
+       }
+}
+func (errorIndicationHandler *ErrorIndicationHandler) Handle (request *models.NotificationRequest) {
+       ranName := request.RanName
+       errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Received Error Indication from E2Node - %s", ranName)
+
+       errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Received ErrorIndication payload at E2M is - %x", request.Payload)
+       errorIndicationMessage, err := errorIndicationHandler.parseErrorIndication(request.Payload)
+       if err != nil {
+               errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle- Parsing is not successful")
+               return
+       }
+       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle ERROR INDICATION from E2Node has been parsed successfully- %+v", errorIndicationMessage)
+       errorIndicationIE := errorIndicationMessage.E2APPDU.InitiatingMessage.Value.ErrorIndication.ProtocolIEs.ErrorIndicationIEs
+       fmt.Printf("errorIndicationIE value is %+v", errorIndicationIE)
+       
+       for i := 0 ; i < len(errorIndicationIE) ; i++ {
+               if errorIndicationIE[i].ID == 2 {
+                       errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-CD is: %+v", errorIndicationIE[i].Value.CriticalityDiagnostics)
+                       if errorIndicationIE[i].Value.CriticalityDiagnostics.ProcedureCode != "" && errorIndicationIE[i].Value.CriticalityDiagnostics.TriggeringMessage.SuccessfulOutcome != nil {
+                               procedureCode := errorIndicationIE[i].Value.CriticalityDiagnostics.ProcedureCode
+                               errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-procedureCode present is: %+v", procedureCode)
+                               errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle- before triggeringMessage present is: %+v", errorIndicationIE[i].Value.CriticalityDiagnostics.TriggeringMessage)
+                               triggeringMessageValue := &errorIndicationIE[i].Value.CriticalityDiagnostics.TriggeringMessage.SuccessfulOutcome
+                               errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-triggeringMessage present is: %+v", *triggeringMessageValue)
+                               if procedureCode != "" && triggeringMessageValue != nil {
+                                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.handleErrorIndicationBasedOnProcedureCode for all scenarios")
+                                       switch procedureCode {
+                                       case E2SETUP_PROCEDURE:
+                                               if triggeringMessageValue != nil {
+                                                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at E2Setup procedure")
+                                                       err = errorIndicationHandler.ranDisconnectionManager.DisconnectRan(ranName)
+                                                       errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Cleanup Completed !!")
+                                                       return
+                                               } else {
+                                                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication recieved for unsuccessful-outcome, no action taken")
+                                               }
+                                       case RICSERVICEUPDATE_PROCEDURE:
+                                               if triggeringMessageValue != nil {
+                                                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at Ric Service Update procedure")
+                                                       err = errorIndicationHandler.RicServiceUpdateManager.RevertRanFunctions(ranName)
+                                                       if err != nil {
+                                                               errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-reverting RanFunctions and updating the nodebInfo failed due to error %+v", err)
+                                                       }
+                                                       return
+                                               } else {
+                                                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication recieved for unsuccessful-outcome, no action taken")
+                                               }
+                                       default:
+                                               errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-problem in handling of error indication")
+                                               return
+                                       }
+                               }
+                       }
+               }
+       }
+       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-CriticalityDiagnostics IEs unsuccessful hence Retrieving based on procedureMap")
+       errorIndicationHandler.HandleBasedOnProcedureType(ranName)
+       errorIndicationHandler.logger.Debugf("#ErrorIndicationHandler.Handle-Cleanup Completed !!")
+}
+
+
+
+func (errorIndicationHandler *ErrorIndicationHandler) HandleBasedOnProcedureType(ranName string) error {
+       errorIndicationHandler.procedureMapMutex.RLock()
+       procedureType, ok := models.ProcedureMap[ranName]
+       errorIndicationHandler.procedureMapMutex.RUnlock()
+       if !ok {
+               errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-Error ProcedureType not found for ranName %s", ranName)
+       } else {
+               switch procedureType {
+               case models.E2SetupProcedureCompleted:
+                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at E2Setup procedure")
+                       err := errorIndicationHandler.ranDisconnectionManager.DisconnectRan(ranName)
+                       if err != nil {
+                               errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-Disconnect RAN and updating the nodebInfo failed due to error %+v", err)
+                       }
+               case models.RicServiceUpdateCompleted:
+                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication happened at Ric Service Update procedure")
+                       err := errorIndicationHandler.RicServiceUpdateManager.RevertRanFunctions(ranName)
+                       if err != nil {
+                               errorIndicationHandler.logger.Errorf("#ErrorIndicationHandler.Handle-reverting RanFunctions and updating the nodebInfo failed due to error %+v", err)
+                       }
+               case models.E2SetupProcedureFailure, models.RicServiceUpdateFailure:
+                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-ErrorIndication occcured before successful outcome hence ignoring")
+               default:
+                       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.Handle-Error in handling the ErrorIndication based on enum")
+               }
+       }
+       return nil
+}
+
+func (errorIndicationHandler *ErrorIndicationHandler) parseErrorIndication(payload []byte) (*models.ErrorIndicationMessage, error) {
+       pipInd := bytes.IndexByte(payload, '|')
+       if pipInd < 0 {
+               return nil, common.NewInternalError(fmt.Errorf("#ErrorIndicationHandler.parseErrorIndication - Error parsing ERROR INDICATION failed extract Payload: no | separator found"))
+       }
+       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.parseErrorIndication - payload: %s", payload)
+       errorIndicationHandler.logger.Infof("#ErrorIndicationHandler.parseErrorIndication - payload: %s", payload[pipInd+1:])
+       errorIndicationMessage := &models.ErrorIndicationMessage{}
+       err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &errorIndicationMessage.E2APPDU)
+       if err != nil {
+               return nil, common.NewInternalError(fmt.Errorf("#ErrorIndicationHandler.parseErrorIndication - Error unmarshalling ERROR INDICATION payload: %x", payload))
+       }
+       return errorIndicationMessage, nil
+}
\ No newline at end of file
diff --git a/E2Manager/handlers/rmrmsghandlers/error_indication_notification_handler_test.go b/E2Manager/handlers/rmrmsghandlers/error_indication_notification_handler_test.go
new file mode 100644 (file)
index 0000000..af3e578
--- /dev/null
@@ -0,0 +1,294 @@
+// Copyright 2023 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.
+
+//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
+//  platform project (RICP)
+
+package rmrmsghandlers
+
+import (
+       "bytes"
+       "e2mgr/clients"
+       "e2mgr/configuration"
+       "e2mgr/managers"
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "e2mgr/tests"
+       "e2mgr/services"
+       "e2mgr/utils"
+       "encoding/json"
+       "io/ioutil"
+       "net/http"
+       "testing"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+)
+
+const (
+       RanNameForErrorIndication        = "test"
+       E2tAddress                       = "10.10.2.15:9800"
+       e2tInstanceFullAddressErrorIndication          = "10.0.2.15:9999"
+       e2SetupMsgPrefixErrorIndication                = e2tInstanceFullAddressErrorIndication + "|"
+       ErrorIndicationXmlPath           = "../../tests/resources/errorIndication/ErrorIndicationForSetupRequest.xml"
+       ErrorIndicationWithoutCDXmlPath           = "../../tests/resources/errorIndication/ErrorIndicationWithoutCD.xml"
+       ErrorIndicationXmlPathServiceUpdate = "../../tests/resources/errorIndication/ErrorIndicationForServiceUpdate.xml"
+       ErrorIndicationXmlPathUnsuccessfuOutcome =  "../../tests/resources/errorIndication/ErrorIndicationUnsuccessfulOutcome.xml"
+       ErrorIndicationXmlPathDefault = "../../tests/resources/errorIndication/ErrorIndicationForDefault.xml"
+       ErrorIndicationInvalidXmlPath = "../../tests/resources/errorIndication/ErrorIndicationInvalid.xml"
+)
+
+func initErrorIndication(t *testing.T) (*ErrorIndicationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock, *mocks.RoutingManagerClientMock, managers.RanListManager,*mocks.RanDisconnectionManagerMock,*mocks.RicServiceUpdateManagerMock, *mocks.MockLogger, *mocks.HttpClientMock,*mocks.RanListManagerMock) {
+       logger := tests.InitLog(t)
+       config := &configuration.Configuration{
+               RnibRetryIntervalMs:       10,
+               MaxRnibConnectionAttempts: 3,
+               RnibWriter: configuration.RnibWriterConfig{
+                       StateChangeMessageChannel: StateChangeMessageChannel,
+               },
+               GlobalRicId: struct {
+                       RicId string
+                       Mcc   string
+                       Mnc   string
+               }{Mcc: "327", Mnc: "94", RicId: "AACCE"}}
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+       RanDisconnectionManagerMock := &mocks.RanDisconnectionManagerMock{}
+       ricServiceUpdateManagerMock := &mocks.RicServiceUpdateManagerMock{}
+       MockLogger := &mocks.MockLogger{}
+       routingManagerClientMock := &mocks.RoutingManagerClientMock{}
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
+       httpClientMock := &mocks.HttpClientMock{}
+       ranListManagerMock := &mocks.RanListManagerMock{}
+
+       ranListManager := managers.NewRanListManager(logger, rnibDataService)
+       ranAlarmService := services.NewRanAlarmService(logger, config)
+       ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(logger, rnibDataService, ranListManager, ranAlarmService)
+       e2tAssociationManager := managers.NewE2TAssociationManager(logger, rnibDataService, e2tInstancesManagerMock, routingManagerClientMock, ranConnectStatusChangeManager)
+       ranDisconnectionManager := managers.NewRanDisconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, e2tAssociationManager, ranConnectStatusChangeManager)
+       RicServiceUpdateManager := managers.NewRicServiceUpdateManager(logger, rnibDataService)
+       handler := ErrorIndicationNotificationHandler(logger, ranDisconnectionManager, RicServiceUpdateManager)
+
+       return handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock, ranListManager, RanDisconnectionManagerMock, ricServiceUpdateManagerMock,MockLogger,httpClientMock,ranListManagerMock
+}
+
+func TestParseErrorIndicationMessage_Success(t *testing.T) {
+       ErrorgnbXml := utils.ReadXmlFile(t, ErrorIndicationXmlPath)
+       handler, _, _, _, _, _, _, _, _,_,_,_ := initErrorIndication(t)
+       prefBytes := []byte(e2SetupMsgPrefixErrorIndication)
+       errorIndicationMessage, err := handler.parseErrorIndication(append(prefBytes, ErrorgnbXml...))
+       assert.NotNil(t, errorIndicationMessage)
+       assert.Nil(t, err)
+}
+
+func TestParseErrorIndication_PipFailure(t *testing.T) {
+       ErrorgnbXml := utils.ReadXmlFile(t, ErrorIndicationXmlPath)
+       handler, _, _, _, _, _,_ ,_, _, _,_,_ := initErrorIndication(t)
+       prefBytes := []byte("10.0.2.15:9999")
+       request, err := handler.parseErrorIndication(append(prefBytes, ErrorgnbXml...))
+       assert.Nil(t, request)
+       assert.NotNil(t, err)
+       assert.EqualError(t, err, "#ErrorIndicationHandler.parseErrorIndication - Error parsing ERROR INDICATION failed extract Payload: no | separator found")
+}
+func TestParseErrorIndicationMessage_UnmarshalFailure(t *testing.T) {
+       handler, _,_, _, _, _, _, _, _, _,_,_ := initErrorIndication(t)
+       prefBytes := []byte(e2SetupMsgPrefixErrorIndication)
+       errorIndicationMessage, err := handler.parseErrorIndication(append(prefBytes, 1, 2, 3))
+       assert.Nil(t, errorIndicationMessage)
+       assert.NotNil(t, err)
+       assert.EqualError(t, err, "#ErrorIndicationHandler.parseErrorIndication - Error unmarshalling ERROR INDICATION payload: 31302e302e322e31353a393939397c010203")
+}
+
+func testErrorIndicationNotificationHandler(t *testing.T) {
+       handler, readerMock, writerMock, _, _, _, _, _, _,_ ,_,_:= initErrorIndication(t)
+       writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
+       notificationRequest := models.NotificationRequest{RanName: RanNameForErrorIndication}
+       handler.Handle(&notificationRequest)
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+}
+
+func testErrorIndicationHandlerWhenConnectedRanSuccess(t *testing.T,xmlPath string) {
+       xml := utils.ReadXmlFile(t, xmlPath)
+       handler, readerMock, writerMock, _, e2tInstancesManagerMock,routingManagerClientMock, _, _, _, _,httpClientMock,_ := initErrorIndication(t)
+       origNodebInfo := &entities.NodebInfo{
+               RanName:                      RanNameForErrorIndication,
+               GlobalNbId:                   &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"},
+               ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
+               AssociatedE2TInstanceAddress: E2tAddress,
+       }
+
+       models.UpdateProcedureType(RanNameForErrorIndication,models.E2SetupProcedureCompleted)
+       var rnibErr error
+       readerMock.On("GetNodeb", RanNameForErrorIndication).Return(origNodebInfo, rnibErr)
+       updatedNodebInfo1 := *origNodebInfo
+       updatedNodebInfo1.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, RanNameForErrorIndication+"_DISCONNECTED").Return(rnibErr)
+       updatedNodebInfo2 := *origNodebInfo
+       updatedNodebInfo2.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+       updatedNodebInfo2.AssociatedE2TInstanceAddress = ""
+       writerMock.On("UpdateNodebInfo", mock.Anything).Return(rnibErr)
+       e2tInstance := &entities.E2TInstance{Address: E2tAddress, AssociatedRanList: []string{RanNameForErrorIndication}}
+       readerMock.On("GetE2TInstance", E2tAddress).Return(e2tInstance, nil).Maybe()
+       e2tInstanceToSave := *e2tInstance
+       e2tInstanceToSave.AssociatedRanList = []string{}
+       //writerMock.On("SaveE2TInstance", &e2tInstanceToSave).Return(nil)
+       mockHttpClientForErrorIndication(httpClientMock, true) //After uncommenting testcase is failing 
+       e2tInstancesManagerMock.On("RemoveRanFromInstance", RanNameForErrorIndication, E2tAddress).Return(nil)
+       routingManagerClientMock.On("DissociateRanE2TInstance", E2tAddress, RanNameForErrorIndication).Return(nil)
+       notificationRequest := &models.NotificationRequest{RanName: RanNameForErrorIndication, Payload: append([]byte(e2SetupMsgPrefixErrorIndication), xml...)}
+
+       
+       handler.Handle(notificationRequest)
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+       httpClientMock.AssertExpectations(t)
+       writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+}
+func TestErrorIndicationHandlerWhenConnectedGnbSuccessE2Setup(t *testing.T) {
+       testErrorIndicationHandlerWhenConnectedRanSuccess(t, ErrorIndicationXmlPath)
+}
+
+func TestErrorIndicationHandlerWhenConnectedGnbSuccessProcedureType(t *testing.T) {
+       testErrorIndicationHandlerWhenConnectedRanSuccess(t, ErrorIndicationWithoutCDXmlPath)
+}
+func TestErrorIndicationHandlerWhenConnectedGnbSuccessServiceUpdate(t *testing.T) {
+       testErrorIndicationHandlerWhenConnectedRanSuccessServiceUpdate(t, ErrorIndicationXmlPathServiceUpdate)
+}
+func TestErrorIndicationHandlerWhenConnectedGnbSuccessServiceUpdateProcedureType(t *testing.T) {
+       testErrorIndicationHandlerWhenConnectedRanSuccessServiceUpdate(t, ErrorIndicationWithoutCDXmlPath)
+}
+func TestErrorIndicationHandlerWhenConnectedGnbSuccessUnsuccessfulOutcome(t *testing.T) {
+       testErrorIndicationHandlerWhenConnectedRanSuccess(t, ErrorIndicationXmlPathUnsuccessfuOutcome)
+}
+func TestErrorIndicationHandlerInvalidXML(t *testing.T) {
+       testErrorIndicationHandlerInvalidXML(t, ErrorIndicationInvalidXmlPath)
+}
+func TestErrorIndicationHandlerForUnknownProcedureType(t *testing.T) {
+       testErrorIndicationHandlerWhenConnectedRanSuccessUnknownProcedureType(t,ErrorIndicationWithoutCDXmlPath)
+}
+func TestErrorIndicationHandlerForUnhandlingProcedureType(t *testing.T) {
+       testErrorIndicationHandlerWhenConnectedRanSuccessUnhandlingProcedureType(t,ErrorIndicationWithoutCDXmlPath)
+}
+func TestErrorIndicationHandlerForDefaultProcedureCode(t *testing.T) {
+       testErrorIndicationHandlerForDefaultProcedureCode(t,ErrorIndicationXmlPathDefault)
+}
+func mockHttpClientForErrorIndication(httpClientMock *mocks.HttpClientMock, isSuccessful bool) {
+       data := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2tAddress, RanNameForErrorIndication)}
+       marshaled, _ := json.Marshal(data)
+       body := bytes.NewBuffer(marshaled)
+       respBody := ioutil.NopCloser(bytes.NewBufferString(""))
+       var respStatusCode int
+       if isSuccessful {
+               respStatusCode = http.StatusCreated
+       } else {
+               respStatusCode = http.StatusBadRequest
+       }
+       httpClientMock.On("Post", clients.DissociateRanE2TInstanceApiSuffix, "application/json", body).Return(&http.Response{StatusCode: respStatusCode, Body: respBody}, nil).Maybe()
+}
+
+func testErrorIndicationHandlerWhenConnectedRanSuccessServiceUpdate(t *testing.T,xmlPath string) {
+       xml := utils.ReadXmlFile(t, xmlPath)
+       handler, readerMock, writerMock, _, _,_, _, _, _, _,_,_ := initErrorIndication(t)
+       origNodebInfo := &entities.NodebInfo{
+               RanName:                      RanNameForErrorIndication,
+               GlobalNbId:                   &entities.GlobalNbId{PlmnId: "xxx", NbId: "yyy"},
+               ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
+               AssociatedE2TInstanceAddress: E2tAddress,
+       }
+       logger := tests.InitLog(t)
+       config := &configuration.Configuration{
+               RnibRetryIntervalMs:       10,
+               MaxRnibConnectionAttempts: 3,
+               RnibWriter: configuration.RnibWriterConfig{
+                       StateChangeMessageChannel: StateChangeMessageChannel,
+               },
+               GlobalRicId: struct {
+                       RicId string
+                       Mcc   string
+                       Mnc   string
+               }{Mcc: "327", Mnc: "94", RicId: "AACCE"}}
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       RicServiceUpdateManager := managers.NewRicServiceUpdateManager(logger, rnibDataService)
+       models.UpdateProcedureType(RanNameForErrorIndication,models.RicServiceUpdateCompleted)
+
+       var rnibErr error
+       readerMock.On("GetNodeb", RanNameForErrorIndication).Return(origNodebInfo, rnibErr)
+       updatedNodebInfo1 := *origNodebInfo
+       updatedNodebInfo1.ConnectionStatus = entities.ConnectionStatus_CONNECTED
+       updatedNodebInfo2 := *origNodebInfo
+       updatedNodebInfo2.ConnectionStatus = entities.ConnectionStatus_CONNECTED
+       updatedNodebInfo2.AssociatedE2TInstanceAddress = ""
+       e2tInstance := &entities.E2TInstance{Address: E2tAddress, AssociatedRanList: []string{RanNameForErrorIndication}}
+       readerMock.On("GetE2TInstance", E2tAddress).Return(e2tInstance, nil).Maybe()
+       e2tInstanceToSave := *e2tInstance
+       e2tInstanceToSave.AssociatedRanList = []string{}
+       writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil)
+       err := RicServiceUpdateManager.RevertRanFunctions(ranName)
+       assert.Nil(t,err)
+
+       notificationRequest := &models.NotificationRequest{RanName: RanNameForErrorIndication, Payload: append([]byte(e2SetupMsgPrefixErrorIndication), xml...)}
+       handler.Handle(notificationRequest)
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+}
+func testErrorIndicationHandlerWhenConnectedRanSuccessUnknownProcedureType(t *testing.T,xmlPath string) {
+       xml := utils.ReadXmlFile(t, xmlPath)
+       handler, readerMock, writerMock, _, _,_, _, _, _, _,httpClientMock,_ := initErrorIndication(t)
+
+       models.UpdateProcedureType(RanNameForErrorIndication,models.E2SetupProcedureNotInitiated)
+       notificationRequest := &models.NotificationRequest{RanName: RanNameForErrorIndication, Payload: append([]byte(e2SetupMsgPrefixErrorIndication), xml...)}
+       handler.Handle(notificationRequest)
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+       httpClientMock.AssertExpectations(t)
+}
+
+func testErrorIndicationHandlerWhenConnectedRanSuccessUnhandlingProcedureType(t *testing.T,xmlPath string) {
+       xml := utils.ReadXmlFile(t, xmlPath)
+       handler, readerMock, writerMock, _, _,_, _, _, _, _,httpClientMock,_ := initErrorIndication(t)
+
+       models.UpdateProcedureType(RanNameForErrorIndication,models.E2SetupProcedureFailure)
+       notificationRequest := &models.NotificationRequest{RanName: RanNameForErrorIndication, Payload: append([]byte(e2SetupMsgPrefixErrorIndication), xml...)}
+
+       handler.Handle(notificationRequest)
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+       httpClientMock.AssertExpectations(t)
+}
+
+func testErrorIndicationHandlerInvalidXML(t *testing.T,xmlPath string) {
+       xml := utils.ReadXmlFile(t, xmlPath)
+       handler, readerMock, writerMock, _, _,_, _, _, _, _,httpClientMock,_ := initErrorIndication(t)
+
+       notificationRequest := &models.NotificationRequest{RanName: RanNameForErrorIndication, Payload: append([]byte(e2SetupMsgPrefixErrorIndication), xml...)}
+
+       handler.Handle(notificationRequest)
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+       httpClientMock.AssertExpectations(t)
+}
+func testErrorIndicationHandlerForDefaultProcedureCode(t *testing.T,xmlPath string) {
+       xml := utils.ReadXmlFile(t, xmlPath)
+       handler, readerMock, writerMock, _, _,_, _, _, _, _,httpClientMock,_ := initErrorIndication(t)
+
+       notificationRequest := &models.NotificationRequest{RanName: RanNameForErrorIndication, Payload: append([]byte(e2SetupMsgPrefixErrorIndication), xml...)}
+
+       handler.Handle(notificationRequest)
+       readerMock.AssertExpectations(t)
+       writerMock.AssertExpectations(t)
+       httpClientMock.AssertExpectations(t)
+}
index 15f89a8..b8d1c06 100644 (file)
@@ -55,14 +55,16 @@ type RicServiceUpdateHandler struct {
        rmrSender       *rmrsender.RmrSender
        rNibDataService services.RNibDataService
        ranListManager  managers.RanListManager
+       RicServiceUpdateManager managers.IRicServiceUpdateManager
 }
 
-func NewRicServiceUpdateHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, ranListManager managers.RanListManager) *RicServiceUpdateHandler {
+func NewRicServiceUpdateHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, ranListManager managers.RanListManager,RicServiceUpdateManager managers.IRicServiceUpdateManager) *RicServiceUpdateHandler {
        return &RicServiceUpdateHandler{
                logger:          logger,
                rmrSender:       rmrSender,
                rNibDataService: rNibDataService,
                ranListManager:  ranListManager,
+               RicServiceUpdateManager: RicServiceUpdateManager,
        }
 }
 
@@ -87,6 +89,8 @@ func (h *RicServiceUpdateHandler) Handle(request *models.NotificationRequest) {
                return
        }
        h.logger.Infof("#RicServiceUpdateHandler.Handle - RIC_SERVICE_UPDATE has been parsed successfully %+v", ricServiceUpdate)
+       h.RicServiceUpdateManager.StoreExistingRanFunctions(ranName)
+       h.logger.Infof("#RicServiceUpdate.Handle - Getting the ranFunctions before we do the RIC ServiceUpdate handling")
 
        ackFunctionIds := h.updateFunctions(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs, nodebInfo)
        if len(ricServiceUpdate.E2APPDU.InitiatingMessage.Value.RICServiceUpdate.ProtocolIEs.RICServiceUpdateIEs) > 1 {
@@ -112,6 +116,8 @@ func (h *RicServiceUpdateHandler) Handle(request *models.NotificationRequest) {
        }
 
        h.logger.Infof("#RicServiceUpdate.Handle - Completed successfully")
+       models.UpdateProcedureType(ranName, models.RicServiceUpdateCompleted)
+       h.logger.Debugf("#RicServiceUpdateHandler.Handle  - updating the enum value to RicServiceUpdateCompleted completed")
 }
 
 func (h *RicServiceUpdateHandler) sendUpdateAck(updateAck models.RicServiceUpdateAckE2APPDU, nodebInfo *entities.NodebInfo, request *models.NotificationRequest) error {
index 6e36298..2262d80 100644 (file)
@@ -35,6 +35,7 @@ import (
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/mock"
+       "e2mgr/managers"
 )
 
 const (
@@ -77,7 +78,8 @@ func initRicServiceUpdateHandler(t *testing.T) (*RicServiceUpdateHandler, *mocks
        writerMock := &mocks.RnibWriterMock{}
        rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
        ranListManagerMock := &mocks.RanListManagerMock{}
-       handler := NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManagerMock)
+       RicServiceUpdateManager := managers.NewRicServiceUpdateManager(logger, rnibDataService)
+       handler := NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManagerMock, RicServiceUpdateManager)
        return handler, readerMock, writerMock, rmrMessengerMock, ranListManagerMock
 }
 
index 4ca6ce9..e1dfee0 100644 (file)
@@ -50,10 +50,11 @@ func initNotificationManagerTest(t *testing.T) (*logger.Logger, *mocks.RnibReade
        routingManagerClient := clients.NewRoutingManagerClient(logger, config, httpClient)
        ranListManager := managers.NewRanListManager(logger, rnibDataService)
        ranAlarmService := services.NewRanAlarmService(logger, config)
+       RicServiceUpdateManager := managers.NewRicServiceUpdateManager(logger, rnibDataService)
        ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(logger, rnibDataService,ranListManager, ranAlarmService)
        e2tAssociationManager := managers.NewE2TAssociationManager(logger, rnibDataService, e2tInstancesManager, routingManagerClient, ranConnectStatusChangeManager)
        rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider()
-       rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager,routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
+       rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager,routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager)
        notificationManager := NewNotificationManager(logger, rmrNotificationHandlerProvider )
        return logger, readerMock, notificationManager
 }
diff --git a/E2Manager/managers/ric_service_update_manager.go b/E2Manager/managers/ric_service_update_manager.go
new file mode 100644 (file)
index 0000000..c342e25
--- /dev/null
@@ -0,0 +1,82 @@
+//
+// Copyright 2023 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.
+
+//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
+//  platform project (RICP).
+
+package managers
+
+
+import(
+       "e2mgr/logger"
+       "e2mgr/services"
+       "errors"
+       "e2mgr/models"
+)
+
+
+type IRicServiceUpdateManager interface {
+       RevertRanFunctions(ranName string) error
+       StoreExistingRanFunctions(ranName string) error
+}
+
+
+type RicServiceUpdateManager struct {
+       logger          *logger.Logger
+       rNibDataService services.RNibDataService
+}
+
+func NewRicServiceUpdateManager(logger *logger.Logger, rNibDataService services.RNibDataService) *RicServiceUpdateManager {
+       return &RicServiceUpdateManager{
+               logger:          logger,
+               rNibDataService: rNibDataService,
+       }
+}
+
+
+func (h *RicServiceUpdateManager) StoreExistingRanFunctions(ranName string) error {
+       nodebInfo, err := h.rNibDataService.GetNodeb(ranName)
+       if err != nil {
+               h.logger.Errorf("#RicServiceUpdateManager.revertRanFunctions - failed to get nodeB entity for ran name: %v due to RNIB Error: %s", ranName, err)
+       }
+       if nodebInfo.GetGnb() == nil {
+        h.logger.Errorf("#RicServiceUpdateManager.revertRanFunctions - GNB is nil for RAN name: %s", ranName)
+        return errors.New("There is empty gnb nodebInfo")
+    }
+       models.ExistingRanFunctiuonsMap[ranName] =  nodebInfo.GetGnb().RanFunctions
+       h.logger.Errorf("#RicServiceUpdateManager.revertRanFunctions - Updated ranFunctions for reverting the changes are %v:", models.ExistingRanFunctiuonsMap[ranName])
+       return nil
+}
+
+func (h *RicServiceUpdateManager) RevertRanFunctions(ranName string) error {
+       nodebInfo, err := h.rNibDataService.GetNodeb(ranName)
+       if err != nil {
+               h.logger.Errorf("#RicServiceUpdateManager.revertRanFunctions - failed to get nodeB entity for ran name: %v due to RNIB Error: %s", ranName, err)
+       }
+
+       if nodebInfo.GetGnb() != nil && nodebInfo.GetGnb().RanFunctions != nil {
+               nodebInfo.GetGnb().RanFunctions = models.ExistingRanFunctiuonsMap[ranName]
+       } else {
+               h.logger.Errorf("#RicServiceUpdateManager.revertRanFunctions returned nil")
+       }
+       err = h.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
+       if err != nil {
+               h.logger.Errorf("#RicServiceUpdateManager.revertRanFunctions - RAN name: %s - Failed at UpdateNodebInfoAndPublish. error: %s", nodebInfo.RanName, err)
+               return err
+       }
+
+       h.logger.Infof("#RicServiceUpdateManager.revertRanFunctions - Revert ranFunctions for RAN name: %s", ranName)
+       return nil
+}
\ No newline at end of file
diff --git a/E2Manager/managers/ric_service_update_manager_test.go b/E2Manager/managers/ric_service_update_manager_test.go
new file mode 100644 (file)
index 0000000..b19e46e
--- /dev/null
@@ -0,0 +1,71 @@
+//
+// Copyright 2023 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.
+
+//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
+//  platform project (RICP).
+
+package managers
+
+
+import (
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/mocks"
+       
+       "e2mgr/services"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "testing"
+       "github.com/stretchr/testify/assert"
+       "e2mgr/tests"
+       "github.com/stretchr/testify/mock"
+)
+
+const (
+       serviceUpdateRANName1 = "gnb:TestRan1"
+    E2tAddress = "10.10.2.15:9800"
+)
+
+
+func initRicServiceUpdateManagerTest(t *testing.T) (*logger.Logger,*mocks.RnibReaderMock, *mocks.RnibWriterMock,services.RNibDataService, *configuration.Configuration, *RicServiceUpdateManager) {
+       logger := tests.InitLog(t)
+
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       RicServiceUpdateManager := NewRicServiceUpdateManager(logger, rnibDataService)
+       return logger, readerMock, writerMock, rnibDataService, config, RicServiceUpdateManager
+}
+func TestUpdateRevertRanFunctions(t *testing.T) {
+
+       _,readerMock, writerMock, _, _, RicServiceUpdateManager := initRicServiceUpdateManagerTest(t)
+       InvName := "test"
+       nodebInfo := &entities.NodebInfo{
+               RanName: InvName,
+               NodeType:                     entities.Node_GNB,
+               Configuration:                &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
+       }
+       gnb := nodebInfo.GetGnb()
+       gnb.RanFunctions = []*entities.RanFunction{{RanFunctionId: 2, RanFunctionRevision: 2}}
+       readerMock.On("GetNodeb", InvName).Return(nodebInfo, nil)
+       writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil)
+       err := RicServiceUpdateManager.StoreExistingRanFunctions(ranName)
+       assert.Nil(t, err)
+       err = RicServiceUpdateManager.RevertRanFunctions(ranName)
+       assert.Nil(t, err)
+       writerMock.AssertExpectations(t)
+       readerMock.AssertExpectations(t)
+       readerMock.AssertCalled(t, "GetNodeb", InvName)
+}
diff --git a/E2Manager/mocks/logger_mock.go b/E2Manager/mocks/logger_mock.go
new file mode 100644 (file)
index 0000000..a5563cf
--- /dev/null
@@ -0,0 +1,45 @@
+//
+// Copyright 2023 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.
+
+//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
+//  platform project (RICP).
+
+package mocks
+
+import (
+       "github.com/stretchr/testify/mock"
+)
+
+
+type MockLogger struct {
+       mock.Mock
+}
+
+type MockRanDisconnectionManager struct {
+       mock.Mock
+}
+
+type MockRicServiceUpdateManager struct {
+       mock.Mock
+}
+
+func (m *MockLogger) Errorf(format string, args ...interface{}) {
+       m.Called(format, args)
+}
+
+func (m *MockLogger) Infof(format string, args ...interface{}) {
+       m.Called(format, args)
+}
+
diff --git a/E2Manager/mocks/ricServiceUpdate_manager_mock.go b/E2Manager/mocks/ricServiceUpdate_manager_mock.go
new file mode 100644 (file)
index 0000000..ed3d493
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// Copyright 2023 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.
+//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
+//  platform project (RICP).
+
+package mocks
+
+import (
+       "github.com/stretchr/testify/mock"
+)
+
+
+type RicServiceUpdateManagerMock struct {
+       mock.Mock
+}
+
+func (m *RicServiceUpdateManagerMock) RevertRanFunctions(ranName string) error {
+       args := m.Called(ranName)
+       return args.Error(0)
+}
diff --git a/E2Manager/models/e2_error_indication_message.go b/E2Manager/models/e2_error_indication_message.go
new file mode 100644 (file)
index 0000000..270c3e5
--- /dev/null
@@ -0,0 +1,93 @@
+package models
+
+import (
+       "encoding/xml"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "sync"
+
+)
+
+
+type ProcedureType int
+
+const (
+       E2SetupProcedureNotInitiated ProcedureType = iota
+       E2SetupProcedureOngoing
+       E2SetupProcedureCompleted
+       E2SetupProcedureFailure
+       RicServiceUpdateCompleted
+       RicServiceUpdateFailure
+)
+
+var(
+       ProcedureMap = make(map[string]ProcedureType)
+       procedureMapMutex sync.RWMutex  
+) 
+
+func UpdateProcedureType(ranName string, newProcedureType ProcedureType) {
+       procedureMapMutex.Lock()
+       defer procedureMapMutex.Unlock()
+       ProcedureMap[ranName] = newProcedureType
+}
+
+var ExistingRanFunctiuonsMap = make(map[string][]*entities.RanFunction)
+
+type ErrorIndicationMessage struct {
+       XMLName xml.Name                `xml:"ErrorIndicationMessage"`
+       Text    string                  `xml:",chardata"`
+       E2APPDU ErrorIndicationE2APPDU `xml:"E2AP-PDU"`
+}
+type ErrorIndicationE2APPDU struct {
+       XMLName           xml.Name                          `xml:"E2AP-PDU"`
+       Text              string                            `xml:",chardata"`
+       InitiatingMessage ErrorIndicationInitiatingMessage `xml:"initiatingMessage"`
+}
+type ErrorIndicationInitiatingMessage struct {
+       Text          string `xml:",chardata"`
+       ProcedureCode string `xml:"procedureCode"`
+       Criticality   struct {
+               Text   string `xml:",chardata"`
+               Reject string `xml:"reject"`
+       } `xml:"criticality"`
+       Value struct {
+               Text             string `xml:",chardata"`
+               ErrorIndication struct {
+                       Text        string `xml:",chardata"`
+                       ProtocolIEs struct {
+                               Text                string                `xml:",chardata"`
+                               ErrorIndicationIEs []ErrorIndicationIEs `xml:"ErrorIndication-IEs"`
+                       } `xml:"protocolIEs"`
+               } `xml:"ErrorIndication"`
+       } `xml:"value"`
+}
+type ErrorIndicationIEs struct {
+       Text        string `xml:",chardata"`
+       ID          int    `xml:"id"`
+       Criticality struct {
+               Text   string `xml:",chardata"`
+               Reject string `xml:"reject"`
+       } `xml:"criticality"`
+       Value struct {
+               Text             string `xml:",chardata"`
+               TransactionID    string `xml:"TransactionID"`
+               RICrequestID  struct {
+                       Text           string `xml:",chardata"`
+                       RicRequestorID int32 `xml:"ricRequestorID"`
+                       RicInstanceID  int32 `xml:"ricInstanceID"`
+               } `xml:"RICrequestID"`
+               RANfunctionID     int32 `xml:"RANfunctionID"`
+               CriticalityDiagnostics struct {
+                       Text        string `xml:",chardata"`
+                       ProcedureCode string `xml:"procedureCode"`
+                       TriggeringMessage TriggeringMessage `xml:"triggeringMessage"`
+               } `xml:"CriticalityDiagnostics"`
+       }`xml:"value"`
+}
+
+type TriggeringMessage struct {
+       Text string    `xml:",chardata"`
+       InitiatingMessage  *struct{} `xml:"initiatingMessage"`
+       SuccessfulOutcome *struct{} `xml:"successful-outcome"`
+       UnsuccessfulOutcome  *struct{} `xml:"unsuccessful-outcome"`
+}
+
diff --git a/E2Manager/models/e2_error_indication_message_test.go b/E2Manager/models/e2_error_indication_message_test.go
new file mode 100644 (file)
index 0000000..80b2159
--- /dev/null
@@ -0,0 +1,32 @@
+//
+// Copyright 2023 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.
+
+//  This source code is part of the near-RT RIC (RAN Intelligent Controller)
+//  platform project (RICP).
+package models_test
+
+import (
+       "fmt"
+       "testing"
+       "e2mgr/models"
+
+)
+const RanNameForErrorIndication = "test"
+
+func TestProcedureTypeForErrorIndication(t *testing.T) {
+       models.ProcedureMap[RanNameForErrorIndication] = models.E2SetupProcedureCompleted
+       models.UpdateProcedureType(RanNameForErrorIndication,models.E2SetupProcedureCompleted)
+       fmt.Println("updating the map to E2SetupProcedureCompleted")
+}
index acdd956..fe17e75 100644 (file)
@@ -61,7 +61,7 @@ func (provider *NotificationHandlerProvider) Register(msgType int, handler rmrms
 func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config *configuration.Configuration,
        rnibDataService services.RNibDataService, rmrSender *rmrsender.RmrSender, e2tInstancesManager managers.IE2TInstancesManager,
        routingManagerClient clients.IRoutingManagerClient, e2tAssociationManager *managers.E2TAssociationManager,
-       ranConnectStatusChangeManager managers.IRanConnectStatusChangeManager, ranListManager managers.RanListManager) {
+       ranConnectStatusChangeManager managers.IRanConnectStatusChangeManager, ranListManager managers.RanListManager,RicServiceUpdateManager managers.IRicServiceUpdateManager) {
 
        // Init converters
        x2SetupResponseConverter := converters.NewX2SetupResponseConverter(logger)
@@ -95,9 +95,10 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, e2tInstancesManager, routingManagerClient)
        e2TKeepAliveResponseHandler := rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)
        e2SetupRequestNotificationHandler := rmrmsghandlers.NewE2SetupRequestNotificationHandler(logger, config, e2tInstancesManager, rmrSender, rnibDataService, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
-       ricServiceUpdateHandler := rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager)
+       ricServiceUpdateHandler := rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager, RicServiceUpdateManager)
        ricE2nodeConfigUpdateHandler := rmrmsghandlers.NewE2nodeConfigUpdateNotificationHandler(logger, rnibDataService, rmrSender)
        e2ResetRequestNotificationHandler := rmrmsghandlers.NewE2ResetRequestNotificationHandler(logger, rnibDataService, config, rmrSender, ranResetChangeManager, changeStatusToConnectedRanManager)
+       errorIndicationNotificationHandler := rmrmsghandlers.ErrorIndicationNotificationHandler(logger, ranReconnectionManager, RicServiceUpdateManager)
 
        provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler)
        provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler)
@@ -115,4 +116,5 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        provider.Register(rmrCgo.RIC_SERVICE_UPDATE, ricServiceUpdateHandler)
        provider.Register(rmrCgo.RIC_E2NODE_CONFIG_UPDATE, ricE2nodeConfigUpdateHandler)
        provider.Register(rmrCgo.RIC_E2_RESET_REQ, e2ResetRequestNotificationHandler)
+       provider.Register(rmrCgo.RIC_E2_RIC_ERROR_INDICATION, errorIndicationNotificationHandler)
 }
index 735bc1a..67ff5d2 100644 (file)
@@ -42,7 +42,7 @@ import (
  * Verify support for known providers.
  */
 
-func initTestCase(t *testing.T) (*logger.Logger, *configuration.Configuration, services.RNibDataService, *rmrsender.RmrSender, managers.IE2TInstancesManager, clients.IRoutingManagerClient, *managers.E2TAssociationManager, managers.IRanConnectStatusChangeManager, managers.RanListManager) {
+func initTestCase(t *testing.T) (*logger.Logger, *configuration.Configuration, services.RNibDataService, *rmrsender.RmrSender, managers.IE2TInstancesManager, clients.IRoutingManagerClient, *managers.E2TAssociationManager, managers.IRanConnectStatusChangeManager, managers.RanListManager, managers.IRicServiceUpdateManager) {
        logger := initLog(t)
        config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3, RnibWriter: configuration.RnibWriterConfig{StateChangeMessageChannel: "RAN_CONNECTION_STATUS_CHANGE", RanManipulationMessageChannel: "RAN_MANIPULATION"}}
 
@@ -56,14 +56,15 @@ func initTestCase(t *testing.T) (*logger.Logger, *configuration.Configuration, s
        routingManagerClient := clients.NewRoutingManagerClient(logger, config, httpClient)
        ranListManager := managers.NewRanListManager(logger, rnibDataService)
        ranAlarmService := services.NewRanAlarmService(logger, config)
+       RicServiceUpdateManager := managers.NewRicServiceUpdateManager(logger, rnibDataService)
        ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(logger, rnibDataService, ranListManager, ranAlarmService)
        e2tAssociationManager := managers.NewE2TAssociationManager(logger, rnibDataService, e2tInstancesManager, routingManagerClient, ranConnectStatusChangeManager)
-       return logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager
+       return logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager
 }
 
 func TestGetNotificationHandlerSuccess(t *testing.T) {
 
-       logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager := initTestCase(t)
+       logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager := initTestCase(t)
 
        ranDisconnectionManager := managers.NewRanDisconnectionManager(logger, configuration.ParseConfiguration(), rnibDataService, e2tAssociationManager, ranConnectStatusChangeManager)
        ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
@@ -98,7 +99,7 @@ func TestGetNotificationHandlerSuccess(t *testing.T) {
                {rmrCgo.E2_TERM_KEEP_ALIVE_RESP, rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)},
                {rmrCgo.RIC_X2_RESET_RESP, rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, converters.NewX2ResetResponseExtractor(logger))},
                {rmrCgo.RIC_X2_RESET, rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)},
-               {rmrCgo.RIC_SERVICE_UPDATE, rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager)},
+               {rmrCgo.RIC_SERVICE_UPDATE, rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager, RicServiceUpdateManager)},
                {rmrCgo.RIC_E2NODE_CONFIG_UPDATE, rmrmsghandlers.NewE2nodeConfigUpdateNotificationHandler(logger, rnibDataService, rmrSender)},
                {rmrCgo.RIC_E2_RESET_REQ, rmrmsghandlers.NewE2ResetRequestNotificationHandler(logger, rnibDataService, config, rmrSender, ranResetManager, changeStatusToConnectedRanManager)},
        }
@@ -106,7 +107,7 @@ func TestGetNotificationHandlerSuccess(t *testing.T) {
        for _, tc := range testCases {
 
                provider := NewNotificationHandlerProvider()
-               provider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
+               provider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager)
                t.Run(fmt.Sprintf("%d", tc.msgType), func(t *testing.T) {
                        handler, err := provider.GetNotificationHandler(tc.msgType)
                        if err != nil {
@@ -135,9 +136,9 @@ func TestGetNotificationHandlerFailure(t *testing.T) {
        }
        for _, tc := range testCases {
 
-               logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager := initTestCase(t)
+               logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager := initTestCase(t)
                provider := NewNotificationHandlerProvider()
-               provider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
+               provider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager)
                t.Run(fmt.Sprintf("%d", tc.msgType), func(t *testing.T) {
                        _, err := provider.GetNotificationHandler(tc.msgType)
                        if err == nil {
index 5ec09b9..fc5c849 100644 (file)
@@ -76,6 +76,10 @@ func (ctx *Context) SendMsg(msg *MBuf, printLogs bool) (*MBuf, error) {
 
        currCMBuf := C.rmr_send_msg(ctx.RmrCtx, allocatedCMBuf)
        defer C.rmr_free_msg(currCMBuf)
+       if currCMBuf == nil {
+               errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - currCMBuf is empty hence return from message")
+               return nil, errors.New(errorMessage)
+       }
 
        state = currCMBuf.state
 
index 2b5c31b..47c2b1f 100644 (file)
@@ -89,6 +89,7 @@ const (
        RIC_E2NODE_CONFIG_UPDATE_FAILURE     = C.RIC_E2NODE_CONFIG_UPDATE_FAILURE
        RIC_E2_RESET_REQ                     = C.RIC_E2_RESET_REQ
        RIC_E2_RESET_RESP                    = C.RIC_E2_RESET_RESP
+       RIC_E2_RIC_ERROR_INDICATION          = C.RIC_E2_RIC_ERROR_INDICATION
 )
 
 const (
index 64ff50f..c9d1147 100644 (file)
@@ -63,6 +63,9 @@ func (ctx *Context) getAllocatedCRmrMBuf(logger *logger.Logger, mBuf *MBuf, maxM
        var meidBuf[RMR_MAX_MEID_LEN]byte
 
        cMBuf = C.rmr_alloc_msg(ctx.RmrCtx, C.int(maxMsgSize))
+       if cMBuf == nil {
+               return nil
+       }
        cMBuf.mtype = C.int(mBuf.MType)
        cMBuf.len = C.int(mBuf.Len)
 
index 2b1b38d..21abcfe 100644 (file)
@@ -73,10 +73,11 @@ func initRmrReceiver(logger *logger.Logger) *RmrReceiver {
        routingManagerClient := clients.NewRoutingManagerClient(logger, config, httpClient)
        ranListManager := managers.NewRanListManager(logger, rnibDataService)
        ranAlarmService := services.NewRanAlarmService(logger, config)
+       RicServiceUpdateManager := managers.NewRicServiceUpdateManager(logger, rnibDataService)
        ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(logger, rnibDataService, ranListManager, ranAlarmService)
        e2tAssociationManager := managers.NewE2TAssociationManager(logger, rnibDataService, e2tInstancesManager, routingManagerClient, ranConnectStatusChangeManager)
        rmrNotificationHandlerProvider := rmrmsghandlerprovider.NewNotificationHandlerProvider()
-       rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
+       rmrNotificationHandlerProvider.Init(logger, config, rnibDataService, rmrSender, e2tInstancesManager, routingManagerClient, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager, RicServiceUpdateManager)
        notificationManager := notificationmanager.NewNotificationManager(logger, rmrNotificationHandlerProvider)
        return NewRmrReceiver(logger, rmrMessenger, notificationManager)
 }
diff --git a/E2Manager/tests/resources/errorIndication/errorIndicationForDefault.xml b/E2Manager/tests/resources/errorIndication/errorIndicationForDefault.xml
new file mode 100644 (file)
index 0000000..e2310f6
--- /dev/null
@@ -0,0 +1,56 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>2</procedureCode>
+        <criticality><reject/></criticality>
+        <value>
+            <ErrorIndication>
+                <protocolIEs>
+                    <ErrorIndication-IEs>
+                        <id>49</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <TransactionID>22</TransactionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>29</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RICrequestID>
+                                <ricRequestorID>1</ricRequestorID>
+                                <ricInstanceID>1</ricInstanceID>
+                            </RICrequestID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>5</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RANfunctionID>4</RANfunctionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>1</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <Cause>
+                                <misc><om-intervention/></misc>
+                            </Cause>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>2</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <CriticalityDiagnostics>
+                            <procedureCode>8</procedureCode>
+                            <triggeringMessage><successful-outcome/></triggeringMessage>
+                            <procedureCriticality><reject/></procedureCriticality>
+                            </CriticalityDiagnostics>
+                        </value>
+                    </ErrorIndication-IEs>
+                </protocolIEs>
+            </ErrorIndication>
+        </value>
+    </initiatingMessage>
+</E2AP-PDU>
\ No newline at end of file
diff --git a/E2Manager/tests/resources/errorIndication/errorIndicationForServiceUpdate.xml b/E2Manager/tests/resources/errorIndication/errorIndicationForServiceUpdate.xml
new file mode 100644 (file)
index 0000000..64fedf9
--- /dev/null
@@ -0,0 +1,56 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>2</procedureCode>
+        <criticality><reject/></criticality>
+        <value>
+            <ErrorIndication>
+                <protocolIEs>
+                    <ErrorIndication-IEs>
+                        <id>49</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <TransactionID>22</TransactionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>29</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RICrequestID>
+                                <ricRequestorID>1</ricRequestorID>
+                                <ricInstanceID>1</ricInstanceID>
+                            </RICrequestID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>5</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RANfunctionID>4</RANfunctionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>1</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <Cause>
+                                <misc><om-intervention/></misc>
+                            </Cause>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>2</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <CriticalityDiagnostics>
+                            <procedureCode>7</procedureCode>
+                            <triggeringMessage><successful-outcome/></triggeringMessage>
+                            <procedureCriticality><reject/></procedureCriticality>
+                            </CriticalityDiagnostics>
+                        </value>
+                    </ErrorIndication-IEs>
+                </protocolIEs>
+            </ErrorIndication>
+        </value>
+    </initiatingMessage>
+</E2AP-PDU>
\ No newline at end of file
diff --git a/E2Manager/tests/resources/errorIndication/errorIndicationForSetupRequest.xml b/E2Manager/tests/resources/errorIndication/errorIndicationForSetupRequest.xml
new file mode 100644 (file)
index 0000000..d35237b
--- /dev/null
@@ -0,0 +1,56 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>2</procedureCode>
+        <criticality><reject/></criticality>
+        <value>
+            <ErrorIndication>
+                <protocolIEs>
+                    <ErrorIndication-IEs>
+                        <id>49</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <TransactionID>22</TransactionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>29</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RICrequestID>
+                                <ricRequestorID>1</ricRequestorID>
+                                <ricInstanceID>1</ricInstanceID>
+                            </RICrequestID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>5</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RANfunctionID>4</RANfunctionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>1</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <Cause>
+                                <misc><om-intervention/></misc>
+                            </Cause>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>2</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <CriticalityDiagnostics>
+                            <procedureCode>1</procedureCode>
+                            <triggeringMessage><successful-outcome/></triggeringMessage>
+                            <procedureCriticality><reject/></procedureCriticality>
+                            </CriticalityDiagnostics>
+                        </value>
+                    </ErrorIndication-IEs>
+                </protocolIEs>
+            </ErrorIndication>
+        </value>
+    </initiatingMessage>
+</E2AP-PDU>
\ No newline at end of file
diff --git a/E2Manager/tests/resources/errorIndication/errorIndicationInvalid.xml b/E2Manager/tests/resources/errorIndication/errorIndicationInvalid.xml
new file mode 100644 (file)
index 0000000..f88722c
--- /dev/null
@@ -0,0 +1,55 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>2</procedureCode>
+        <criticality><reject/></criticality>
+        <value>
+            <ErrorIndication>
+                <protocolIEs>
+                    <ErrorIndication-IEs>
+                        <id>49</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <TransactionID>22</TransactionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>29</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RICrequestID>
+                                <ricRequestorID>1</ricRequestorID>
+                                <ricInstanceID>1</ricInstanceID>
+                            </RICrequestID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>5</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RANfunctionID>4</RANfunctionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>1</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <Cause>
+                                <misc><om-intervention/></misc>
+                            </Cause>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>2</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <CriticalityDiagnostics>
+                            <procedureCode>7</procedureCode>
+                            <triggeringMessage><successful-outcome/></triggeringMessage>
+                            <procedureCriticality><reject/></procedureCriticality>
+                            </CriticalityDiagnostics>
+                        </value>
+                    </ErrorIndication-IEs>
+                </protocolIEs>
+            </ErrorIndication>
+        </value>
+    </initiatingMessage>
\ No newline at end of file
diff --git a/E2Manager/tests/resources/errorIndication/errorIndicationUnsuccessfulOutcome.xml b/E2Manager/tests/resources/errorIndication/errorIndicationUnsuccessfulOutcome.xml
new file mode 100644 (file)
index 0000000..c45e110
--- /dev/null
@@ -0,0 +1,56 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>2</procedureCode>
+        <criticality><reject/></criticality>
+        <value>
+            <ErrorIndication>
+                <protocolIEs>
+                    <ErrorIndication-IEs>
+                        <id>49</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <TransactionID>22</TransactionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>29</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RICrequestID>
+                                <ricRequestorID>1</ricRequestorID>
+                                <ricInstanceID>1</ricInstanceID>
+                            </RICrequestID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>5</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RANfunctionID>4</RANfunctionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>1</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <Cause>
+                                <misc><om-intervention/></misc>
+                            </Cause>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>2</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <CriticalityDiagnostics>
+                            <procedureCode>7</procedureCode>
+                            <triggeringMessage><unsuccessful-outcome/></triggeringMessage>
+                            <procedureCriticality><reject/></procedureCriticality>
+                            </CriticalityDiagnostics>
+                        </value>
+                    </ErrorIndication-IEs>
+                </protocolIEs>
+            </ErrorIndication>
+        </value>
+    </initiatingMessage>
+</E2AP-PDU>
\ No newline at end of file
diff --git a/E2Manager/tests/resources/errorIndication/errorIndicationWithoutCD.xml b/E2Manager/tests/resources/errorIndication/errorIndicationWithoutCD.xml
new file mode 100644 (file)
index 0000000..21e422d
--- /dev/null
@@ -0,0 +1,36 @@
+<E2AP-PDU>
+    <initiatingMessage>
+        <procedureCode>2</procedureCode>
+        <criticality><reject/></criticality>
+        <value>
+            <ErrorIndication>
+                <protocolIEs>
+                    <ErrorIndication-IEs>
+                        <id>49</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <TransactionID>22</TransactionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>29</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RICrequestID>
+                                <ricRequestorID>1</ricRequestorID>
+                                <ricInstanceID>1</ricInstanceID>
+                            </RICrequestID>
+                        </value>
+                    </ErrorIndication-IEs>
+                    <ErrorIndication-IEs>
+                        <id>5</id>
+                        <criticality><reject/></criticality>
+                        <value>
+                            <RANfunctionID>4</RANfunctionID>
+                        </value>
+                    </ErrorIndication-IEs>
+                </protocolIEs>
+            </ErrorIndication>
+        </value>
+    </initiatingMessage>
+</E2AP-PDU>
\ No newline at end of file