Support E2 Setup message...<Natalia> 58/2758/1
authoridanshal <idan.shalom@intl.att.com>
Wed, 11 Mar 2020 16:11:02 +0000 (18:11 +0200)
committeridanshal <idan.shalom@intl.att.com>
Wed, 11 Mar 2020 16:11:12 +0000 (18:11 +0200)
Change-Id: I3bb3476065aba70e3aac1fec212003e8c26e680e
Signed-off-by: idanshal <idan.shalom@intl.att.com>
13 files changed:
E2Manager/Dockerfile
E2Manager/go.mod
E2Manager/go.sum
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go [new file with mode: 0644]
E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go [new file with mode: 0644]
E2Manager/handlers/rmrmsghandlers/e2_term_init_notification_handler_test.go
E2Manager/models/e2_setup_request_message.go [new file with mode: 0644]
E2Manager/models/e2_setup_success_response_message.go [new file with mode: 0644]
E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go
E2Manager/rmrCgo/rmrCgoTypes.go
E2Manager/tests/resources/setupRequest_en-gNB.xml [new file with mode: 0644]
E2Manager/tests/resources/setupRequest_gnb.xml [new file with mode: 0644]
E2Manager/tests/resources/setupRequest_ng-eNB.xml [new file with mode: 0644]

index 25a972a..1726158 100644 (file)
@@ -27,10 +27,10 @@ COPY . .
 ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin
 #RUN git clone https://gerrit.o-ran-sc.org/r/ric-plt/lib/rmr && cd rmr/; mkdir build; cd build; /opt/bin/cmake -DDEV_PKG=1 ..; make install
 # Install RMr library and dev files
-RUN wget --content-disposition  https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_1.13.0_amd64.deb/download.deb
-RUN dpkg -i rmr_1.13.0_amd64.deb
-RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_1.13.0_amd64.deb/download.deb
-RUN dpkg -i rmr-dev_1.13.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr_3.3.0_amd64.deb/download.deb
+RUN dpkg -i rmr_3.3.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/staging/packages/debian/stretch/rmr-dev_3.3.0_amd64.deb/download.deb
+RUN dpkg -i rmr-dev_3.3.0_amd64.deb
 
 RUN cd 3rdparty/asn1codec && make
 RUN go build app/main.go
