"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"
)
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()
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)
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()
if !generalConfiguration.EnableRic {
cause := models.Cause{Misc: &models.CauseMisc{OmIntervention: &struct{}{}}}
h.handleUnsuccessfulResponse(ranName, request, cause, setupRequest)
+ models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure)
return
}
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
}
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)
cause := models.Cause{Transport: &models.CauseTransport{TransportResourceUnavailable: &struct{}{}}}
h.handleUnsuccessfulResponse(nodebInfo.RanName, request, cause, setupRequest)
+ models.UpdateProcedureType(ranName, models.E2SetupProcedureFailure)
}
return
}
}
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 {
}
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)
}
}
--- /dev/null
+// 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
--- /dev/null
+// 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(¬ificationRequest)
+ 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)
+}
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,
}
}
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 {
}
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 {
"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 (
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
}
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
}
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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)
+}
--- /dev/null
+//
+// 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)
+}
+
--- /dev/null
+//
+// 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)
+}
--- /dev/null
+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"`
+}
+
--- /dev/null
+//
+// 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")
+}
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)
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)
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)
}
* 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"}}
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)
{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)},
}
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 {
}
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 {
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
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 (
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)
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)
}
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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
--- /dev/null
+<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