"e2mgr/configuration"\r
"e2mgr/logger"\r
"e2mgr/models"\r
+ "e2mgr/rmrCgo"\r
"e2mgr/services"\r
+ "e2mgr/services/rmrsender"\r
"e2mgr/utils"\r
+ "encoding/xml"\r
"time"\r
\r
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"\r
\r
const E2ResetRequestLogInfoElapsedTime = "#E2ResetRequestNotificationHandler.Handle - Summary: elapsed time for receiving and handling reset request message from E2 terminator: %f ms"\r
\r
+var (\r
+ resetRequestEmptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "protocolIEs", "procedureCode", "ResetResponse", "ResetResponseIEs", "id", "criticality", "TransactionID"}\r
+)\r
+\r
type E2ResetRequestNotificationHandler struct {\r
logger *logger.Logger\r
rnibDataService services.RNibDataService\r
config *configuration.Configuration\r
+ rmrSender *rmrsender.RmrSender\r
}\r
\r
-func NewE2ResetRequestNotificationHandler(logger *logger.Logger, rnibDataService services.RNibDataService, config *configuration.Configuration) *E2ResetRequestNotificationHandler {\r
+func NewE2ResetRequestNotificationHandler(logger *logger.Logger, rnibDataService services.RNibDataService, config *configuration.Configuration, rmrSender *rmrsender.RmrSender) *E2ResetRequestNotificationHandler {\r
return &E2ResetRequestNotificationHandler{\r
logger: logger,\r
rnibDataService: rnibDataService,\r
config: config,\r
+ rmrSender: rmrSender,\r
}\r
}\r
\r
\r
e.waitfortimertimeout(request)\r
\r
+ ranName := request.RanName\r
+ resetRequest, err := e.parseE2ResetMessage(request.Payload)\r
+ if err != nil {\r
+ e.logger.Errorf(err.Error())\r
+ return\r
+ }\r
+ e.logger.Infof("#E2ResetRequestNotificationHandler.Handle - RIC_RESET_REQUEST has been parsed successfully %+v", resetRequest)\r
+ e.handleSuccessfulResponse(ranName, request, resetRequest)\r
+\r
nodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTED\r
\r
err = e.rnibDataService.UpdateNodebInfoAndPublish(nodebInfo)\r
time.Sleep(time.Duration(timeout/100) * time.Millisecond)\r
}\r
}\r
+\r
+func (e *E2ResetRequestNotificationHandler) parseE2ResetMessage(payload []byte) (*models.E2ResetRequestMessage, error) {\r
+ e2resetMessage := models.E2ResetRequestMessage{}\r
+ err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2resetMessage.E2APPDU))\r
+\r
+ if err != nil {\r
+ e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - error in parsing request message: %+v", err)\r
+ return nil, err\r
+ }\r
+ e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - Unmarshalling is successful %v", e2resetMessage.E2APPDU.InitiatingMessage.ProcedureCode)\r
+ return &e2resetMessage, nil\r
+}\r
+\r
+func (h *E2ResetRequestNotificationHandler) handleSuccessfulResponse(ranName string, req *models.NotificationRequest, resetRequest *models.E2ResetRequestMessage) {\r
+\r
+ successResponse := models.NewE2ResetResponseMessage(resetRequest)\r
+ h.logger.Debugf("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - E2_RESET_RESPONSE has been built successfully %+v", successResponse)\r
+\r
+ responsePayload, err := xml.Marshal(&successResponse.E2ApPdu)\r
+ if err != nil {\r
+ h.logger.Warnf("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - Error marshalling RIC_E2_RESET_RESP. Payload: %s", ranName, responsePayload)\r
+ }\r
+\r
+ responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload, resetRequestEmptyTagsToReplaceToSelfClosingTags)\r
+\r
+ h.logger.Infof("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - payload: %s", responsePayload)\r
+\r
+ msg := models.NewRmrMessage(rmrCgo.RIC_E2_RESET_RESP, ranName, responsePayload, req.TransactionId, req.GetMsgSrc())\r
+ h.logger.Infof("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - RIC_E2_RESET_RESP message has been built successfully. Message: %x", ranName, msg)\r
+ err = h.rmrSender.Send(msg)\r
+ if err != nil {\r
+ h.logger.Errorf("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - Error sending e2 success response %+v", ranName, msg)\r
+ }\r
+}\r
"e2mgr/configuration"\r
"e2mgr/mocks"\r
"e2mgr/models"\r
+ "e2mgr/rmrCgo"\r
+\r
+ // "e2mgr/rmrCgo"\r
"e2mgr/services"\r
"e2mgr/tests"\r
"e2mgr/utils"\r
"testing"\r
\r
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"\r
+ // "github.com/stretchr/testify/assert"\r
"github.com/stretchr/testify/mock"\r
)\r
\r
E2ResetXmlPath = "../../tests/resources/reset/reset-request.xml"\r
)\r
\r
-func initE2ResetMocks(t *testing.T) (*E2ResetRequestNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock) {\r
+func initE2ResetMocks(t *testing.T) (*E2ResetRequestNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock) {\r
logger := tests.InitLog(t)\r
config := &configuration.Configuration{\r
RnibRetryIntervalMs: 10,\r
MaxRnibConnectionAttempts: 3,\r
+ E2ResetTimeOutSec: 10,\r
RnibWriter: configuration.RnibWriterConfig{\r
StateChangeMessageChannel: StateChangeMessageChannel,\r
}}\r
+ rmrMessengerMock := &mocks.RmrMessengerMock{}\r
+ rmrSender := tests.InitRmrSender(rmrMessengerMock, logger)\r
readerMock := &mocks.RnibReaderMock{}\r
writerMock := &mocks.RnibWriterMock{}\r
rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)\r
- handler := NewE2ResetRequestNotificationHandler(logger, rnibDataService, config)\r
- return handler, readerMock, writerMock\r
+ handler := NewE2ResetRequestNotificationHandler(logger, rnibDataService, config, rmrSender)\r
+ return handler, readerMock, writerMock, rmrMessengerMock\r
}\r
\r
-func TestE2ResetRequestHandler(t *testing.T) {\r
+func TestE2ResettNotificationHandler(t *testing.T) {\r
e2ResetXml := utils.ReadXmlFile(t, E2ResetXmlPath)\r
- handler, readerMock, writerMock := initE2ResetMocks(t)\r
+ handler, readerMock, writerMock, rmrMessengerMock := initE2ResetMocks(t)\r
var nodebInfo = &entities.NodebInfo{\r
RanName: gnbNodebRanName,\r
AssociatedE2TInstanceAddress: e2tInstanceFullAddress,\r
}\r
readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil)\r
writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil)\r
+ var errEmpty error\r
+ rmrMessage := &rmrCgo.MBuf{}\r
+ rmrMessengerMock.On("SendMsg", mock.Anything, mock.Anything).Return(rmrMessage, errEmpty)\r
notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(""), e2ResetXml...)}\r
handler.Handle(notificationRequest)\r
readerMock.AssertExpectations(t)\r
writerMock.AssertExpectations(t)\r
+ rmrMessengerMock.AssertNotCalled(t, "SendMsg")\r
+}\r
+\r
+func TestE2ResettNotificationHandler_UpdateStatus_Connected(t *testing.T) {\r
+ e2ResetXml := utils.ReadXmlFile(t, E2ResetXmlPath)\r
+ handler, readerMock, writerMock, rmrMessengerMock := initE2ResetMocks(t)\r
+ var nodebInfo = &entities.NodebInfo{\r
+ RanName: gnbNodebRanName,\r
+ AssociatedE2TInstanceAddress: e2tInstanceFullAddress,\r
+ ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,\r
+ NodeType: entities.Node_GNB,\r
+ Configuration: &entities.NodebInfo_Gnb{\r
+ Gnb: &entities.Gnb{},\r
+ },\r
+ }\r
+ readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil)\r
+ writerMock.On("UpdateNodebInfoAndPublish", mock.Anything).Return(nil)\r
+ nodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTED\r
+ readerMock.On("GetNodeb", gnbNodebRanName).Return(nodebInfo, nil)\r
+\r
+ var errEmpty error\r
+ rmrMessage := &rmrCgo.MBuf{}\r
+ rmrMessengerMock.On("SendMsg", mock.Anything, mock.Anything).Return(rmrMessage, errEmpty)\r
+ notificationRequest := &models.NotificationRequest{RanName: gnbNodebRanName, Payload: append([]byte(""), e2ResetXml...)}\r
+ handler.Handle(notificationRequest)\r
+ readerMock.AssertCalled(t, "GetNodeb", mock.Anything)\r
+ writerMock.AssertCalled(t, "UpdateNodebInfoAndPublish", mock.Anything)\r
+ readerMock.AssertCalled(t, "GetNodeb", mock.Anything)\r
+ rmrMessengerMock.AssertNotCalled(t, "SendMsg")\r
}\r
e2SetupRequestNotificationHandler := rmrmsghandlers.NewE2SetupRequestNotificationHandler(logger, config, e2tInstancesManager, rmrSender, rnibDataService, e2tAssociationManager, ranConnectStatusChangeManager, ranListManager)
ricServiceUpdateHandler := rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager)
ricE2nodeConfigUpdateHandler := rmrmsghandlers.NewE2nodeConfigUpdateNotificationHandler(logger, rnibDataService, rmrSender)
- e2ResetRequestNotificationHandler := rmrmsghandlers.NewE2ResetRequestNotificationHandler(logger, rnibDataService, config)
+ e2ResetRequestNotificationHandler := rmrmsghandlers.NewE2ResetRequestNotificationHandler(logger, rnibDataService, config, rmrSender)
provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler)
provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler)
{rmrCgo.RIC_X2_RESET, rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)},
{rmrCgo.RIC_SERVICE_UPDATE, rmrmsghandlers.NewRicServiceUpdateHandler(logger, rmrSender, rnibDataService, ranListManager)},
{rmrCgo.RIC_E2NODE_CONFIG_UPDATE, rmrmsghandlers.NewE2nodeConfigUpdateNotificationHandler(logger, rnibDataService, rmrSender)},
- {rmrCgo.RIC_E2_RESET_REQ, rmrmsghandlers.NewE2ResetRequestNotificationHandler(logger, rnibDataService, config)},
+ {rmrCgo.RIC_E2_RESET_REQ, rmrmsghandlers.NewE2ResetRequestNotificationHandler(logger, rnibDataService, config, rmrSender)},
}
for _, tc := range testCases {
RIC_E2NODE_CONFIG_UPDATE_ACK = C.RIC_E2NODE_CONFIG_UPDATE_ACK
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
)
const (