index 8cd3f48..6f2c06e 100644 (file)
@@ -1,9 +1,9 @@
 module e2mgr
 
 require (
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.30
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.30
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.30
+       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.31
+       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.31
+       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.31
        gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.5.2
        github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
        github.com/go-ozzo/ozzo-validation v3.5.0+incompatible
index 1f1691a..50ace17 100644 (file)
@@ -1,10 +1,16 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.30 h1:GuA/5jPx+Srjcs38Bja0392Ht+7ubUOyBbCAp4QRCJY=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.30/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.31 h1:zRZCGfATFQ2VfK4Eh7DaWQn7AgySsUqDheCLx5cfN3U=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.0.31/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.30 h1:MBOyQeDNA+8rs8OSsEIuh7oHhO/5v7ISimd/BMRhLYA=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.30/go.mod h1:Fh23KkroYw5CRBh39WzZzxpKSkpQWL3scdzGnMngLo8=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.31 h1:J5voE21HWJv1lZKJS7Yc+qPSTc3U2g9NRiCVsdTR2KQ=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.0.31/go.mod h1:Fh23KkroYw5CRBh39WzZzxpKSkpQWL3scdzGnMngLo8=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.30 h1:fL5qY6KS5RRxvduCnXeK8fWj7YUF1p9b9ObduFSSlRs=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.30/go.mod h1:HeUXZTDqAaGYiVVcWrHwgY0qDNQ6Rt6nZSvWdMueDNc=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.31 h1:hNK2niv1crecqU44P/gmz/VQSABhVXqkcDlvb62E0jo=
+gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.0.31/go.mod h1:0VWDEhoWG7Zflif7FjVzgomzcnS4TjlYM2l/NzREauY=
 gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.2 h1:UK7awyRKIkVdokWvvkYvazlg3EWIfMnIqCcJxTnLlDA=
 gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.5.2/go.mod h1:y2WhrCvdLkAKdH+ySdHSOSehACJkTMyZghCGVcqoZzc=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler.go
new file mode 100644 (file)
index 0000000..1c5abe7
--- /dev/null
@@ -0,0 +1,147 @@
+package rmrmsghandlers
+
+import (
+       "bytes"
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/models"
+       "e2mgr/rmrCgo"
+       "e2mgr/services"
+       "e2mgr/services/rmrsender"
+       "e2mgr/utils"
+       "encoding/xml"
+       "errors"
+       "fmt"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+)
+
+type E2SetupRequestNotificationHandler struct {
+       logger                 *logger.Logger
+       e2tInstancesManager    managers.IE2TInstancesManager
+       rmrSender              *rmrsender.RmrSender
+       rNibDataService       services.RNibDataService
+       e2tAssociationManager *managers.E2TAssociationManager
+}
+
+func NewE2SetupRequestNotificationHandler(logger *logger.Logger, e2tInstancesManager managers.IE2TInstancesManager, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService, e2tAssociationManager *managers.E2TAssociationManager) E2SetupRequestNotificationHandler {
+       return E2SetupRequestNotificationHandler{
+               logger:                 logger,
+               e2tInstancesManager:    e2tInstancesManager,
+               rmrSender: rmrSender,
+               rNibDataService: rNibDataService,
+               e2tAssociationManager: e2tAssociationManager,
+       }
+}
+
+func (h E2SetupRequestNotificationHandler) Handle(request *models.NotificationRequest){
+       ranName := request.RanName
+       h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - received E2 Setup Request. Payload: %x", ranName, request.Payload)
+
+       setupRequest, e2tIpAddress, err := h.parseSetupRequest(request.Payload)
+       if err != nil {
+               h.logger.Errorf(err.Error())
+               return
+       }
+
+       h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - E2T Address: %s - handling E2_SETUP_REQUEST", e2tIpAddress)
+
+       _, err = h.e2tInstancesManager.GetE2TInstance(e2tIpAddress)
+
+       if err != nil {
+               h.logger.Errorf("#E2TermInitNotificationHandler.Handle - Failed retrieving E2TInstance. error: %s", err)
+               return
+       }
+
+       nodebInfo, err := h.rNibDataService.GetNodeb(ranName)
+       if err != nil{
+               if _, ok := err.(*common.ResourceNotFoundError); ok{
+                       nbIdentity := h.buildNbIdentity(ranName, setupRequest)
+                       nodebInfo = h.buildNodebInfo(ranName, e2tIpAddress, setupRequest)
+                       err = h.rNibDataService.SaveNodeb(nbIdentity, nodebInfo)
+                       if err != nil{
+                               h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to save nodebInfo entity. Error: %s", ranName, err)
+                               return
+                       }
+               } else{
+                       h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to retrieve nodebInfo entity. Error: %s", ranName, err)
+                       return
+               }
+
+       } else {
+               if nodebInfo.ConnectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
+                       h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s, connection status: %s - nodeB entity in incorrect state", nodebInfo.RanName, nodebInfo.ConnectionStatus)
+                       h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - Summary: elapsed time for receiving and handling setup request message from E2 terminator: %f ms", utils.ElapsedTime(request.StartTime))
+                       return
+               }
+               h.updateNodeBFunctions(nodebInfo, setupRequest)
+       }
+       err = h.e2tAssociationManager.AssociateRan(e2tIpAddress, nodebInfo)
+       if err != nil{
+               h.logger.Errorf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - failed to associate E2T to nodeB entity. Error: %s", ranName, err)
+               return
+       }
+       successResponse := &models.E2SetupSuccessResponseMessage{}
+       successResponse.SetPlmnId(setupRequest.GetPlmnId())
+       successResponse.SetNbId("&" + fmt.Sprintf("%020b", 0xf0))
+       responsePayload, err := xml.Marshal(successResponse)
+       if err != nil{
+               h.logger.Warnf("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - Error marshalling E2 Setup Response. Response: %x", ranName, responsePayload)
+       }
+       msg := models.NewRmrMessage(rmrCgo.RIC_E2_SETUP_RESP, ranName, responsePayload, request.TransactionId)
+       h.logger.Infof("#E2SetupRequestNotificationHandler.Handle - RAN name: %s - E2 Setup Request has been built. Message: %x", ranName, msg)
+       //TODO err = h.rmrSender.Send(msg)
+
+}
+
+func (h E2SetupRequestNotificationHandler) parseSetupRequest(payload []byte)(*models.E2SetupRequestMessage, string, error){
+
+       colonInd := bytes.IndexByte(payload, ':')
+       if colonInd < 0 {
+               return nil, "", errors.New("#E2SetupRequestNotificationHandler.parseSetupRequest - Error parsing E2 Setup Request, failed extract E2T IP Address: no ':' separator found")
+       }
+
+       e2tIpAddress := string(payload[:colonInd])
+       if len(e2tIpAddress) == 0 {
+               return nil, "", errors.New("#E2SetupRequestNotificationHandler.parseSetupRequest - Empty E2T Address received")
+       }
+
+       pipInd := bytes.IndexByte(payload, '|')
+       if pipInd < 0 {
+               return nil, "", errors.New( "#E2SetupRequestNotificationHandler.parseSetupRequest - Error parsing E2 Setup Request failed extract Payload: no | separator found")
+       }
+
+       setupRequest := &models.E2SetupRequestMessage{}
+       err := xml.Unmarshal(payload[pipInd + 1:], &setupRequest)
+       if err != nil {
+               return nil, "", errors.New("#E2SetupRequestNotificationHandler.parseSetupRequest - Error unmarshalling E2 Setup Request payload: %s")
+       }
+
+       return setupRequest, e2tIpAddress, nil
+}
+
+func (h E2SetupRequestNotificationHandler) updateNodeBFunctions(nodeB *entities.NodebInfo, request *models.E2SetupRequestMessage){
+       //TODO the function should be implemented in the scope of the US 192 "Save the entire Setup request in RNIB"
+}
+
+func (h E2SetupRequestNotificationHandler) buildNodebInfo(ranName string, e2tAddress string, request *models.E2SetupRequestMessage) *entities.NodebInfo{
+       nodebInfo := &entities.NodebInfo{
+               AssociatedE2TInstanceAddress: e2tAddress,
+               ConnectionStatus: entities.ConnectionStatus_CONNECTED,
+               RanName: ranName,
+               NodeType: entities.Node_GNB,
+               Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
+       }
+       h.updateNodeBFunctions(nodebInfo, request)
+       return nodebInfo
+}
+
+func (h E2SetupRequestNotificationHandler) buildNbIdentity(ranName string, setupRequest *models.E2SetupRequestMessage)*entities.NbIdentity{
+       return &entities.NbIdentity{
+               InventoryName:ranName,
+               GlobalNbId: &entities.GlobalNbId{
+                       PlmnId: setupRequest.GetPlmnId(),
+                       NbId:   setupRequest.GetNbId(),
+               },
+       }
+}
\ No newline at end of file
diff --git a/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go b/E2Manager/handlers/rmrmsghandlers/e2_setup_request_notification_handler_test.go
new file mode 100644 (file)
index 0000000..bd24f17
--- /dev/null
@@ -0,0 +1,505 @@
+package rmrmsghandlers
+
+import (
+       "bytes"
+       "e2mgr/configuration"
+       "e2mgr/logger"
+       "e2mgr/managers"
+       "e2mgr/mocks"
+       "e2mgr/models"
+       "e2mgr/services"
+       "e2mgr/tests"
+       "errors"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/mock"
+       "io"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+       "testing"
+)
+
+const (
+       prefix = "10.0.2.15:9999|"
+       logFilePath = "./loggerTest.txt"
+       e2tInstanceAddress = "10.0.2.15"
+       nodebRanName = "gnb:310-410-b5c67788"
+)
+
+func TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       handler := stubMockSuccessFlowNewNodeb(t)
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)}
+       handler.Handle(notificationRequest)
+       assertSuccessFlowNewNodebLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleNewEnGnbSuccess(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_en-gNB.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlEnGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewEnGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       handler := stubMockSuccessFlowNewNodeb(t)
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlEnGnb...)}
+       handler.Handle(notificationRequest)
+       assertSuccessFlowNewNodebLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleNewNgEnbSuccess(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_ng-eNB.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlEnGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewNgEnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       handler := stubMockSuccessFlowNewNodeb(t)
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlEnGnb...)}
+       handler.Handle(notificationRequest)
+       assertSuccessFlowNewNodebLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleExistingGnbSuccess(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       handler := stubMockSuccessFlowExistingNodeb(t)
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)}
+       handler.Handle(notificationRequest)
+       assertSuccessFlowExistingNodebLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleParseError(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       _, handler, _, _, _, _, _ := initMocks(t)
+       prefBytes := []byte("invalid_prefix")
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)}
+       handler.Handle(notificationRequest)
+       assertParseErrorFlowLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleUnmarshalError(t *testing.T) {
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       _, handler, _, _, _, _, _ := initMocks(t)
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, "xmlGnb"...)}
+       handler.Handle(notificationRequest)
+       assertUnmarshalErrorFlowLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleGetE2TInstanceError(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       _, handler, _, _, _, e2tInstancesManagerMock, _ := initMocks(t)
+       var e2tInstance * entities.E2TInstance
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewResourceNotFoundError("Not found"))
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)}
+       handler.Handle(notificationRequest)
+       assertGetE2TInstanceErrorLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleGetNodebError(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+       _, handler, readerMock, _, _, e2tInstancesManagerMock, _ := initMocks(t)
+       var e2tInstance = &entities.E2TInstance{}
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       var gnb *entities.NodebInfo
+       readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewInternalError(errors.New("Some error")))
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)}
+       handler.Handle(notificationRequest)
+       assertGetNodebErrorLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleAssociationError(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       _, handler, readerMock, writerMock, _, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t)
+       var e2tInstance = &entities.E2TInstance{}
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       var gnb *entities.NodebInfo
+       readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewResourceNotFoundError("Not found"))
+       writerMock.On("SaveNodeb", mock.Anything, mock.Anything).Return(nil)
+       routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceAddress, mock.Anything).Return(errors.New("association error"))
+
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)}
+       handler.Handle(notificationRequest)
+       assertAssociationErrorLogs(t)
+}
+
+func TestE2SetupRequestNotificationHandler_HandleExistingGnbInvalidStatusError(t *testing.T) {
+       path, err :=filepath.Abs("../../tests/resources/setupRequest_gnb.xml")
+       if err != nil {
+               t.Fatal(err)
+       }
+       xmlGnb, err := ioutil.ReadFile(path)
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       logFile, err := os.Create(logFilePath)
+       if err != nil{
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleNewGnbSuccess - failed to create file, error: %s", err)
+       }
+       oldStdout := os.Stdout
+       defer changeStdout(oldStdout)
+       defer removeLogFile(t)
+       os.Stdout = logFile
+
+       handler := stubMockInvalidStatusFlowExistingNodeb(t)
+       prefBytes := []byte(prefix)
+       notificationRequest := &models.NotificationRequest{RanName: nodebRanName, Payload: append(prefBytes, xmlGnb...)}
+       handler.Handle(notificationRequest)
+       assertInvalidNodebStatusLogs(t)
+}
+
+func assertInvalidNodebStatusLogs(t *testing.T){
+       buf := getLogFileBuffer(t)
+       assertReceivedAndParsedLog(buf, t)
+       assertInvalidNodebStatusLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertInvalidNodebStatusLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "#RnibDataService.GetNodeb")
+       assert.Contains(t, record, "connection status: SHUTTING_DOWN")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "#E2SetupRequestNotificationHandler.Handle")
+       assert.Contains(t, record, "connection status: SHUTTING_DOWN - nodeB entity in incorrect state")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "#E2SetupRequestNotificationHandler.Handle")
+       assert.Contains(t, record, "Summary: elapsed time for receiving and handling setup request message from E2 terminator")
+}
+
+func assertAssociationErrorLogs(t *testing.T){
+       buf := getLogFileBuffer(t)
+       assertReceivedAndParsedLog(buf, t)
+       assertNewNodebSavedLog(buf, t)
+       assertAssociationErrorLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertAssociationErrorLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - Associating RAN")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - RoutingManager failure: Failed to associate RAN")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "#E2SetupRequestNotificationHandler.Handle - RAN name:")
+       assert.Contains(t, record, "failed to associate E2T to nodeB entity")
+}
+
+func assertGetNodebErrorLogs(t *testing.T) {
+       buf := getLogFileBuffer(t)
+       assertReceivedAndParsedLog(buf, t)
+       assertGetNodebErrorLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertGetNodebErrorLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "failed to retrieve nodebInfo entity")
+}
+
+func assertGetE2TInstanceErrorLogs(t *testing.T) {
+       buf := getLogFileBuffer(t)
+       assertReceivedAndParsedLog(buf, t)
+       assertGetE2TInstanceErrorLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertGetE2TInstanceErrorLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "Failed retrieving E2TInstance")
+}
+
+func removeLogFile(t *testing.T) {
+       err := os.Remove(logFilePath)
+       if err != nil {
+               t.Errorf("e2_setup_request_notification_handler_test.TestE2SetupRequestNotificationHandler_HandleGnbSuccess - failed to remove file, error: %s", err)
+       }
+}
+
+func assertParseErrorFlowLogs(t *testing.T) {
+       buf := getLogFileBuffer(t)
+       assertReceivedAndFailedParseLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertUnmarshalErrorFlowLogs(t *testing.T) {
+       buf := getLogFileBuffer(t)
+       assertReceivedAndFailedUnmarshalLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertSuccessFlowNewNodebLogs(t *testing.T){
+       buf := getLogFileBuffer(t)
+       assertReceivedAndParsedLog(buf, t)
+       assertNewNodebSavedLog(buf, t)
+       assertAssociatedLog(buf, t)
+       assertRequestBuiltLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertSuccessFlowExistingNodebLogs(t *testing.T){
+       buf := getLogFileBuffer(t)
+       assertReceivedAndParsedLog(buf, t)
+       assertExistingNodebRetrievedLog(buf, t)
+       assertAssociatedLog(buf, t)
+       assertRequestBuiltLog(buf, t)
+       assertNoMoreRecordsLog(buf, t)
+}
+
+func assertReceivedAndParsedLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "received E2 Setup Request")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "handling E2_SETUP_REQUEST")
+}
+
+func assertReceivedAndFailedParseLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "received E2 Setup Request")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "Error parsing E2 Setup Request")
+}
+
+func assertReceivedAndFailedUnmarshalLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "received E2 Setup Request")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "Error unmarshalling E2 Setup Request")
+}
+
+func assertNewNodebSavedLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "#RnibDataService.SaveNodeb - nbIdentity:")
+}
+
+func assertExistingNodebRetrievedLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "#RnibDataService.GetNodeb - RAN name:")
+}
+
+func assertAssociatedLog(buf *bytes.Buffer, t *testing.T){
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - Associating RAN")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "#RnibDataService.UpdateNodebInfo")
+       record, _ = buf.ReadString('\n')
+       assert.Contains(t, record, "#E2TAssociationManager.AssociateRan - successfully associated RAN")
+}
+
+func assertRequestBuiltLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Contains(t, record, "E2 Setup Request has been built")
+}
+
+func assertNoMoreRecordsLog(buf *bytes.Buffer, t *testing.T) {
+       record, _ := buf.ReadString('\n')
+       assert.Empty(t, record)
+}
+
+func stubMockSuccessFlowNewNodeb(t *testing.T) E2SetupRequestNotificationHandler{
+       _, handler, readerMock, writerMock, _, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t)
+       var e2tInstance = &entities.E2TInstance{}
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       var gnb *entities.NodebInfo
+       readerMock.On("GetNodeb", mock.Anything).Return(gnb, common.NewResourceNotFoundError("Not found"))
+       writerMock.On("SaveNodeb", mock.Anything, mock.Anything).Return(nil)
+       routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceAddress, mock.Anything).Return(nil)
+       writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
+       e2tInstancesManagerMock.On("AddRansToInstance", mock.Anything, mock.Anything).Return(nil)
+       return handler
+}
+
+func stubMockSuccessFlowExistingNodeb(t *testing.T) E2SetupRequestNotificationHandler{
+       _, handler, readerMock, writerMock, _, e2tInstancesManagerMock, routingManagerClientMock := initMocks(t)
+       var e2tInstance = &entities.E2TInstance{}
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       var gnb = &entities.NodebInfo{RanName: nodebRanName}
+       readerMock.On("GetNodeb", mock.Anything).Return(gnb, nil)
+       routingManagerClientMock.On("AssociateRanToE2TInstance", e2tInstanceAddress, mock.Anything).Return(nil)
+       writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
+       e2tInstancesManagerMock.On("AddRansToInstance", mock.Anything, mock.Anything).Return(nil)
+       return handler
+}
+
+func stubMockInvalidStatusFlowExistingNodeb(t *testing.T) E2SetupRequestNotificationHandler{
+       _, handler, readerMock, _, _, e2tInstancesManagerMock, _ := initMocks(t)
+       var e2tInstance = &entities.E2TInstance{}
+       e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
+       var gnb = &entities.NodebInfo{RanName: nodebRanName, ConnectionStatus:entities.ConnectionStatus_SHUTTING_DOWN}
+       readerMock.On("GetNodeb", mock.Anything).Return(gnb, nil)
+       return handler
+}
+
+func initMocks(t *testing.T) (*logger.Logger, E2SetupRequestNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock, *mocks.RoutingManagerClientMock) {
+       logger := tests.InitLog(t)
+       config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
+       rmrMessengerMock := &mocks.RmrMessengerMock{}
+       rmrSender := tests.InitRmrSender(rmrMessengerMock, logger)
+       readerMock := &mocks.RnibReaderMock{}
+       writerMock := &mocks.RnibWriterMock{}
+       routingManagerClientMock := &mocks.RoutingManagerClientMock{}
+       rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
+       e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
+       e2tAssociationManager := managers.NewE2TAssociationManager(logger, rnibDataService, e2tInstancesManagerMock, routingManagerClientMock)
+       handler := NewE2SetupRequestNotificationHandler(logger, e2tInstancesManagerMock, rmrSender, rnibDataService, e2tAssociationManager)
+       return logger, handler, readerMock, writerMock, rmrMessengerMock, e2tInstancesManagerMock, routingManagerClientMock
+}
+
+func changeStdout(old *os.File) {
+       os.Stdout = old
+}
+
+func getLogFileBuffer(t *testing.T) *bytes.Buffer {
+       logFile, err := os.Open(logFilePath)
+       if err != nil {
+               t.Errorf("e2_setup_request_notification_handler_test.assertSuccessFlowNewNodebLogRecords - failed to open file, error: %s", err)
+       }
+       var buf bytes.Buffer
+       _, err = io.Copy(&buf, logFile)
+       if err != nil {
+               t.Errorf("e2_setup_request_notification_handler_test.assertSuccessFlowNewNodebLogRecords - failed to copy bytes, error: %s", err)
+       }
+       return &buf
+}
+
index 9a258d0..95b818b 100644 (file)
@@ -42,7 +42,6 @@ import (
        "testing"
 )
 
