First commit
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"e2mgr/clients"
|
||||
"e2mgr/configuration"
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/logger"
|
||||
"e2mgr/managers"
|
||||
"e2mgr/models"
|
||||
"e2mgr/rmrCgo"
|
||||
"e2mgr/services"
|
||||
"e2mgr/services/rmrsender"
|
||||
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
|
||||
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DeleteAllRequestHandler struct {
|
||||
rnibDataService services.RNibDataService
|
||||
rmrSender *rmrsender.RmrSender
|
||||
config *configuration.Configuration
|
||||
logger *logger.Logger
|
||||
e2tInstancesManager managers.IE2TInstancesManager
|
||||
rmClient clients.IRoutingManagerClient
|
||||
}
|
||||
|
||||
const PartialSuccessDueToRmErrorMessage = "Operation succeeded except for routing manager outbound call"
|
||||
|
||||
func NewDeleteAllRequestHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rnibDataService services.RNibDataService, e2tInstancesManager managers.IE2TInstancesManager, rmClient clients.IRoutingManagerClient) *DeleteAllRequestHandler {
|
||||
return &DeleteAllRequestHandler{
|
||||
logger: logger,
|
||||
rnibDataService: rnibDataService,
|
||||
rmrSender: rmrSender,
|
||||
config: config,
|
||||
e2tInstancesManager: e2tInstancesManager,
|
||||
rmClient: rmClient,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *DeleteAllRequestHandler) Handle(request models.Request) (models.IResponse, error) {
|
||||
h.logger.Infof("#DeleteAllRequestHandler.Handle - handling shutdown request")
|
||||
|
||||
e2tAddresses, err := h.e2tInstancesManager.GetE2TAddresses()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(e2tAddresses) == 0 {
|
||||
err, _ = h.updateNodebs(h.updateNodebInfoForceShutdown)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dissocErr := h.rmClient.DissociateAllRans(e2tAddresses)
|
||||
|
||||
if dissocErr != nil {
|
||||
h.logger.Warnf("#DeleteAllRequestHandler.Handle - routing manager failure. continue flow.")
|
||||
}
|
||||
|
||||
err, updatedAtLeastOnce := h.updateNodebs(h.updateNodebInfoShuttingDown)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = h.e2tInstancesManager.ClearRansOfAllE2TInstances()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
|
||||
|
||||
err = h.rmrSender.Send(&rmrMessage)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#DeleteAllRequestHandler.Handle - failed to send sctp clear all message to RMR: %s", err)
|
||||
return nil, e2managererrors.NewRmrError()
|
||||
}
|
||||
|
||||
if !updatedAtLeastOnce {
|
||||
h.logger.Infof("#DeleteAllRequestHandler.Handle - DB wasn't updated, not activating timer")
|
||||
|
||||
if dissocErr != nil {
|
||||
return models.NewRedButtonPartialSuccessResponseModel(PartialSuccessDueToRmErrorMessage), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
time.Sleep(time.Duration(h.config.BigRedButtonTimeoutSec) * time.Second)
|
||||
h.logger.Infof("#DeleteAllRequestHandler.Handle - timer expired")
|
||||
|
||||
err, _ = h.updateNodebs(h.updateNodebInfoShutDown)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dissocErr != nil {
|
||||
return models.NewRedButtonPartialSuccessResponseModel(PartialSuccessDueToRmErrorMessage), nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (h *DeleteAllRequestHandler) updateNodebs(updateCb func(node *entities.NodebInfo) (error, bool)) (error, bool) {
|
||||
nbIdentityList, err := h.rnibDataService.GetListNodebIds()
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#DeleteAllRequestHandler.updateNodebs - failed to get nodes list from rNib. Error: %s", err)
|
||||
return e2managererrors.NewRnibDbError(), false
|
||||
}
|
||||
|
||||
updatedAtLeastOnce := false
|
||||
|
||||
for _, nbIdentity := range nbIdentityList {
|
||||
node, err := h.rnibDataService.GetNodeb(nbIdentity.InventoryName)
|
||||
|
||||
if err != nil {
|
||||
_, ok := err.(*common.ResourceNotFoundError)
|
||||
|
||||
if !ok {
|
||||
h.logger.Errorf("#DeleteAllRequestHandler.updateNodebs - failed to get nodeB entity for ran name: %s from rNib. error: %s", nbIdentity.InventoryName, err)
|
||||
return e2managererrors.NewRnibDbError(), false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err, updated := updateCb(node)
|
||||
|
||||
if err != nil {
|
||||
return err, false
|
||||
}
|
||||
|
||||
if updated {
|
||||
updatedAtLeastOnce = true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, updatedAtLeastOnce
|
||||
}
|
||||
|
||||
func (h *DeleteAllRequestHandler) updateNodebInfoForceShutdown(node *entities.NodebInfo) (error, bool) {
|
||||
err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUT_DOWN, true)
|
||||
|
||||
if err != nil {
|
||||
return err, false
|
||||
}
|
||||
|
||||
return nil, true
|
||||
}
|
||||
|
||||
func (h *DeleteAllRequestHandler) updateNodebInfoShuttingDown(node *entities.NodebInfo) (error, bool) {
|
||||
if node.ConnectionStatus == entities.ConnectionStatus_SHUT_DOWN {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUTTING_DOWN, true)
|
||||
|
||||
if err != nil {
|
||||
return err, false
|
||||
}
|
||||
|
||||
return nil, true
|
||||
}
|
||||
|
||||
func (h *DeleteAllRequestHandler) updateNodebInfoShutDown(node *entities.NodebInfo) (error, bool) {
|
||||
if node.ConnectionStatus == entities.ConnectionStatus_SHUT_DOWN {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
if node.ConnectionStatus != entities.ConnectionStatus_SHUTTING_DOWN {
|
||||
h.logger.Warnf("#DeleteAllRequestHandler.updateNodebInfoShutDown - RAN name: %s - ignore, status is not Shutting Down", node.RanName)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
err := h.updateNodebInfo(node, entities.ConnectionStatus_SHUT_DOWN, false)
|
||||
|
||||
if err != nil {
|
||||
return err, false
|
||||
}
|
||||
|
||||
return nil, true
|
||||
}
|
||||
|
||||
func (h *DeleteAllRequestHandler) updateNodebInfo(node *entities.NodebInfo, connectionStatus entities.ConnectionStatus, resetAssociatedE2TAddress bool) error {
|
||||
node.ConnectionStatus = connectionStatus
|
||||
|
||||
if resetAssociatedE2TAddress {
|
||||
node.AssociatedE2TInstanceAddress = ""
|
||||
}
|
||||
|
||||
err := h.rnibDataService.UpdateNodebInfo(node)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#DeleteAllRequestHandler.updateNodebInfo - RAN name: %s - failed updating nodeB entity in rNib. error: %s", node.RanName, err)
|
||||
return e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
h.logger.Infof("#DeleteAllRequestHandler.updateNodebInfo - RAN name: %s, connection status: %s", node.RanName, connectionStatus)
|
||||
return nil
|
||||
|
||||
}
|
@@ -0,0 +1,473 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"e2mgr/clients"
|
||||
"e2mgr/configuration"
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/logger"
|
||||
"e2mgr/managers"
|
||||
"e2mgr/mocks"
|
||||
"e2mgr/models"
|
||||
"e2mgr/rmrCgo"
|
||||
"e2mgr/services"
|
||||
"e2mgr/services/rmrsender"
|
||||
"e2mgr/tests"
|
||||
"encoding/json"
|
||||
"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/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func setupDeleteAllRequestHandlerTest(t *testing.T) (*DeleteAllRequestHandler, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.HttpClientMock) {
|
||||
log := initLog(t)
|
||||
config := configuration.ParseConfiguration()
|
||||
config.BigRedButtonTimeoutSec = 1
|
||||
config.RoutingManager.BaseUrl = BaseRMUrl
|
||||
|
||||
readerMock := &mocks.RnibReaderMock{}
|
||||
writerMock := &mocks.RnibWriterMock{}
|
||||
rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
|
||||
|
||||
rmrMessengerMock := &mocks.RmrMessengerMock{}
|
||||
rmrSender := getRmrSender(rmrMessengerMock, log)
|
||||
|
||||
e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, log)
|
||||
httpClientMock := &mocks.HttpClientMock{}
|
||||
rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
|
||||
handler := NewDeleteAllRequestHandler(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient)
|
||||
return handler, readerMock, writerMock, rmrMessengerMock, httpClientMock
|
||||
}
|
||||
|
||||
func mapE2TAddressesToE2DataList(e2tAddresses []string) models.RoutingManagerE2TDataList {
|
||||
e2tDataList := make(models.RoutingManagerE2TDataList, len(e2tAddresses))
|
||||
|
||||
for i, v := range e2tAddresses {
|
||||
e2tDataList[i] = models.NewRoutingManagerE2TData(v)
|
||||
}
|
||||
|
||||
return e2tDataList
|
||||
}
|
||||
|
||||
func mockHttpClientDissociateAllRans(httpClientMock *mocks.HttpClientMock, e2tAddresses []string, ok bool) {
|
||||
data := mapE2TAddressesToE2DataList(e2tAddresses)
|
||||
marshaled, _ := json.Marshal(data)
|
||||
body := bytes.NewBuffer(marshaled)
|
||||
url := BaseRMUrl + clients.DissociateRanE2TInstanceApiSuffix
|
||||
respBody := ioutil.NopCloser(bytes.NewBufferString(""))
|
||||
|
||||
var status int
|
||||
if ok {
|
||||
status = http.StatusOK
|
||||
} else {
|
||||
status = http.StatusBadRequest
|
||||
}
|
||||
httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: status, Body: respBody}, nil)
|
||||
}
|
||||
|
||||
func TestGetE2TAddressesFailure(t *testing.T) {
|
||||
h, readerMock, _, _, _ := setupDeleteAllRequestHandlerTest(t)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{}, common.NewInternalError(errors.New("error")))
|
||||
_, err := h.Handle(nil)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestOneRanGetE2TAddressesEmptyList(t *testing.T) {
|
||||
h, readerMock, writerMock, _, _ := setupDeleteAllRequestHandlerTest(t)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{}, nil)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,}
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
_, err := h.Handle(nil)
|
||||
assert.Nil(t, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestTwoRansGetE2TAddressesEmptyListOneGetNodebFailure(t *testing.T) {
|
||||
h, readerMock, writerMock, _, _ := setupDeleteAllRequestHandlerTest(t)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{}, nil)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}, {InventoryName: "RanName_2"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,}
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
var nb2 *entities.NodebInfo
|
||||
readerMock.On("GetNodeb", "RanName_2").Return(nb2, common.NewInternalError(errors.New("error")))
|
||||
_, err := h.Handle(nil)
|
||||
assert.IsType(t,&e2managererrors.RnibDbError{}, err)
|
||||
writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
|
||||
readerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestTwoRansGetE2TAddressesEmptyListOneUpdateNodebInfoFailure(t *testing.T) {
|
||||
h, readerMock, writerMock, _, _ := setupDeleteAllRequestHandlerTest(t)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{}, nil)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}, {InventoryName: "RanName_2"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
|
||||
nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,}
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
|
||||
nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,}
|
||||
readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
|
||||
updatedNb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb2).Return(common.NewInternalError(errors.New("error")))
|
||||
_, err := h.Handle(nil)
|
||||
assert.IsType(t,&e2managererrors.RnibDbError{}, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestOneRanDissociateSucceedsTryShuttingDownFailure(t *testing.T) {
|
||||
h, readerMock, writerMock, _, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
e2tAddresses := []string{E2TAddress}
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, true)
|
||||
nbIdentityList := []*entities.NbIdentity{}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, common.NewInternalError(errors.New("error")))
|
||||
_, err := h.Handle(nil)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestOneRanDissociateFailsTryShuttingDownFailure(t *testing.T) {
|
||||
h, readerMock, writerMock, _, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
e2tAddresses := []string{E2TAddress}
|
||||
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, false)
|
||||
nbIdentityList := []*entities.NbIdentity{}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, common.NewInternalError(errors.New("error")))
|
||||
_, err := h.Handle(nil)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestOneRanTryShuttingDownSucceedsClearFails(t *testing.T) {
|
||||
h, readerMock, writerMock, _, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
e2tAddresses := []string{E2TAddress}
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, true)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
|
||||
readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{}, common.NewInternalError(errors.New("error")))
|
||||
_, err := h.Handle(nil)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestOneRanTryShuttingDownSucceedsClearSucceedsRmrSendFails(t *testing.T) {
|
||||
h, readerMock, writerMock, rmrMessengerMock, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
e2tAddresses := []string{E2TAddress}
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, true)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
|
||||
e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"RanName_1"}}
|
||||
readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{&e2tInstance}, nil)
|
||||
updatedE2tInstance := e2tInstance
|
||||
updatedE2tInstance.AssociatedRanList = []string{}
|
||||
writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
|
||||
|
||||
rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
|
||||
mbuf := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction, rmrMessage.GetMsgSrc())
|
||||
rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, e2managererrors.NewRmrError())
|
||||
_, err := h.Handle(nil)
|
||||
assert.IsType(t, &e2managererrors.RmrError{}, err)
|
||||
rmrMessengerMock.AssertCalled(t, "SendMsg", mbuf, true)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func testTwoRansTryShuttingDownSucceedsClearSucceedsRmrSucceedsAllRansAreShutdown(t *testing.T, partial bool) {
|
||||
h, readerMock, writerMock, rmrMessengerMock, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
e2tAddresses := []string{E2TAddress}
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, !partial)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}, {InventoryName: "RanName_2"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN}
|
||||
nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN}
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
|
||||
e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"RanName_1", "RanName_2"}}
|
||||
readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{&e2tInstance}, nil)
|
||||
updatedE2tInstance := e2tInstance
|
||||
updatedE2tInstance.AssociatedRanList = []string{}
|
||||
writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
|
||||
|
||||
rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
|
||||
mbuf := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction, rmrMessage.GetMsgSrc())
|
||||
rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, nil)
|
||||
resp, err := h.Handle(nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
if partial {
|
||||
assert.IsType(t, &models.RedButtonPartialSuccessResponseModel{}, resp)
|
||||
} else {
|
||||
assert.Nil(t, resp)
|
||||
}
|
||||
|
||||
rmrMessengerMock.AssertCalled(t, "SendMsg", mbuf, true)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestTwoRansTryShuttingDownSucceedsClearSucceedsRmrSucceedsAllRansAreShutdownSuccess(t *testing.T) {
|
||||
testTwoRansTryShuttingDownSucceedsClearSucceedsRmrSucceedsAllRansAreShutdown(t, false)
|
||||
}
|
||||
|
||||
func TestTwoRansTryShuttingDownSucceedsClearSucceedsRmrSucceedsAllRansAreShutdownPartialSuccess(t *testing.T) {
|
||||
testTwoRansTryShuttingDownSucceedsClearSucceedsRmrSucceedsAllRansAreShutdown(t, true)
|
||||
}
|
||||
|
||||
//func TestOneRanTryShuttingDownSucceedsClearSucceedsRmrSucceedsRanStatusIsAlreadyShutdown(t *testing.T) {
|
||||
// h, readerMock, writerMock, rmrMessengerMock, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
// e2tAddresses := []string{E2TAddress}
|
||||
|
||||
// readerMock.On("GetE2TAddresses").Return(e2tAddresses , nil)
|
||||
// mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses ,true)
|
||||
// nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}}
|
||||
// readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
// nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
// readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
// updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
// writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
// readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
|
||||
// e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"RanName_1"}}
|
||||
// readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{&e2tInstance }, nil)
|
||||
// updatedE2tInstance := e2tInstance
|
||||
// updatedE2tInstance.AssociatedRanList = []string{}
|
||||
// writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
|
||||
//
|
||||
// rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
|
||||
// mbuf := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction)
|
||||
// rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, nil)
|
||||
//
|
||||
// readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
// nbAfterTimer := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN,}
|
||||
// readerMock.On("GetNodeb", /*"RanName_1"*/mock.Anything).Return(nbAfterTimer , nil) // Since this is a second call with same arguments we send mock.Anything due to mock limitations
|
||||
// _, err := h.Handle(nil)
|
||||
// assert.Nil(t, err)
|
||||
// rmrMessengerMock.AssertCalled(t, "SendMsg",mbuf, true)
|
||||
// readerMock.AssertExpectations(t)
|
||||
// writerMock.AssertExpectations(t)
|
||||
// writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
|
||||
//}
|
||||
|
||||
//func TestOneRanTryShuttingDownSucceedsClearSucceedsRmrSucceedsRanStatusIsShuttingDownUpdateFailure(t *testing.T) {
|
||||
// h, readerMock, writerMock, rmrMessengerMock, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
// e2tAddresses := []string{E2TAddress}
|
||||
// readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
// mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, true)
|
||||
// nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}}
|
||||
// readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
// //nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
// //readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
// updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
// writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
// readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
|
||||
// e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"RanName_1"}}
|
||||
// readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{&e2tInstance}, nil)
|
||||
// updatedE2tInstance := e2tInstance
|
||||
// updatedE2tInstance.AssociatedRanList = []string{}
|
||||
// writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
|
||||
//
|
||||
// rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
|
||||
// mbuf := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction)
|
||||
// rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, nil)
|
||||
//
|
||||
// readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
// readerMock.On("GetNodeb", "RanName_1").Return(updatedNb1, nil)
|
||||
// updatedNb2 := *updatedNb1
|
||||
// updatedNb2.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
|
||||
// writerMock.On("UpdateNodebInfo", &updatedNb2).Return(common.NewInternalError(errors.New("error")))
|
||||
// _, err := h.Handle(nil)
|
||||
// assert.IsType(t,&e2managererrors.RnibDbError{}, err)
|
||||
// rmrMessengerMock.AssertCalled(t, "SendMsg", mbuf, true)
|
||||
// readerMock.AssertExpectations(t)
|
||||
// writerMock.AssertExpectations(t)
|
||||
//}
|
||||
|
||||
func testOneRanTryShuttingDownSucceedsClearSucceedsRmrSucceedsRanStatusIsShuttingDown(t *testing.T, partial bool) {
|
||||
h, readerMock, writerMock, rmrMessengerMock, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
e2tAddresses := []string{E2TAddress}
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, !partial)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
//nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
//readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
|
||||
e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"RanName_1"}}
|
||||
readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{&e2tInstance}, nil)
|
||||
updatedE2tInstance := e2tInstance
|
||||
updatedE2tInstance.AssociatedRanList = []string{}
|
||||
writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
|
||||
|
||||
rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
|
||||
mbuf := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction, rmrMessage.GetMsgSrc())
|
||||
rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, nil)
|
||||
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(updatedNb1, nil)
|
||||
updatedNb2 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb2).Return(nil)
|
||||
_, err := h.Handle(nil)
|
||||
assert.Nil(t, err)
|
||||
rmrMessengerMock.AssertCalled(t, "SendMsg", mbuf, true)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
|
||||
}
|
||||
|
||||
func TestOneRanTryShuttingDownSucceedsClearSucceedsRmrSucceedsRanStatusIsShuttingDownSuccess (t *testing.T) {
|
||||
testOneRanTryShuttingDownSucceedsClearSucceedsRmrSucceedsRanStatusIsShuttingDown(t, false)
|
||||
}
|
||||
|
||||
func TestOneRanTryShuttingDownSucceedsClearSucceedsRmrSucceedsRanStatusIsShuttingDownPartialSuccess (t *testing.T) {
|
||||
testOneRanTryShuttingDownSucceedsClearSucceedsRmrSucceedsRanStatusIsShuttingDown(t, true)
|
||||
}
|
||||
|
||||
func TestSuccessTwoE2TInstancesSixRans(t *testing.T) {
|
||||
h, readerMock, writerMock, rmrMessengerMock, httpClientMock := setupDeleteAllRequestHandlerTest(t)
|
||||
e2tAddresses := []string{E2TAddress, E2TAddress2}
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
mockHttpClientDissociateAllRans(httpClientMock, e2tAddresses, true)
|
||||
nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1"}, {InventoryName: "RanName_2"}, {InventoryName: "RanName_3"}, {InventoryName: "RanName_4"}, {InventoryName: "RanName_5"}, {InventoryName: "RanName_6"}}
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
//nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
//readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
|
||||
//nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
//readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
|
||||
//nb3 := &entities.NodebInfo{RanName: "RanName_3", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
//readerMock.On("GetNodeb", "RanName_3").Return(nb3, nil)
|
||||
//nb4 := &entities.NodebInfo{RanName: "RanName_4", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress2}
|
||||
//readerMock.On("GetNodeb", "RanName_4").Return(nb4, nil)
|
||||
//nb5 := &entities.NodebInfo{RanName: "RanName_5", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress2}
|
||||
//readerMock.On("GetNodeb", "RanName_5").Return(nb5, nil)
|
||||
//nb6 := &entities.NodebInfo{RanName: "RanName_6", ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: E2TAddress2}
|
||||
//readerMock.On("GetNodeb", "RanName_6").Return(nb6, nil)
|
||||
|
||||
updatedNb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb1).Return(nil)
|
||||
updatedNb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb2).Return(nil)
|
||||
updatedNb3 := &entities.NodebInfo{RanName: "RanName_3", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb3).Return(nil)
|
||||
updatedNb4 := &entities.NodebInfo{RanName: "RanName_4", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb4).Return(nil)
|
||||
updatedNb5 := &entities.NodebInfo{RanName: "RanName_5", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb5).Return(nil)
|
||||
updatedNb6 := &entities.NodebInfo{RanName: "RanName_6", ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
writerMock.On("UpdateNodebInfo", updatedNb6).Return(nil)
|
||||
|
||||
readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"RanName_1", "RanName_2", "RanName_3"}}
|
||||
e2tInstance2 := entities.E2TInstance{Address: E2TAddress2, AssociatedRanList: []string{"RanName_4", "RanName_5", "RanName_6"}}
|
||||
readerMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{&e2tInstance, &e2tInstance2}, nil)
|
||||
updatedE2tInstance := e2tInstance
|
||||
updatedE2tInstance.AssociatedRanList = []string{}
|
||||
updatedE2tInstance2 := e2tInstance2
|
||||
updatedE2tInstance2.AssociatedRanList = []string{}
|
||||
writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
|
||||
writerMock.On("SaveE2TInstance", &updatedE2tInstance2).Return(nil)
|
||||
|
||||
rmrMessage := models.RmrMessage{MsgType: rmrCgo.RIC_SCTP_CLEAR_ALL}
|
||||
mbuf := rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction, rmrMessage.GetMsgSrc())
|
||||
rmrMessengerMock.On("SendMsg", mbuf, true).Return(mbuf, nil)
|
||||
|
||||
readerMock.On("GetListNodebIds").Return(nbIdentityList, nil)
|
||||
readerMock.On("GetNodeb", "RanName_1").Return(updatedNb1, nil)
|
||||
readerMock.On("GetNodeb", "RanName_2").Return(updatedNb2, nil)
|
||||
readerMock.On("GetNodeb", "RanName_3").Return(updatedNb3, nil)
|
||||
readerMock.On("GetNodeb", "RanName_4").Return(updatedNb4, nil)
|
||||
readerMock.On("GetNodeb", "RanName_5").Return(updatedNb5, nil)
|
||||
readerMock.On("GetNodeb", "RanName_6").Return(updatedNb6, nil)
|
||||
|
||||
updatedNb1AfterTimer := *updatedNb1
|
||||
updatedNb1AfterTimer.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb1AfterTimer).Return(nil)
|
||||
updatedNb2AfterTimer := *updatedNb2
|
||||
updatedNb2AfterTimer.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb2AfterTimer).Return(nil)
|
||||
updatedNb3AfterTimer := *updatedNb3
|
||||
updatedNb3AfterTimer.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb3AfterTimer).Return(nil)
|
||||
updatedNb4AfterTimer := *updatedNb4
|
||||
updatedNb4AfterTimer.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb4AfterTimer).Return(nil)
|
||||
updatedNb5AfterTimer := *updatedNb5
|
||||
updatedNb5AfterTimer.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb5AfterTimer).Return(nil)
|
||||
updatedNb6AfterTimer := *updatedNb6
|
||||
updatedNb6AfterTimer.ConnectionStatus = entities.ConnectionStatus_SHUT_DOWN
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb6AfterTimer).Return(nil)
|
||||
_, err := h.Handle(nil)
|
||||
assert.Nil(t, err)
|
||||
rmrMessengerMock.AssertCalled(t, "SendMsg", mbuf, true)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 12)
|
||||
}
|
||||
|
||||
func initLog(t *testing.T) *logger.Logger {
|
||||
log, err := logger.InitLogger(logger.DebugLevel)
|
||||
if err != nil {
|
||||
t.Errorf("#initLog test - failed to initialize logger, error: %s", err)
|
||||
}
|
||||
return log
|
||||
}
|
||||
|
||||
func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
|
||||
rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
|
||||
rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
|
||||
return rmrsender.NewRmrSender(log, rmrMessenger)
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/logger"
|
||||
"e2mgr/managers"
|
||||
"e2mgr/models"
|
||||
)
|
||||
|
||||
type GetE2TInstancesRequestHandler struct {
|
||||
e2tInstancesManager managers.IE2TInstancesManager
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
func NewGetE2TInstancesRequestHandler(logger *logger.Logger, e2tInstancesManager managers.IE2TInstancesManager) *GetE2TInstancesRequestHandler {
|
||||
return &GetE2TInstancesRequestHandler{
|
||||
logger: logger,
|
||||
e2tInstancesManager: e2tInstancesManager,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *GetE2TInstancesRequestHandler) Handle(request models.Request) (models.IResponse, error) {
|
||||
|
||||
e2tInstances, err := h.e2tInstancesManager.GetE2TInstances()
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#GetE2TInstancesRequestHandler.Handle - Error fetching E2T instances from rNib: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mapped := make([]*models.E2TInstanceResponseModel, len(e2tInstances))
|
||||
|
||||
for i, v := range e2tInstances {
|
||||
mapped[i] = models.NewE2TInstanceResponseModel(v.Address, v.AssociatedRanList)
|
||||
}
|
||||
|
||||
return models.E2TInstancesResponse(mapped), nil
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/configuration"
|
||||
"e2mgr/managers"
|
||||
"e2mgr/mocks"
|
||||
"e2mgr/models"
|
||||
"e2mgr/services"
|
||||
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const E2TAddress2 = "10.0.2.15:3213"
|
||||
|
||||
func setupGetE2TInstancesListRequestHandlerTest(t *testing.T) (*GetE2TInstancesRequestHandler, *mocks.RnibReaderMock) {
|
||||
log := initLog(t)
|
||||
config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
|
||||
readerMock := &mocks.RnibReaderMock{}
|
||||
rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
|
||||
e2tInstancesManager := managers.NewE2TInstancesManager(rnibDataService, log)
|
||||
handler := NewGetE2TInstancesRequestHandler(log, e2tInstancesManager)
|
||||
return handler, readerMock
|
||||
}
|
||||
|
||||
func TestGetE2TInstancesFailure(t *testing.T) {
|
||||
handler, rnibReaderMock := setupGetE2TInstancesListRequestHandlerTest(t)
|
||||
rnibReaderMock.On("GetE2TAddresses").Return([]string{}, common.NewInternalError(errors.New("error")))
|
||||
_, err := handler.Handle(nil)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestGetE2TInstancesNoInstances(t *testing.T) {
|
||||
handler, rnibReaderMock := setupGetE2TInstancesListRequestHandlerTest(t)
|
||||
rnibReaderMock.On("GetE2TAddresses").Return([]string{}, nil)
|
||||
resp, err := handler.Handle(nil)
|
||||
assert.Nil(t, err)
|
||||
assert.IsType(t, models.E2TInstancesResponse{}, resp)
|
||||
assert.Len(t, resp, 0)
|
||||
}
|
||||
|
||||
func TestGetE2TInstancesSuccess(t *testing.T) {
|
||||
handler, rnibReaderMock := setupGetE2TInstancesListRequestHandlerTest(t)
|
||||
|
||||
e2tAddresses := []string{E2TAddress, E2TAddress2}
|
||||
rnibReaderMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
|
||||
e2tInstance := entities.E2TInstance{Address: E2TAddress, AssociatedRanList: []string{"test1", "test2"}}
|
||||
e2tInstance2 := entities.E2TInstance{Address: E2TAddress2, AssociatedRanList: []string{"test3", "test4", "test5"}}
|
||||
|
||||
rnibReaderMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{&e2tInstance, &e2tInstance2}, nil)
|
||||
resp, err := handler.Handle(nil)
|
||||
assert.Nil(t, err)
|
||||
assert.IsType(t, models.E2TInstancesResponse{}, resp)
|
||||
assert.Len(t, resp, 2)
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/logger"
|
||||
"e2mgr/models"
|
||||
"e2mgr/services"
|
||||
)
|
||||
|
||||
type GetNodebIdListRequestHandler struct {
|
||||
rNibDataService services.RNibDataService
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
func NewGetNodebIdListRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService) *GetNodebIdListRequestHandler {
|
||||
return &GetNodebIdListRequestHandler{
|
||||
logger: logger,
|
||||
rNibDataService: rNibDataService,
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *GetNodebIdListRequestHandler) Handle(request models.Request) (models.IResponse, error) {
|
||||
|
||||
nodebIdList, err := handler.rNibDataService.GetListNodebIds()
|
||||
|
||||
if err != nil {
|
||||
handler.logger.Errorf("#GetNodebIdListRequestHandler.Handle - Error fetching Nodeb Identity list from rNib: %v", err)
|
||||
return nil, e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
return models.NewGetNodebIdListResponse(nodebIdList), nil
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/configuration"
|
||||
"e2mgr/mocks"
|
||||
"e2mgr/models"
|
||||
"e2mgr/services"
|
||||
"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/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func setupGetNodebIdListRequestHandlerTest(t *testing.T) (*GetNodebIdListRequestHandler, *mocks.RnibReaderMock) {
|
||||
log := initLog(t)
|
||||
config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
|
||||
readerMock := &mocks.RnibReaderMock{}
|
||||
|
||||
rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
|
||||
handler := NewGetNodebIdListRequestHandler(log, rnibDataService)
|
||||
return handler, readerMock
|
||||
}
|
||||
|
||||
func TestHandleGetNodebIdListSuccess(t *testing.T) {
|
||||
handler, readerMock := setupGetNodebIdListRequestHandlerTest(t)
|
||||
var rnibError error
|
||||
readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, rnibError)
|
||||
response, err := handler.Handle(nil)
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, response)
|
||||
assert.IsType(t, &models.GetNodebIdListResponse{}, response)
|
||||
}
|
||||
|
||||
func TestHandleGetNodebIdListFailure(t *testing.T) {
|
||||
handler, readerMock := setupGetNodebIdListRequestHandlerTest(t)
|
||||
var nodebIdList []*entities.NbIdentity
|
||||
readerMock.On("GetListNodebIds").Return(nodebIdList, common.NewInternalError(errors.New("#reader.GetListNodebIds - Internal Error")))
|
||||
response, err := handler.Handle(nil)
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, response)
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/logger"
|
||||
"e2mgr/models"
|
||||
"e2mgr/services"
|
||||
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
|
||||
)
|
||||
|
||||
type GetNodebRequestHandler struct {
|
||||
rNibDataService services.RNibDataService
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
func NewGetNodebRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService) *GetNodebRequestHandler {
|
||||
return &GetNodebRequestHandler{
|
||||
logger: logger,
|
||||
rNibDataService: rNibDataService,
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *GetNodebRequestHandler) Handle(request models.Request) (models.IResponse, error) {
|
||||
getNodebRequest := request.(models.GetNodebRequest)
|
||||
ranName:= getNodebRequest.RanName
|
||||
nodeb, err := handler.rNibDataService.GetNodeb(ranName)
|
||||
|
||||
if err != nil {
|
||||
handler.logger.Errorf("#GetNodebRequestHandler.Handle - RAN name: %s - Error fetching RAN from rNib: %v", ranName, err)
|
||||
return nil, rnibErrorToE2ManagerError(err)
|
||||
}
|
||||
|
||||
return models.NewGetNodebResponse(nodeb), nil
|
||||
}
|
||||
|
||||
func rnibErrorToE2ManagerError(err error) error {
|
||||
_, ok := err.(*common.ResourceNotFoundError)
|
||||
if ok {
|
||||
return e2managererrors.NewResourceNotFoundError()
|
||||
}
|
||||
return e2managererrors.NewRnibDbError()
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/configuration"
|
||||
"e2mgr/mocks"
|
||||
"e2mgr/models"
|
||||
"e2mgr/services"
|
||||
"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/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func setupGetNodebRequestHandlerTest(t *testing.T) (*GetNodebRequestHandler, *mocks.RnibReaderMock) {
|
||||
log := initLog(t)
|
||||
config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
|
||||
readerMock := &mocks.RnibReaderMock{}
|
||||
rnibDataService := services.NewRnibDataService(log, config, readerMock, nil)
|
||||
handler := NewGetNodebRequestHandler(log, rnibDataService)
|
||||
return handler, readerMock
|
||||
}
|
||||
|
||||
func TestHandleGetNodebSuccess(t *testing.T) {
|
||||
handler, readerMock := setupGetNodebRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
var rnibError error
|
||||
readerMock.On("GetNodeb", ranName).Return(&entities.NodebInfo{RanName:ranName}, rnibError)
|
||||
response, err := handler.Handle(models.GetNodebRequest{RanName: ranName})
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, response)
|
||||
assert.IsType(t, &models.GetNodebResponse{}, response)
|
||||
}
|
||||
|
||||
func TestHandleGetNodebFailure(t *testing.T) {
|
||||
handler, readerMock := setupGetNodebRequestHandlerTest(t)
|
||||
ranName := "test1"
|
||||
var nodebInfo *entities.NodebInfo
|
||||
readerMock.On("GetNodeb", ranName).Return(nodebInfo, common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")))
|
||||
response, err := handler.Handle(models.GetNodebRequest{RanName: ranName})
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, response)
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/models"
|
||||
)
|
||||
|
||||
type RequestHandler interface {
|
||||
Handle(request models.Request) (models.IResponse, error)
|
||||
}
|
@@ -0,0 +1,221 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/logger"
|
||||
"e2mgr/managers"
|
||||
"e2mgr/models"
|
||||
"e2mgr/services"
|
||||
"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/go-ozzo/ozzo-validation"
|
||||
"github.com/go-ozzo/ozzo-validation/is"
|
||||
)
|
||||
|
||||
const (
|
||||
X2SetupActivityName = "X2_SETUP"
|
||||
EndcSetupActivityName = "ENDC_SETUP"
|
||||
)
|
||||
|
||||
type SetupRequestHandler struct {
|
||||
rNibDataService services.RNibDataService
|
||||
logger *logger.Logger
|
||||
ranSetupManager managers.IRanSetupManager
|
||||
protocol entities.E2ApplicationProtocol
|
||||
e2tAssociationManager *managers.E2TAssociationManager
|
||||
e2tInstancesManager managers.IE2TInstancesManager
|
||||
}
|
||||
|
||||
func NewSetupRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService,
|
||||
ranSetupManager managers.IRanSetupManager, protocol entities.E2ApplicationProtocol, e2tInstancesManager managers.IE2TInstancesManager, e2tAssociationManager *managers.E2TAssociationManager) *SetupRequestHandler {
|
||||
return &SetupRequestHandler{
|
||||
logger: logger,
|
||||
rNibDataService: rNibDataService,
|
||||
ranSetupManager: ranSetupManager,
|
||||
protocol: protocol,
|
||||
e2tAssociationManager: e2tAssociationManager,
|
||||
e2tInstancesManager: e2tInstancesManager,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SetupRequestHandler) Handle(request models.Request) (models.IResponse, error) {
|
||||
|
||||
setupRequest := request.(models.SetupRequest)
|
||||
|
||||
err := h.validateRequestDetails(setupRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodebInfo, err := h.rNibDataService.GetNodeb(setupRequest.RanName)
|
||||
|
||||
if err != nil {
|
||||
_, ok := err.(*common.ResourceNotFoundError)
|
||||
if !ok {
|
||||
h.logger.Errorf("#SetupRequestHandler.Handle - failed to get nodeB entity for ran name: %v from RNIB. Error: %s", setupRequest.RanName, err)
|
||||
return nil, e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
result := h.connectNewRan(&setupRequest, h.protocol)
|
||||
return nil, result
|
||||
}
|
||||
|
||||
if nodebInfo.ConnectionStatus == entities.ConnectionStatus_SHUTTING_DOWN {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN: %s in wrong state (%s)", nodebInfo.RanName, entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)])
|
||||
result := e2managererrors.NewWrongStateError(h.getActivityName(h.protocol), entities.ConnectionStatus_name[int32(nodebInfo.ConnectionStatus)])
|
||||
return nil, result
|
||||
}
|
||||
|
||||
if len(nodebInfo.AssociatedE2TInstanceAddress) != 0 {
|
||||
result := h.connectExistingRanWithAssociatedE2TAddress(nodebInfo)
|
||||
return nil, result
|
||||
}
|
||||
|
||||
result := h.connectExistingRanWithoutAssociatedE2TAddress(nodebInfo)
|
||||
return nil, result
|
||||
}
|
||||
|
||||
func createInitialNodeInfo(requestDetails *models.SetupRequest, protocol entities.E2ApplicationProtocol) (*entities.NodebInfo, *entities.NbIdentity) {
|
||||
|
||||
nodebInfo := &entities.NodebInfo{
|
||||
Ip: requestDetails.RanIp,
|
||||
Port: uint32(requestDetails.RanPort),
|
||||
ConnectionStatus: entities.ConnectionStatus_CONNECTING,
|
||||
E2ApplicationProtocol: protocol,
|
||||
RanName: requestDetails.RanName,
|
||||
}
|
||||
|
||||
nbIdentity := &entities.NbIdentity{
|
||||
InventoryName: requestDetails.RanName,
|
||||
}
|
||||
|
||||
return nodebInfo, nbIdentity
|
||||
}
|
||||
|
||||
func (h *SetupRequestHandler) connectExistingRanWithoutAssociatedE2TAddress(nodebInfo *entities.NodebInfo) error {
|
||||
e2tAddress, err := h.e2tInstancesManager.SelectE2TInstance()
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed selecting E2T instance", nodebInfo.RanName)
|
||||
|
||||
if nodebInfo.ConnectionStatus == entities.ConnectionStatus_DISCONNECTED{
|
||||
return err
|
||||
}
|
||||
|
||||
nodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
|
||||
updateError := h.rNibDataService.UpdateNodebInfo(nodebInfo)
|
||||
|
||||
if updateError != nil {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed updating nodeb. error: %s", nodebInfo.RanName, updateError)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
err = h.e2tAssociationManager.AssociateRan(e2tAddress, nodebInfo)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - failed associating ran to e2t address %s. error: %s", nodebInfo.RanName, e2tAddress, err)
|
||||
return err
|
||||
}
|
||||
|
||||
h.logger.Infof("#SetupRequestHandler.connectExistingRanWithoutAssociatedE2TAddress - RAN name: %s - successfully updated nodeb in rNib", nodebInfo.RanName)
|
||||
|
||||
result := h.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING)
|
||||
return result
|
||||
}
|
||||
|
||||
func (h *SetupRequestHandler) connectExistingRanWithAssociatedE2TAddress(nodebInfo *entities.NodebInfo) error {
|
||||
status := entities.ConnectionStatus_CONNECTING
|
||||
if nodebInfo.ConnectionStatus == entities.ConnectionStatus_CONNECTED {
|
||||
status = nodebInfo.ConnectionStatus
|
||||
}
|
||||
err := h.rNibDataService.UpdateNodebInfo(nodebInfo)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN name: %s - failed resetting connection attempts of RAN. error: %s", nodebInfo.RanName, err)
|
||||
return e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
h.logger.Infof("#SetupRequestHandler.connectExistingRanWithAssociatedE2TAddress - RAN name: %s - successfully reset connection attempts of RAN", nodebInfo.RanName)
|
||||
|
||||
result := h.ranSetupManager.ExecuteSetup(nodebInfo, status)
|
||||
return result
|
||||
}
|
||||
|
||||
func (h *SetupRequestHandler) connectNewRan(request *models.SetupRequest, protocol entities.E2ApplicationProtocol) error {
|
||||
|
||||
e2tAddress, err := h.e2tInstancesManager.SelectE2TInstance()
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed selecting E2T instance", request.RanName)
|
||||
return err
|
||||
}
|
||||
|
||||
nodebInfo, nodebIdentity := createInitialNodeInfo(request, protocol)
|
||||
|
||||
err = h.rNibDataService.SaveNodeb(nodebIdentity, nodebInfo)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed to save initial nodeb entity in RNIB. error: %s", request.RanName, err)
|
||||
return e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
h.logger.Infof("#SetupRequestHandler.connectNewRan - RAN name: %s - initial nodeb entity was saved to rNib", request.RanName)
|
||||
|
||||
err = h.e2tAssociationManager.AssociateRan(e2tAddress, nodebInfo)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#SetupRequestHandler.connectNewRan - RAN name: %s - failed associating ran to e2t address %s. error: %s", request.RanName, e2tAddress, err)
|
||||
return err
|
||||
}
|
||||
|
||||
result := h.ranSetupManager.ExecuteSetup(nodebInfo, entities.ConnectionStatus_CONNECTING)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (handler *SetupRequestHandler) validateRequestDetails(request models.SetupRequest) error {
|
||||
|
||||
if request.RanPort == 0 {
|
||||
handler.logger.Errorf("#SetupRequestHandler.validateRequestDetails - validation failure: port cannot be zero")
|
||||
return e2managererrors.NewRequestValidationError()
|
||||
}
|
||||
err := validation.ValidateStruct(&request,
|
||||
validation.Field(&request.RanIp, validation.Required, is.IP),
|
||||
validation.Field(&request.RanName, validation.Required),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
handler.logger.Errorf("#SetupRequestHandler.validateRequestDetails - validation failure, error: %v", err)
|
||||
return e2managererrors.NewRequestValidationError()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *SetupRequestHandler) getActivityName(protocol entities.E2ApplicationProtocol) string {
|
||||
if protocol == entities.E2ApplicationProtocol_X2_SETUP_REQUEST {
|
||||
return X2SetupActivityName
|
||||
}
|
||||
return EndcSetupActivityName
|
||||
}
|
@@ -0,0 +1,462 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"e2mgr/clients"
|
||||
"e2mgr/configuration"
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/e2pdus"
|
||||
"e2mgr/managers"
|
||||
"e2mgr/mocks"
|
||||
"e2mgr/models"
|
||||
"e2mgr/rmrCgo"
|
||||
"e2mgr/services"
|
||||
"encoding/json"
|
||||
"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"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const E2TAddress = "10.0.2.15:8989"
|
||||
const RanName = "test"
|
||||
const BaseRMUrl = "http://10.10.2.15:12020/routingmanager"
|
||||
|
||||
func initSetupRequestTest(t *testing.T, protocol entities.E2ApplicationProtocol) (*mocks.RnibReaderMock, *mocks.RnibWriterMock, *SetupRequestHandler, *mocks.E2TInstancesManagerMock, *mocks.RanSetupManagerMock, *mocks.HttpClientMock) {
|
||||
log := initLog(t)
|
||||
config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
|
||||
config.RoutingManager.BaseUrl = BaseRMUrl
|
||||
|
||||
readerMock := &mocks.RnibReaderMock{}
|
||||
writerMock := &mocks.RnibWriterMock{}
|
||||
|
||||
rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
|
||||
|
||||
ranSetupManagerMock := &mocks.RanSetupManagerMock{}
|
||||
e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
|
||||
httpClientMock := &mocks.HttpClientMock{}
|
||||
mockHttpClientAssociateRan(httpClientMock)
|
||||
rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
|
||||
e2tAssociationManager := managers.NewE2TAssociationManager(log, rnibDataService, e2tInstancesManagerMock, rmClient)
|
||||
handler := NewSetupRequestHandler(log, rnibDataService, ranSetupManagerMock, protocol, e2tInstancesManagerMock, e2tAssociationManager)
|
||||
|
||||
return readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, httpClientMock
|
||||
}
|
||||
|
||||
func initSetupRequestTestBasicMocks(t *testing.T, protocol entities.E2ApplicationProtocol) (*mocks.RnibReaderMock, *mocks.RnibWriterMock, *SetupRequestHandler, *mocks.RmrMessengerMock, *mocks.HttpClientMock, *mocks.E2TInstancesManagerMock) {
|
||||
log := initLog(t)
|
||||
config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
|
||||
config.RoutingManager.BaseUrl = BaseRMUrl
|
||||
readerMock := &mocks.RnibReaderMock{}
|
||||
writerMock := &mocks.RnibWriterMock{}
|
||||
|
||||
rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
|
||||
|
||||
rmrMessengerMock := &mocks.RmrMessengerMock{}
|
||||
rmrSender := getRmrSender(rmrMessengerMock, log)
|
||||
ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
|
||||
e2tInstancesManagerMock := &mocks.E2TInstancesManagerMock{}
|
||||
httpClientMock := &mocks.HttpClientMock{}
|
||||
rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
|
||||
e2tAssociationManager := managers.NewE2TAssociationManager(log, rnibDataService, e2tInstancesManagerMock, rmClient)
|
||||
handler := NewSetupRequestHandler(log, rnibDataService, ranSetupManager, protocol, e2tInstancesManagerMock, e2tAssociationManager)
|
||||
|
||||
return readerMock, writerMock, handler, rmrMessengerMock, httpClientMock, e2tInstancesManagerMock
|
||||
}
|
||||
|
||||
func mockHttpClientAssociateRan(httpClientMock *mocks.HttpClientMock) {
|
||||
data := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress, RanName)}
|
||||
marshaled, _ := json.Marshal(data)
|
||||
body := bytes.NewBuffer(marshaled)
|
||||
url := BaseRMUrl + clients.AssociateRanToE2TInstanceApiSuffix
|
||||
respBody := ioutil.NopCloser(bytes.NewBufferString(""))
|
||||
httpClientMock.On("Post", url, "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
|
||||
}
|
||||
|
||||
func TestX2SetupHandleNoPortError(t *testing.T) {
|
||||
readerMock, _, handler, _, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
|
||||
sr := models.SetupRequest{"127.0.0.1", 0, RanName,}
|
||||
_, err := handler.Handle(sr)
|
||||
assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
|
||||
readerMock.AssertNotCalled(t, "GetNodeb")
|
||||
}
|
||||
|
||||
func TestX2SetupHandleNoRanNameError(t *testing.T) {
|
||||
readerMock, _, handler, _, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
|
||||
sr := models.SetupRequest{RanPort: 8080, RanIp: "127.0.0.1"}
|
||||
_, err := handler.Handle(sr)
|
||||
assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
|
||||
readerMock.AssertNotCalled(t, "GetNodeb")
|
||||
}
|
||||
|
||||
func TestX2SetupHandleNoIpError(t *testing.T) {
|
||||
readerMock, _, handler, _, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
|
||||
sr := models.SetupRequest{RanPort: 8080, RanName: RanName}
|
||||
_, err := handler.Handle(sr)
|
||||
assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
|
||||
readerMock.AssertNotCalled(t, "GetNodeb")
|
||||
}
|
||||
|
||||
func TestX2SetupHandleInvalidIpError(t *testing.T) {
|
||||
readerMock, _, handler, _, _, _:= initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
|
||||
sr := models.SetupRequest{RanPort: 8080, RanName: RanName, RanIp: "invalid ip"}
|
||||
_, err := handler.Handle(sr)
|
||||
assert.IsType(t, &e2managererrors.RequestValidationError{}, err)
|
||||
readerMock.AssertNotCalled(t, "GetNodeb")
|
||||
}
|
||||
|
||||
func TestSetupGetNodebFailure(t *testing.T) {
|
||||
readerMock, _, handler, _, _, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
|
||||
rnibErr := &common.ValidationError{}
|
||||
nb := &entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN,}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, rnibErr)
|
||||
|
||||
sr := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
_, err := handler.Handle(sr)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
}
|
||||
|
||||
func TestSetupNewRanSelectE2TInstancesDbError(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return("", e2managererrors.NewRnibDbError())
|
||||
_, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
e2tInstancesManagerMock.AssertNotCalled(t, "AddRansToInstance")
|
||||
writerMock.AssertNotCalled(t, "SaveNodeb")
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
func TestSetupNewRanSelectE2TInstancesNoInstances(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
nodebInfo, _ := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
writerMock.On("SaveNodeb", mock.Anything, mock.Anything).Return(nil)
|
||||
updatedNb := *nodebInfo
|
||||
updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTING).Return(nil)
|
||||
_, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
assert.Nil(t, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
e2tInstancesManagerMock.AssertExpectations(t)
|
||||
ranSetupManagerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestSetupNewRanAssociateRanFailure(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, httpClientMock := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(e2managererrors.NewRnibDbError())
|
||||
setupRequest := &models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
nb, nbIdentity := createInitialNodeInfo(setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
|
||||
writerMock.On("SaveNodeb", nbIdentity, mock.Anything).Return(nil)
|
||||
writerMock.On("UpdateNodebInfo", nb).Return(nil)
|
||||
nb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
mockHttpClientAssociateRan(httpClientMock)
|
||||
updatedNb := *nb
|
||||
updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
|
||||
_, err := handler.Handle(*setupRequest)
|
||||
assert.NotNil(t, err)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
e2tInstancesManagerMock.AssertExpectations(t)
|
||||
ranSetupManagerMock.AssertExpectations(t)
|
||||
httpClientMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestSetupNewRanSaveNodebFailure(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(common.NewInternalError(fmt.Errorf("")))
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
func TestSetupNewRanSetupDbError(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(e2managererrors.NewRnibDbError())
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(nil)
|
||||
updatedNb := *nodebInfo
|
||||
updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.NotNil(t, err)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
readerMock.AssertExpectations(t)
|
||||
writerMock.AssertExpectations(t)
|
||||
ranSetupManagerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestSetupNewRanSetupRmrError(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(nil)
|
||||
updatedNb := *nodebInfo
|
||||
updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTING).Return(e2managererrors.NewRmrError())
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.RmrError{}, err)
|
||||
}
|
||||
|
||||
func TestSetupNewRanSetupSuccess(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError(""))
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
nodebInfo, nbIdentity := createInitialNodeInfo(&setupRequest, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
writerMock.On("SaveNodeb", nbIdentity, nodebInfo).Return(nil)
|
||||
updatedNb := *nodebInfo
|
||||
updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTING).Return(nil)
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestX2SetupExistingRanShuttingDown(t *testing.T) {
|
||||
readerMock, _, handler, e2tInstancesManagerMock, ranSetupManagerMock , _:= initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN}, nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.WrongStateError{}, err)
|
||||
e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
func TestEndcSetupExistingRanShuttingDown(t *testing.T) {
|
||||
readerMock, _, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
|
||||
readerMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{RanName: RanName, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN}, nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.WrongStateError{}, err)
|
||||
e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
func TestSetupExistingRanWithoutAssocE2TInstanceSelectDbError(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return("", e2managererrors.NewRnibDbError())
|
||||
updatedNb := *nb
|
||||
updatedNb.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
func TestSetupExistingRanWithoutAssocE2TInstanceSelectNoInstanceError(t *testing.T) {
|
||||
readerMock, writerMock, handler, rmrMessengerMock, httpClientMock,e2tInstancesManagerMock:= initSetupRequestTestBasicMocks(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
readerMock.On("GetE2TAddresses").Return([]string{}, nil)
|
||||
writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", "10.0.2.15:8989", []string{"test"}).Return(nil)
|
||||
mockHttpClientAssociateRan(httpClientMock)
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.InternalError{}, err)
|
||||
rmrMessengerMock.AssertNotCalled(t, "SendMsg")
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestSetupExistingRanWithoutAssocE2TInstanceSelectNoInstanceErrorUpdateFailure(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return("", e2managererrors.NewE2TInstanceAbsenceError())
|
||||
updatedNb := *nb
|
||||
updatedNb.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(common.NewInternalError(fmt.Errorf("")))
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.E2TInstanceAbsenceError{}, err)
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
func TestSetupExistingRanWithoutAssocE2TInstanceSelectErrorAlreadyDisconnected(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, e2managererrors.NewE2TInstanceAbsenceError())
|
||||
setupRequest := models.SetupRequest{"127.0.0.1", 8080, RanName,}
|
||||
_, err := handler.Handle(setupRequest)
|
||||
assert.IsType(t, &e2managererrors.E2TInstanceAbsenceError{}, err)
|
||||
writerMock.AssertNotCalled(t, "UpdateNodebInfo")
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
//func TestSetupExistingRanWithoutAssocE2TInstanceAssociateRanFailure(t *testing.T) {
|
||||
// readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
// nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
|
||||
// readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
// e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
// e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(e2managererrors.NewRnibDbError())
|
||||
// writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
|
||||
// _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
// assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
// writerMock.AssertNotCalled(t, "UpdateNodebInfo")
|
||||
// ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
//}
|
||||
|
||||
//func TestSetupExistingRanWithoutAssocE2TInstanceAssociateRanSucceedsUpdateNodebFails(t *testing.T) {
|
||||
// readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
// nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
|
||||
// readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
// e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
// e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(nil)
|
||||
// updatedNb := *nb
|
||||
// updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
// writerMock.On("UpdateNodebInfo", &updatedNb).Return(common.NewInternalError(fmt.Errorf("")))
|
||||
// _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
// assert.IsType(t, /* &e2managererrors.RnibDbError{} */&common.InternalError{}, err)
|
||||
// ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
//}
|
||||
|
||||
//func TestSetupExistingRanWithoutAssocE2TInstanceExecuteSetupFailure(t *testing.T) {
|
||||
// readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
// nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
|
||||
// readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
// e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
// e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(nil)
|
||||
// updatedNb := *nb
|
||||
// updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
// writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
// ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTING).Return(e2managererrors.NewRnibDbError())
|
||||
// _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
// assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
//}
|
||||
//
|
||||
//func TestSetupExistingRanWithoutAssocE2TInstanceSuccess(t *testing.T) {
|
||||
// readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
// nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: ""}
|
||||
// readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
// e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
// e2tInstancesManagerMock.On("AddRansToInstance", E2TAddress, []string{RanName}).Return(nil)
|
||||
// updatedNb := *nb
|
||||
// updatedNb.AssociatedE2TInstanceAddress = E2TAddress
|
||||
// writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
// ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTING).Return(nil)
|
||||
// _, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
// assert.Nil(t, err)
|
||||
//}
|
||||
|
||||
func TestSetupExistingRanWithAssocE2TInstanceUpdateNodebFailure(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
updatedNb := *nb
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(common.NewInternalError(fmt.Errorf("")))
|
||||
_, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
assert.IsType(t, &e2managererrors.RnibDbError{}, err)
|
||||
e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
|
||||
e2tInstancesManagerMock.AssertNotCalled(t, "AddRansToInstance")
|
||||
ranSetupManagerMock.AssertNotCalled(t, "ExecuteSetup")
|
||||
}
|
||||
|
||||
func TestSetupExistingRanWithAssocE2TInstanceExecuteSetupRmrError(t *testing.T) {
|
||||
readerMock, writerMock, handler, rmrMessengerMock, _, _ := initSetupRequestTestBasicMocks(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
updatedNb := *nb
|
||||
updatedNb3 := updatedNb
|
||||
updatedNb3.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
payload := e2pdus.PackedX2setupRequest
|
||||
xaction := []byte(RanName)
|
||||
msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), RanName, &payload, &xaction, nil)
|
||||
rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg, e2managererrors.NewRmrError())
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb3).Return(nil)
|
||||
_, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
assert.IsType(t, &e2managererrors.RmrError{}, err)
|
||||
writerMock.AssertExpectations(t)
|
||||
}
|
||||
|
||||
func TestSetupExistingRanWithAssocE2TInstanceConnectedSuccess(t *testing.T) {
|
||||
readerMock, writerMock, handler, e2tInstancesManagerMock, ranSetupManagerMock, _ := initSetupRequestTest(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
updatedNb := *nb
|
||||
writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
|
||||
ranSetupManagerMock.On("ExecuteSetup", &updatedNb, entities.ConnectionStatus_CONNECTED).Return(nil)
|
||||
_, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
assert.Nil(t, err)
|
||||
e2tInstancesManagerMock.AssertNotCalled(t, "SelectE2TInstance")
|
||||
e2tInstancesManagerMock.AssertNotCalled(t, "AddRansToInstance")
|
||||
}
|
||||
|
||||
func TestSetupExistingRanWithoutAssocE2TInstanceExecuteRoutingManagerError(t *testing.T) {
|
||||
readerMock, writerMock, handler, rmrMessengerMock, httpClientMock, e2tInstancesManagerMock := initSetupRequestTestBasicMocks(t, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
|
||||
nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
|
||||
readerMock.On("GetNodeb", RanName).Return(nb, nil)
|
||||
writerMock.On("UpdateNodebInfo", nb).Return(nil)
|
||||
e2tInstancesManagerMock.On("SelectE2TInstance").Return(E2TAddress, nil)
|
||||
mockHttpClientAssociateRan(httpClientMock)
|
||||
e2tInstancesManagerMock.On("AddRansToInstance", mock.Anything, mock.Anything).Return(nil)
|
||||
msg := &rmrCgo.MBuf{}
|
||||
var errNIl error
|
||||
rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg, errNIl)
|
||||
_, err := handler.Handle(models.SetupRequest{"127.0.0.1", 8080, RanName,})
|
||||
assert.Nil(t, err)
|
||||
writerMock.AssertExpectations(t)
|
||||
readerMock.AssertExpectations(t)
|
||||
httpClientMock.AssertExpectations(t)
|
||||
}
|
@@ -0,0 +1,233 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/logger"
|
||||
"e2mgr/models"
|
||||
"e2mgr/services"
|
||||
"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/pkg/errors"
|
||||
)
|
||||
|
||||
const VALIDATION_FAILURE_MESSAGE = "#UpdateGnbRequestHandler.Handle - validation failure: %s is a mandatory field"
|
||||
|
||||
type UpdateGnbRequestHandler struct {
|
||||
logger *logger.Logger
|
||||
rNibDataService services.RNibDataService
|
||||
}
|
||||
|
||||
func NewUpdateGnbRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService) *UpdateGnbRequestHandler {
|
||||
return &UpdateGnbRequestHandler{
|
||||
logger: logger,
|
||||
rNibDataService: rNibDataService,
|
||||
}
|
||||
}
|
||||
|
||||
func (h *UpdateGnbRequestHandler) Handle(request models.Request) (models.IResponse, error) {
|
||||
|
||||
updateGnbRequest := request.(models.UpdateGnbRequest)
|
||||
|
||||
h.logger.Infof("#UpdateGnbRequestHandler.Handle - Ran name: %s", updateGnbRequest.RanName)
|
||||
|
||||
err := h.validateRequestBody(updateGnbRequest)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodebInfo, err := h.rNibDataService.GetNodeb(updateGnbRequest.RanName)
|
||||
|
||||
if err != nil {
|
||||
_, ok := err.(*common.ResourceNotFoundError)
|
||||
if !ok {
|
||||
h.logger.Errorf("#UpdateGnbRequestHandler.Handle - RAN name: %s - failed to get nodeb entity from RNIB. Error: %s", updateGnbRequest.RanName, err)
|
||||
return nil, e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
h.logger.Errorf("#UpdateGnbRequestHandler.Handle - RAN name: %s - RAN not found on RNIB. Error: %s", updateGnbRequest.RanName, err)
|
||||
return nil, e2managererrors.NewResourceNotFoundError()
|
||||
}
|
||||
|
||||
err = h.updateGnbCells(nodebInfo, updateGnbRequest)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return models.NewUpdateGnbResponse(nodebInfo), nil
|
||||
}
|
||||
|
||||
func (h *UpdateGnbRequestHandler) updateGnbCells(nodebInfo *entities.NodebInfo, updateGnbRequest models.UpdateGnbRequest) error {
|
||||
|
||||
ranName := nodebInfo.RanName
|
||||
gnb := nodebInfo.GetGnb()
|
||||
|
||||
if gnb == nil {
|
||||
h.logger.Errorf("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - nodeb missing gnb configuration", ranName)
|
||||
return e2managererrors.NewInternalError()
|
||||
}
|
||||
|
||||
if len(gnb.ServedNrCells) != 0 {
|
||||
err := h.rNibDataService.RemoveServedNrCells(ranName, gnb.ServedNrCells)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - Failed removing served nr cells", ranName)
|
||||
return e2managererrors.NewRnibDbError()
|
||||
}
|
||||
}
|
||||
|
||||
gnb.ServedNrCells = updateGnbRequest.ServedNrCells
|
||||
|
||||
err := h.rNibDataService.UpdateGnbCells(nodebInfo, updateGnbRequest.ServedNrCells)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - Failed updating GNB cells. Error: %s", ranName, err)
|
||||
return e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
h.logger.Infof("#UpdateGnbRequestHandler.updateGnbCells - RAN name: %s - Successfully updated GNB cells", ranName)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *UpdateGnbRequestHandler) validateRequestBody(updateGnbRequest models.UpdateGnbRequest) error {
|
||||
|
||||
if len(updateGnbRequest.ServedNrCells) == 0 {
|
||||
h.logger.Errorf(VALIDATION_FAILURE_MESSAGE+" and cannot be empty", "servedCells")
|
||||
return e2managererrors.NewRequestValidationError()
|
||||
}
|
||||
|
||||
for _, servedNrCell := range updateGnbRequest.ServedNrCells {
|
||||
if servedNrCell.ServedNrCellInformation == nil {
|
||||
h.logger.Errorf(VALIDATION_FAILURE_MESSAGE+" and cannot be empty", "servedNrCellInformation")
|
||||
return e2managererrors.NewRequestValidationError()
|
||||
}
|
||||
|
||||
err := isServedNrCellInformationValid(servedNrCell.ServedNrCellInformation)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf(VALIDATION_FAILURE_MESSAGE, err)
|
||||
return e2managererrors.NewRequestValidationError()
|
||||
}
|
||||
|
||||
if len(servedNrCell.NrNeighbourInfos) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, nrNeighbourInformation := range servedNrCell.NrNeighbourInfos {
|
||||
|
||||
err := isNrNeighbourInformationValid(nrNeighbourInformation)
|
||||
|
||||
if err != nil {
|
||||
h.logger.Errorf(VALIDATION_FAILURE_MESSAGE, err)
|
||||
return e2managererrors.NewRequestValidationError()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isServedNrCellInformationValid(servedNrCellInformation *entities.ServedNRCellInformation) error {
|
||||
if servedNrCellInformation.CellId == "" {
|
||||
return errors.New("cellId")
|
||||
}
|
||||
|
||||
if servedNrCellInformation.ChoiceNrMode == nil {
|
||||
return errors.New("choiceNrMode")
|
||||
}
|
||||
|
||||
if servedNrCellInformation.NrMode == entities.Nr_UNKNOWN {
|
||||
return errors.New("nrMode")
|
||||
}
|
||||
|
||||
if servedNrCellInformation.NrPci == 0 {
|
||||
return errors.New("nrPci")
|
||||
}
|
||||
|
||||
if len(servedNrCellInformation.ServedPlmns) == 0 {
|
||||
return errors.New("servedPlmns")
|
||||
}
|
||||
|
||||
return isServedNrCellInfoChoiceNrModeValid(servedNrCellInformation.ChoiceNrMode)
|
||||
}
|
||||
|
||||
func isServedNrCellInfoChoiceNrModeValid(choiceNrMode *entities.ServedNRCellInformation_ChoiceNRMode) error {
|
||||
if choiceNrMode.Fdd != nil {
|
||||
return isServedNrCellInfoFddValid(choiceNrMode.Fdd)
|
||||
}
|
||||
|
||||
if choiceNrMode.Tdd != nil {
|
||||
return isServedNrCellInfoTddValid(choiceNrMode.Tdd)
|
||||
}
|
||||
|
||||
return errors.New("served nr cell fdd / tdd")
|
||||
}
|
||||
|
||||
func isServedNrCellInfoTddValid(tdd *entities.ServedNRCellInformation_ChoiceNRMode_TddInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func isServedNrCellInfoFddValid(fdd *entities.ServedNRCellInformation_ChoiceNRMode_FddInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func isNrNeighbourInformationValid(nrNeighbourInformation *entities.NrNeighbourInformation) error {
|
||||
if nrNeighbourInformation.NrCgi == "" {
|
||||
return errors.New("nrCgi")
|
||||
}
|
||||
|
||||
if nrNeighbourInformation.ChoiceNrMode == nil {
|
||||
return errors.New("choiceNrMode")
|
||||
}
|
||||
|
||||
if nrNeighbourInformation.NrMode == entities.Nr_UNKNOWN {
|
||||
return errors.New("nrMode")
|
||||
}
|
||||
|
||||
if nrNeighbourInformation.NrPci == 0 {
|
||||
return errors.New("nrPci")
|
||||
}
|
||||
|
||||
return isNrNeighbourInfoChoiceNrModeValid(nrNeighbourInformation.ChoiceNrMode)
|
||||
}
|
||||
|
||||
func isNrNeighbourInfoChoiceNrModeValid(choiceNrMode *entities.NrNeighbourInformation_ChoiceNRMode) error {
|
||||
if choiceNrMode.Fdd != nil {
|
||||
return isNrNeighbourInfoFddValid(choiceNrMode.Fdd)
|
||||
}
|
||||
|
||||
if choiceNrMode.Tdd != nil {
|
||||
return isNrNeighbourInfoTddValid(choiceNrMode.Tdd)
|
||||
}
|
||||
|
||||
return errors.New("nr neighbour fdd / tdd")
|
||||
}
|
||||
|
||||
func isNrNeighbourInfoTddValid(tdd *entities.NrNeighbourInformation_ChoiceNRMode_TddInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func isNrNeighbourInfoFddValid(fdd *entities.NrNeighbourInformation_ChoiceNRMode_FddInfo) error {
|
||||
return nil
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/e2pdus"
|
||||
"e2mgr/logger"
|
||||
"e2mgr/models"
|
||||
"e2mgr/rmrCgo"
|
||||
"e2mgr/services"
|
||||
"e2mgr/services/rmrsender"
|
||||
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
|
||||
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
X2_RESET_ACTIVITY_NAME = "X2_RESET"
|
||||
)
|
||||
|
||||
type X2ResetRequestHandler struct {
|
||||
rNibDataService services.RNibDataService
|
||||
rmrSender *rmrsender.RmrSender
|
||||
logger *logger.Logger
|
||||
}
|
||||
|
||||
func NewX2ResetRequestHandler(logger *logger.Logger, rmrSender *rmrsender.RmrSender, rNibDataService services.RNibDataService) *X2ResetRequestHandler {
|
||||
return &X2ResetRequestHandler{
|
||||
rNibDataService: rNibDataService,
|
||||
rmrSender: rmrSender,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *X2ResetRequestHandler) Handle(request models.Request) (models.IResponse, error) {
|
||||
|
||||
resetRequest := request.(models.ResetRequest)
|
||||
handler.logger.Infof("#X2ResetRequestHandler.Handle - Ran name: %s", resetRequest.RanName)
|
||||
|
||||
if len(resetRequest.Cause) == 0 {
|
||||
resetRequest.Cause = e2pdus.OmInterventionCause
|
||||
}
|
||||
|
||||
payload, ok := e2pdus.KnownCausesToX2ResetPDU(resetRequest.Cause)
|
||||
|
||||
if !ok {
|
||||
handler.logger.Errorf("#X2ResetRequestHandler.Handle - Unknown cause (%s)", resetRequest.Cause)
|
||||
return nil, e2managererrors.NewRequestValidationError()
|
||||
}
|
||||
|
||||
nodeb, err := handler.rNibDataService.GetNodeb(resetRequest.RanName)
|
||||
if err != nil {
|
||||
handler.logger.Errorf("#X2ResetRequestHandler.Handle - failed to get status of RAN: %s from RNIB. Error: %s", resetRequest.RanName, err.Error())
|
||||
_, ok := err.(*common.ResourceNotFoundError)
|
||||
if ok {
|
||||
return nil, e2managererrors.NewResourceNotFoundError()
|
||||
}
|
||||
return nil, e2managererrors.NewRnibDbError()
|
||||
}
|
||||
|
||||
if nodeb.ConnectionStatus != entities.ConnectionStatus_CONNECTED {
|
||||
handler.logger.Errorf("#X2ResetRequestHandler.Handle - RAN: %s in wrong state (%s)", resetRequest.RanName, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
|
||||
return nil, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
|
||||
}
|
||||
|
||||
var xAction []byte
|
||||
var msgSrc unsafe.Pointer
|
||||
msg := models.NewRmrMessage(rmrCgo.RIC_X2_RESET, resetRequest.RanName, payload, xAction, msgSrc)
|
||||
|
||||
err = handler.rmrSender.Send(msg)
|
||||
|
||||
if err != nil {
|
||||
handler.logger.Errorf("#X2ResetRequestHandler.Handle - failed to send reset message to RMR: %s", err)
|
||||
return nil, e2managererrors.NewRmrError()
|
||||
}
|
||||
|
||||
handler.logger.Infof("#X2ResetRequestHandler.Handle - sent x2 reset to RAN: %s with cause: %s", resetRequest.RanName, resetRequest.Cause)
|
||||
|
||||
return nil, nil
|
||||
}
|
@@ -0,0 +1,154 @@
|
||||
//
|
||||
// Copyright 2019 AT&T Intellectual Property
|
||||
// Copyright 2019 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 httpmsghandlers
|
||||
|
||||
import (
|
||||
"e2mgr/configuration"
|
||||
"e2mgr/e2managererrors"
|
||||
"e2mgr/mocks"
|
||||
"e2mgr/models"
|
||||
"e2mgr/rmrCgo"
|
||||
"e2mgr/services"
|
||||
"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"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func setupX2ResetRequestHandlerTest(t *testing.T) (*X2ResetRequestHandler, *mocks.RmrMessengerMock, *mocks.RnibReaderMock) {
|
||||
log := initLog(t)
|
||||
config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
|
||||
readerMock := &mocks.RnibReaderMock{}
|
||||
writerMock := &mocks.RnibWriterMock{}
|
||||
rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
|
||||
rmrMessengerMock := &mocks.RmrMessengerMock{}
|
||||
rmrSender := getRmrSender(rmrMessengerMock, log)
|
||||
handler := NewX2ResetRequestHandler(log, rmrSender, rnibDataService)
|
||||
|
||||
return handler, rmrMessengerMock, readerMock
|
||||
}
|
||||
func TestHandleSuccessfulDefaultCause(t *testing.T) {
|
||||
handler, rmrMessengerMock, readerMock := setupX2ResetRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
// o&m intervention
|
||||
payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
|
||||
var xAction[]byte
|
||||
var msgSrc unsafe.Pointer
|
||||
msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
|
||||
|
||||
rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
|
||||
|
||||
var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
|
||||
readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
|
||||
|
||||
_, actual := handler.Handle(models.ResetRequest{RanName: ranName})
|
||||
|
||||
assert.Nil(t, actual)
|
||||
}
|
||||
|
||||
func TestHandleSuccessfulRequestedCause(t *testing.T) {
|
||||
handler, rmrMessengerMock, readerMock := setupX2ResetRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
|
||||
var xAction[]byte
|
||||
var msgSrc unsafe.Pointer
|
||||
msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
|
||||
rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
|
||||
|
||||
var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
|
||||
readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
|
||||
|
||||
_, actual := handler.Handle(models.ResetRequest{RanName: ranName, Cause: "protocol:transfer-syntax-error"})
|
||||
|
||||
assert.Nil(t, actual)
|
||||
}
|
||||
|
||||
func TestHandleFailureUnknownCause(t *testing.T) {
|
||||
handler, _, readerMock := setupX2ResetRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
|
||||
readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
|
||||
|
||||
_, actual := handler.Handle(models.ResetRequest{RanName: ranName, Cause: "XXX"})
|
||||
|
||||
assert.IsType(t, e2managererrors.NewRequestValidationError(), actual)
|
||||
|
||||
}
|
||||
|
||||
func TestHandleFailureWrongState(t *testing.T) {
|
||||
handler, _, readerMock := setupX2ResetRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
|
||||
readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
|
||||
|
||||
_, actual := handler.Handle(models.ResetRequest{RanName: ranName})
|
||||
|
||||
assert.IsType(t, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]), actual)
|
||||
}
|
||||
|
||||
func TestHandleFailureRanNotFound(t *testing.T) {
|
||||
handler, _, readerMock := setupX2ResetRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
|
||||
readerMock.On("GetNodeb", ranName).Return(&entities.NodebInfo{}, common.NewResourceNotFoundError("nodeb not found"))
|
||||
|
||||
_, actual := handler.Handle(models.ResetRequest{RanName: ranName})
|
||||
|
||||
assert.IsType(t, e2managererrors.NewResourceNotFoundError(), actual)
|
||||
}
|
||||
|
||||
func TestHandleFailureRnibError(t *testing.T) {
|
||||
handler, _, readerMock := setupX2ResetRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
|
||||
readerMock.On("GetNodeb", ranName).Return(&entities.NodebInfo{}, common.NewInternalError(fmt.Errorf("internal error")))
|
||||
|
||||
_, actual := handler.Handle(models.ResetRequest{RanName: ranName})
|
||||
|
||||
assert.IsType(t, e2managererrors.NewRnibDbError(), actual)
|
||||
}
|
||||
|
||||
func TestHandleFailureRmrError(t *testing.T) {
|
||||
handler, rmrMessengerMock, readerMock := setupX2ResetRequestHandlerTest(t)
|
||||
|
||||
ranName := "test1"
|
||||
// o&m intervention
|
||||
payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
|
||||
var xAction[]byte
|
||||
var msgSrc unsafe.Pointer
|
||||
msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
|
||||
rmrMessengerMock.On("SendMsg", msg, true).Return(&rmrCgo.MBuf{}, fmt.Errorf("rmr error"))
|
||||
|
||||
var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
|
||||
readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
|
||||
|
||||
_, actual := handler.Handle(models.ResetRequest{RanName: ranName})
|
||||
|
||||
assert.IsType(t, e2managererrors.NewRmrError(), actual)
|
||||
}
|
Reference in New Issue
Block a user