-const e2tInstanceAddress = "10.0.2.15"
 const e2tInitPayload = "{\"address\":\"10.0.2.15\", \"fqdn\":\"\"}"
 
 func initRanLostConnectionTest(t *testing.T) (*logger.Logger, E2TermInitNotificationHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.E2TInstancesManagerMock, *mocks.RoutingManagerClientMock) {
@@ -96,7 +95,7 @@ func TestE2TermInitUnmarshalPayloadFailure(t *testing.T) {
 }
 
 func TestE2TermInitEmptyE2TAddress(t *testing.T) {
-       _, handler, _, _, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
        notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte("{\"address\":\"\"}")}
        handler.Handle(notificationRequest)
        e2tInstancesManagerMock.AssertNotCalled(t, "GetE2TInstance")
@@ -104,7 +103,7 @@ func TestE2TermInitEmptyE2TAddress(t *testing.T) {
 }
 
 func TestE2TermInitGetE2TInstanceFailure(t *testing.T) {
-       _, handler, _, _, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
        var e2tInstance *entities.E2TInstance
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, common.NewInternalError(fmt.Errorf("internal error")))
        notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
@@ -163,7 +162,7 @@ func TestE2TermInitNewE2TInstance__RoutingManagerError(t *testing.T) {
 }
 
 func TestE2TermInitExistingE2TInstanceNoAssociatedRans(t *testing.T) {
-       _, handler, _, _, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       _, handler, _, _, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
        e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
        notificationRequest := &models.NotificationRequest{RanName: RanName, Payload: []byte(e2tInitPayload)}
@@ -239,7 +238,7 @@ func TestE2TermInitHandlerSuccessOneRan_RoutingManagerError(t *testing.T) {
 }
 
 func TestE2TermInitHandlerSuccessOneRanShuttingdown(t *testing.T) {
-       _, _, handler, readerMock, writerMock,_ := initRanLostConnectionTestWithRealE2tInstanceManager(t)
+       _, _, handler, readerMock, writerMock, _ := initRanLostConnectionTestWithRealE2tInstanceManager(t)
        var rnibErr error
 
        var initialNodeb = &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
@@ -259,7 +258,7 @@ func TestE2TermInitHandlerSuccessOneRanShuttingdown(t *testing.T) {
 }
 
 func TestE2TermInitHandlerSuccessOneRan_ToBeDeleted(t *testing.T) {
-       _, _, handler, readerMock, writerMock, httpClientMock:= initRanLostConnectionTestWithRealE2tInstanceManager(t)
+       _, _, handler, readerMock, writerMock, httpClientMock := initRanLostConnectionTestWithRealE2tInstanceManager(t)
        var rnibErr error
 
        var initialNodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
@@ -299,7 +298,6 @@ func TestE2TermInitHandlerSuccessTwoRans(t *testing.T) {
        var updatedDisconnectedFirstRan = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, RanName: RanName, AssociatedE2TInstanceAddress: ""}
        writerMock.On("UpdateNodebInfo", updatedDisconnectedFirstRan).Return(rnibErr)
 
-
        //Second RAN
        var secondRan = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED, RanName: test2, AssociatedE2TInstanceAddress: "10.0.2.15"}
        var disconnectedSecondRan = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, RanName: test2, AssociatedE2TInstanceAddress: "10.0.2.15"}
@@ -433,7 +431,7 @@ func TestE2TermInitHandlerSuccessTwoRansFirstRnibInternalErrorFailure(t *testing
 }
 
 func TestE2TermInitHandlerSuccessZeroRans(t *testing.T) {
-       _, handler, _, writerMock, e2tInstancesManagerMock, _  := initRanLostConnectionTest(t)
+       _, handler, _, writerMock, e2tInstancesManagerMock, _ := initRanLostConnectionTest(t)
 
        e2tInstance := entities.NewE2TInstance(e2tInstanceAddress)
        e2tInstancesManagerMock.On("GetE2TInstance", e2tInstanceAddress).Return(e2tInstance, nil)
diff --git a/E2Manager/models/e2_setup_request_message.go b/E2Manager/models/e2_setup_request_message.go
new file mode 100644 (file)
index 0000000..63c4a8e
--- /dev/null
@@ -0,0 +1,157 @@
+package models
+
+import (
+       "encoding/xml"
+       "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+)
+
+type E2SetupRequestMessage struct {
+       XMLName xml.Name `xml:"E2SetupRequestMessage"`
+       Text    string   `xml:",chardata"`
+       E2APPDU struct {
+               Text              string `xml:",chardata"`
+               InitiatingMessage 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"`
+                               E2setupRequest struct {
+                                       Text        string `xml:",chardata"`
+                                       ProtocolIEs struct {
+                                               Text              string `xml:",chardata"`
+                                               E2setupRequestIEs []struct {
+                                                       Text        string `xml:",chardata"`
+                                                       ID          string `xml:"id"`
+                                                       Criticality struct {
+                                                               Text   string `xml:",chardata"`
+                                                               Reject string `xml:"reject"`
+                                                       } `xml:"criticality"`
+                                                       Value struct {
+                                                               Text           string `xml:",chardata"`
+                                                               GlobalE2nodeID struct {
+                                                                       Text string `xml:",chardata"`
+                                                                       GNB  struct {
+                                                                               Text        string `xml:",chardata"`
+                                                                               GlobalGNBID struct {
+                                                                                       Text   string `xml:",chardata"`
+                                                                                       PlmnID string `xml:"plmn-id"`
+                                                                                       GnbID  struct {
+                                                                                               Text  string `xml:",chardata"`
+                                                                                               GnbID string `xml:"gnb-ID"`
+                                                                                       } `xml:"gnb-id"`
+                                                                               } `xml:"global-gNB-ID"`
+                                                                       } `xml:"gNB"`
+                                                                       EnGNB struct {
+                                                                               Text        string `xml:",chardata"`
+                                                                               GlobalGNBID struct {
+                                                                                       Text   string `xml:",chardata"`
+                                                                                       PlmnID string `xml:"plmn-id"`
+                                                                                       GnbID  struct {
+                                                                                               Text  string `xml:",chardata"`
+                                                                                               GnbID string `xml:"gnb-ID"`
+                                                                                       } `xml:"gnb-id"`
+                                                                               } `xml:"global-gNB-ID"`
+                                                                       } `xml:"en-gNB"`
+                                                                       NgENB struct {
+                                                                               Text          string `xml:",chardata"`
+                                                                               GlobalNgENBID struct {
+                                                                                       Text   string `xml:",chardata"`
+                                                                                       PlmnID string `xml:"plmn-id"`
+                                                                                       GnbID  struct {
+                                                                                               Text  string `xml:",chardata"`
+                                                                                               GnbID string `xml:"gnb-ID"`
+                                                                                       } `xml:"gnb-id"`
+                                                                               } `xml:"global-ng-eNB-ID"`
+                                                                       } `xml:"ng-eNB"`
+                                                                       ENB struct {
+                                                                               Text        string `xml:",chardata"`
+                                                                               GlobalENBID struct {
+                                                                                       Text   string `xml:",chardata"`
+                                                                                       PlmnID string `xml:"plmn-id"`
+                                                                                       GnbID  struct {
+                                                                                               Text  string `xml:",chardata"`
+                                                                                               GnbID string `xml:"gnb-ID"`
+                                                                                       } `xml:"gnb-id"`
+                                                                               } `xml:"global-eNB-ID"`
+                                                                       } `xml:"eNB"`
+                                                               } `xml:"GlobalE2node-ID"`
+                                                               RANfunctionsList struct {
+                                                                       Text                      string `xml:",chardata"`
+                                                                       ProtocolIESingleContainer []struct {
+                                                                               Text        string `xml:",chardata"`
+                                                                               ID          string `xml:"id"`
+                                                                               Criticality struct {
+                                                                                       Text   string `xml:",chardata"`
+                                                                                       Reject string `xml:"reject"`
+                                                                               } `xml:"criticality"`
+                                                                               Value struct {
+                                                                                       Text            string `xml:",chardata"`
+                                                                                       RANfunctionItem struct {
+                                                                                               Text                  string `xml:",chardata"`
+                                                                                               RanFunctionID         string `xml:"ranFunctionID"`
+                                                                                               RanFunctionDefinition string `xml:"ranFunctionDefinition"`
+                                                                                               RanFunctionRevision   string `xml:"ranFunctionRevision"`
+                                                                                       } `xml:"RANfunction-Item"`
+                                                                               } `xml:"value"`
+                                                                       } `xml:"ProtocolIE-SingleContainer"`
+                                                               } `xml:"RANfunctions-List"`
+                                                       } `xml:"value"`
+                                               } `xml:"E2setupRequestIEs"`
+                                       } `xml:"protocolIEs"`
+                               } `xml:"E2setupRequest"`
+                       } `xml:"value"`
+               } `xml:"initiatingMessage"`
+       } `xml:"E2AP-PDU"`
+}
+
+func (m *E2SetupRequestMessage) GetNodeType() entities.Node_Type{
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.GNB.GlobalGNBID.PlmnID; id!= ""{
+               return entities.Node_GNB
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.EnGNB.GlobalGNBID.PlmnID; id!= ""{
+               return entities.Node_GNB
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.ENB.GlobalENBID.PlmnID; id!= ""{
+               return entities.Node_ENB
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.NgENB.GlobalNgENBID.PlmnID; id!= ""{
+               return entities.Node_GNB
+       }
+       return entities.Node_UNKNOWN
+}
+
+func (m *E2SetupRequestMessage) GetPlmnId() string{
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.GNB.GlobalGNBID.PlmnID; id!= ""{
+               return id
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.EnGNB.GlobalGNBID.PlmnID; id!= ""{
+               return id
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.ENB.GlobalENBID.PlmnID; id!= ""{
+               return id
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.NgENB.GlobalNgENBID.PlmnID; id!= ""{
+               return id
+       }
+       return ""
+}
+
+func (m *E2SetupRequestMessage) GetNbId() string{
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.GNB.GlobalGNBID.GnbID.GnbID; id!= ""{
+               return id
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.EnGNB.GlobalGNBID.GnbID.GnbID; id!= ""{
+               return id
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.ENB.GlobalENBID.GnbID.GnbID; id!= ""{
+               return id
+       }
+       if id := m.E2APPDU.InitiatingMessage.Value.E2setupRequest.ProtocolIEs.E2setupRequestIEs[0].Value.GlobalE2nodeID.NgENB.GlobalNgENBID.GnbID.GnbID; id!= ""{
+               return id
+       }
+       return ""
+}
\ No newline at end of file
diff --git a/E2Manager/models/e2_setup_success_response_message.go b/E2Manager/models/e2_setup_success_response_message.go
new file mode 100644 (file)
index 0000000..f829651
--- /dev/null
@@ -0,0 +1,54 @@
+package models
+import (
+       "encoding/xml"
+)
+
+type E2SetupSuccessResponseMessage struct {
+       XMLName xml.Name `xml:"E2SetupSuccessResponseMessage"`
+       Text    string   `xml:",chardata"`
+       E2APPDU struct {
+               Text              string `xml:",chardata"`
+               SuccessfulOutcome 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"`
+                               E2setupResponse struct {
+                                       Text        string `xml:",chardata"`
+                                       ProtocolIEs struct {
+                                               Text               string `xml:",chardata"`
+                                               E2setupResponseIEs struct {
+                                                       Text        string `xml:",chardata"`
+                                                       ID          string `xml:"id"`
+                                                       Criticality struct {
+                                                               Text   string `xml:",chardata"`
+                                                               Reject string `xml:"reject"`
+                                                       } `xml:"criticality"`
+                                                       Value struct {
+                                                               Text        string `xml:",chardata"`
+                                                               GlobalRICID struct {
+                                                                       Text         string `xml:",chardata"`
+                                                                       PLMNIdentity string `xml:"pLMN-Identity"`
+                                                                       RicID        string `xml:"ric-ID"`
+                                                               } `xml:"GlobalRIC-ID"`
+                                                       } `xml:"value"`
+                                               } `xml:"E2setupResponseIEs"`
+                                       } `xml:"protocolIEs"`
+                               } `xml:"E2setupResponse"`
+                       } `xml:"value"`
+               } `xml:"successfulOutcome"`
+       } `xml:"E2AP-PDU"`
+}
+
+
+func (m *E2SetupSuccessResponseMessage) SetPlmnId(plmnId string){
+       m.E2APPDU.SuccessfulOutcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs.Value.GlobalRICID.PLMNIdentity = plmnId
+}
+
+func (m *E2SetupSuccessResponseMessage) SetNbId(ricID string){
+       m.E2APPDU.SuccessfulOutcome.Value.E2setupResponse.ProtocolIEs.E2setupResponseIEs.Value.GlobalRICID.RicID = ricID
+}
\ No newline at end of file
index 252e047..b161841 100644 (file)
@@ -68,7 +68,7 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        x2ResetResponseExtractor := converters.NewX2ResetResponseExtractor(logger)
 
        // Init managers
-       ranDisconnectionManager := managers.NewRanDisconnectionManager(logger, config, rnibDataService, e2tAssociationManager)
+       ranReconnectionManager := managers.NewRanDisconnectionManager(logger, config, rnibDataService, e2tAssociationManager)
        ranStatusChangeManager := managers.NewRanStatusChangeManager(logger, rmrSender)
        x2SetupResponseManager := managers.NewX2SetupResponseManager(x2SetupResponseConverter)
        x2SetupFailureResponseManager := managers.NewX2SetupFailureResponseManager(x2SetupFailureResponseConverter)
@@ -80,14 +80,15 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        x2SetupFailureResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, x2SetupFailureResponseManager, nil, rmrCgo.RIC_X2_SETUP_FAILURE)
        endcSetupResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupResponseManager, ranStatusChangeManager, rmrCgo.RIC_ENDC_X2_SETUP_RESP)
        endcSetupFailureResponseHandler := rmrmsghandlers.NewSetupResponseNotificationHandler(logger, rnibDataService, endcSetupFailureResponseManager, nil, rmrCgo.RIC_ENDC_X2_SETUP_FAILURE)
-       ranLostConnectionHandler := rmrmsghandlers.NewRanLostConnectionHandler(logger, ranDisconnectionManager)
+       ranLostConnectionHandler := rmrmsghandlers.NewRanLostConnectionHandler(logger, ranReconnectionManager)
        enbLoadInformationNotificationHandler := rmrmsghandlers.NewEnbLoadInformationNotificationHandler(logger, rnibDataService, enbLoadInformationExtractor)
        x2EnbConfigurationUpdateHandler := rmrmsghandlers.NewX2EnbConfigurationUpdateHandler(logger, rmrSender)
        endcConfigurationUpdateHandler := rmrmsghandlers.NewEndcConfigurationUpdateHandler(logger, rmrSender)
        x2ResetResponseHandler := rmrmsghandlers.NewX2ResetResponseHandler(logger, rnibDataService, ranStatusChangeManager, x2ResetResponseExtractor)
        x2ResetRequestNotificationHandler := rmrmsghandlers.NewX2ResetRequestNotificationHandler(logger, rnibDataService, ranStatusChangeManager, rmrSender)
-       e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranDisconnectionManager, e2tInstancesManager, routingManagerClient)
+       e2TermInitNotificationHandler := rmrmsghandlers.NewE2TermInitNotificationHandler(logger, ranReconnectionManager, e2tInstancesManager, routingManagerClient)
        e2TKeepAliveResponseHandler := rmrmsghandlers.NewE2TKeepAliveResponseHandler(logger, rnibDataService, e2tInstancesManager)
+       e2SetupRequestNotificationHandler := rmrmsghandlers.NewE2SetupRequestNotificationHandler(logger, e2tInstancesManager, rmrSender, rnibDataService, e2tAssociationManager)
 
        provider.Register(rmrCgo.RIC_X2_SETUP_RESP, x2SetupResponseHandler)
        provider.Register(rmrCgo.RIC_X2_SETUP_FAILURE, x2SetupFailureResponseHandler)
@@ -101,4 +102,5 @@ func (provider *NotificationHandlerProvider) Init(logger *logger.Logger, config
        provider.Register(rmrCgo.RIC_X2_RESET, x2ResetRequestNotificationHandler)
        provider.Register(rmrCgo.RIC_E2_TERM_INIT, e2TermInitNotificationHandler)
        provider.Register(rmrCgo.E2_TERM_KEEP_ALIVE_RESP, e2TKeepAliveResponseHandler)
+       provider.Register(rmrCgo.RIC_E2_SETUP_REQ, e2SetupRequestNotificationHandler)
 }
index eff707c..4875e1e 100644 (file)
@@ -76,6 +76,9 @@ const (
        RAN_RECONFIGURED                                         = C.RAN_RECONFIGURED
        E2_TERM_KEEP_ALIVE_REQ                           = C.E2_TERM_KEEP_ALIVE_REQ
        E2_TERM_KEEP_ALIVE_RESP                          = C.E2_TERM_KEEP_ALIVE_RESP
+       RIC_E2_SETUP_REQ                                         = C.RIC_E2_SETUP_REQ
+       RIC_E2_SETUP_RESP                    = C.RIC_E2_SETUP_RESP
+       RIC_E2_SETUP_FAILURE                 = C.RIC_E2_SETUP_FAILURE
 )
 
 const (
diff --git a/E2Manager/tests/resources/setupRequest_en-gNB.xml b/E2Manager/tests/resources/setupRequest_en-gNB.xml
new file mode 100644 (file)
index 0000000..95b137a
--- /dev/null
@@ -0,0 +1,62 @@
+<E2SetupRequestMessage>\r
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>1</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <E2setupRequest>\r
+                <protocolIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>3</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <GlobalE2node-ID>\r
+                                <en-gNB>\r
+                                    <global-gNB-ID>\r
+                                        <plmn-id>13 10 14</plmn-id>\r
+                                        <gnb-id>\r
+                                            <gnb-ID>\r
+                                                10110101110001100111011110001000\r
+                                            </gnb-ID>\r
+                                        </gnb-id>\r
+                                    </global-gNB-ID>\r
+                                </en-gNB>\r
+                            </GlobalE2node-ID>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>10</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>1</ranFunctionID>\r
+                                            <ranFunctionDefinition>33 44 55</ranFunctionDefinition>\r
+                                            <ranFunctionRevision>0</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>7</ranFunctionID>\r
+                                            <ranFunctionDefinition>33 44 55</ranFunctionDefinition>\r
+                                            <ranFunctionRevision>0</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                </protocolIEs>\r
+            </E2setupRequest>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
+</E2SetupRequestMessage>
\ No newline at end of file
diff --git a/E2Manager/tests/resources/setupRequest_gnb.xml b/E2Manager/tests/resources/setupRequest_gnb.xml
new file mode 100644 (file)
index 0000000..1a74a2a
--- /dev/null
@@ -0,0 +1,60 @@
+<E2SetupRequestMessage>\r
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>1</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <E2setupRequest>\r
+                <protocolIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>3</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <GlobalE2node-ID>\r
+                                <gNB>\r
+                                    <global-gNB-ID>\r
+                                        <plmn-id>13 10 14</plmn-id>\r
+                                        <gnb-id>\r
+                                            <gnb-ID>10110101110001100111011110001000</gnb-ID>\r
+                                        </gnb-id>\r
+                                    </global-gNB-ID>\r
+                                </gNB>\r
+                            </GlobalE2node-ID>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>10</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>1</ranFunctionID>\r
+                                            <ranFunctionDefinition>33 44 55</ranFunctionDefinition>\r
+                                            <ranFunctionRevision>0</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>7</ranFunctionID>\r
+                                            <ranFunctionDefinition>33 44 55</ranFunctionDefinition>\r
+                                            <ranFunctionRevision>0</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                </protocolIEs>\r
+            </E2setupRequest>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
+</E2SetupRequestMessage>
\ No newline at end of file
diff --git a/E2Manager/tests/resources/setupRequest_ng-eNB.xml b/E2Manager/tests/resources/setupRequest_ng-eNB.xml
new file mode 100644 (file)
index 0000000..c60775c
--- /dev/null
@@ -0,0 +1,60 @@
+<E2SetupRequestMessage>\r
+<E2AP-PDU>\r
+    <initiatingMessage>\r
+        <procedureCode>1</procedureCode>\r
+        <criticality><reject/></criticality>\r
+        <value>\r
+            <E2setupRequest>\r
+                <protocolIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>3</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <GlobalE2node-ID>\r
+                                <ng-eNB>\r
+                                    <global-ng-eNB-ID>\r
+                                        <plmn-id>13 10 14</plmn-id>\r
+                                        <gnb-id>\r
+                                            <gnb-ID>10110101110001100111011110001000</gnb-ID>\r
+                                        </gnb-id>\r
+                                    </global-ng-eNB-ID>\r
+                                </ng-eNB>\r
+                            </GlobalE2node-ID>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                    <E2setupRequestIEs>\r
+                        <id>10</id>\r
+                        <criticality><reject/></criticality>\r
+                        <value>\r
+                            <RANfunctions-List>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>1</ranFunctionID>\r
+                                            <ranFunctionDefinition>33 44 55</ranFunctionDefinition>\r
+                                            <ranFunctionRevision>0</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                                <ProtocolIE-SingleContainer>\r
+                                    <id>8</id>\r
+                                    <criticality><reject/></criticality>\r
+                                    <value>\r
+                                        <RANfunction-Item>\r
+                                            <ranFunctionID>7</ranFunctionID>\r
+                                            <ranFunctionDefinition>33 44 55</ranFunctionDefinition>\r
+                                            <ranFunctionRevision>0</ranFunctionRevision>\r
+                                        </RANfunction-Item>\r
+                                    </value>\r
+                                </ProtocolIE-SingleContainer>\r
+                            </RANfunctions-List>\r
+                        </value>\r
+                    </E2setupRequestIEs>\r
+                </protocolIEs>\r
+            </E2setupRequest>\r
+        </value>\r
+    </initiatingMessage>\r
+</E2AP-PDU>\r
+</E2SetupRequestMessage>
\ No newline at end of file