"rsm/httpserver"
"rsm/logger"
"rsm/managers/rmrmanagers"
+ "rsm/providers/httpmsghandlerprovider"
"rsm/rmrcgo"
"rsm/rsmdb"
"rsm/services"
defer rmrMessenger.Close()
go rmrReceiver.ListenAndHandle()
- //handlerProvider := httpmsghandlerprovider.NewRequestHandlerProvider(logger, rmrSender, config, rnibDataService)
+ handlerProvider := httpmsghandlerprovider.NewRequestHandlerProvider(logger, rnibDataService, resourceStatusService)
rootController := controllers.NewRootController(rnibDataService)
- //controller := controllers.NewController(logger, handlerProvider)
- _ = httpserver.Run(config.Http.Port, rootController)
-}
+ controller := controllers.NewController(logger, handlerProvider)
+ _ = httpserver.Run(config.Http.Port, rootController, controller)
+}
\ No newline at end of file
package controllers
-type IController interface {
-}
-
-/*
import (
"encoding/json"
"io"
)
type IController interface {
+ ResourceStatus(writer http.ResponseWriter, r *http.Request)
}
type Controller struct {
}
}
+func (c *Controller) ResourceStatus(writer http.ResponseWriter, r *http.Request) {
+ c.logger.Infof("[Client -> RSM] #Controller.ResourceStatus - request: %v", c.prettifyRequest(r))
+
+ request := models.ResourceStatusRequest{}
+
+ if !c.extractJsonBody(r, &request, writer) {
+ return
+ }
+
+ c.handleRequest(writer, &r.Header, httpmsghandlerprovider.ResourceStatusRequest, request, true)
+}
+
func (c *Controller) extractJsonBody(r *http.Request, request models.Request, writer http.ResponseWriter) bool {
defer r.Body.Close()
body, err := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
return
}
- response, err := (*handler).Handle(request)
-
- if err != nil {
- c.handleErrorResponse(err, writer)
- return
- }
-
- if response == nil {
- writer.WriteHeader(http.StatusNoContent)
- c.logger.Infof("[RSM -> Client] #Controller.handleRequest - status response: %v", http.StatusNoContent)
- return
- }
-
- result, err := response.Marshal()
+ err = handler.Handle(request)
if err != nil {
c.handleErrorResponse(err, writer)
return
}
- c.logger.Infof("[RSM -> Client] #Controller.handleRequest - response: %s", result)
- writer.Header().Set("Content-Type", "application/json")
- writer.Write([]byte(result))
+ writer.WriteHeader(http.StatusNoContent)
+ c.logger.Infof("[RSM -> Client] #Controller.handleRequest - status response: %v", http.StatusNoContent)
}
func (c *Controller) validateRequestHeader(header *http.Header) error {
e2Error, _ := err.(*rsmerrors.RmrError)
errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
httpError = http.StatusInternalServerError
+ case *rsmerrors.RsmError:
+ e2Error, _ := err.(*rsmerrors.RsmError)
+ errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
+ httpError = http.StatusInternalServerError
case *rsmerrors.ResourceNotFoundError:
e2Error, _ := err.(*rsmerrors.ResourceNotFoundError)
errorResponseDetails = models.ErrorResponse{Code: e2Error.Code, Message: e2Error.Message}
if err != nil {
c.logger.Errorf("#Controller.handleErrorResponse - Cannot send response. writer:%v", writer)
}
-}*/
-/*
+}
func (c *Controller) prettifyRequest(request *http.Request) string {
dump, _ := httputil.DumpRequest(request, true)
requestPrettyPrint := strings.Replace(string(dump), "\r\n", " ", -1)
return strings.Replace(requestPrettyPrint, "\n", "", -1)
-}
-*/
+}
\ No newline at end of file
package controllers
-/*
import (
"encoding/json"
"fmt"
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"rsm/configuration"
+ "rsm/enums"
+ "rsm/logger"
"rsm/mocks"
"rsm/models"
"rsm/providers/httpmsghandlerprovider"
"rsm/rsmerrors"
- "rsm/tests/testhelper"
+ "rsm/services"
+ "rsm/tests"
+ "strings"
"testing"
)
-func setupControllerTest(t *testing.T) (*Controller, *mocks.RnibReaderMock, *mocks.RmrMessengerMock) {
- config := configuration.ParseConfiguration()
+func setupControllerTest(t *testing.T) (*Controller, *mocks.RnibReaderMock, *mocks.RsmReaderMock, *mocks.RsmWriterMock, *mocks.ResourceStatusServiceMock) {
+ log, err := logger.InitLogger(logger.DebugLevel)
+ if err != nil {
+ t.Errorf("#... - failed to initialize logger, error: %s", err)
+ }
- rmrMessengerMock := &mocks.RmrMessengerMock{}
- readerMock := &mocks.RnibReaderMock{}
- rnibDataService, rmrSender, log := testhelper.InitTestCase(t)
- handlerProvider := httpmsghandlerprovider.NewRequestHandlerProvider(log, rmrSender, config, rnibDataService)
+ config, err := configuration.ParseConfiguration()
+ if err != nil {
+ t.Errorf("#... - failed to parse configuration error: %s", err)
+ }
+
+ resourceStatusServiceMock := &mocks.ResourceStatusServiceMock{}
+ rnibReaderMock := &mocks.RnibReaderMock{}
+ rsmReaderMock := &mocks.RsmReaderMock{}
+ rsmWriterMock := &mocks.RsmWriterMock{}
+
+ rnibDataService := services.NewRnibDataService(log, config, rnibReaderMock, rsmReaderMock, rsmWriterMock)
+ handlerProvider := httpmsghandlerprovider.NewRequestHandlerProvider(log, rnibDataService, resourceStatusServiceMock)
controller := NewController(log, handlerProvider)
- return controller, readerMock, rmrMessengerMock
+ return controller, rnibReaderMock, rsmReaderMock, rsmWriterMock, resourceStatusServiceMock
+}
+
+func TestResourceStatusInvalidBody(t *testing.T) {
+ controller, _, _, _ , _:= setupControllerTest(t)
+
+ header := http.Header{}
+ header.Set("Content-Type", "application/json")
+ httpRequest, _ := http.NewRequest("PUT", "http://localhost:4800/v1/general/resourcestatus", strings.NewReader("{}{}"))
+ httpRequest.Header = header
+
+ writer := httptest.NewRecorder()
+ controller.ResourceStatus(writer, httpRequest)
+
+ var errorResponse = parseJsonRequest(t, writer.Body)
+
+ assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
+ assert.Equal(t, rsmerrors.NewInvalidJsonError().Code, errorResponse.Code)
+}
+
+func TestResourceStatusSuccess(t *testing.T) {
+ controller, readerMock, rsmReaderMock, rsmWriterMock, resourceStatusServiceMock := setupControllerTest(t)
+
+ cellId1 := "02f829:0007ab00"
+ cellId2 := "02f829:0007ab50"
+ nodebInfo := &entities.NodebInfo{
+ RanName: tests.RanName,
+ ConnectionStatus: entities.ConnectionStatus_CONNECTED,
+ Configuration: &entities.NodebInfo_Enb{
+ Enb: &entities.Enb{
+ ServedCells: []*entities.ServedCellInfo{{CellId: cellId1}, {CellId: cellId2}},
+ },
+ },
+ }
+ var nbIdentityList []*entities.NbIdentity
+ config := tests.GetRsmGeneralConfiguration(true)
+
+ rsmWriterMock.On("SaveRsmGeneralConfiguration", config).Return(nil)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(config, nil)
+ readerMock.On("GetListEnbIds").Return(nbIdentityList, nil)
+ readerMock.On("GetNodeb", tests.RanName).Return(nodebInfo)
+ resourceStatusServiceMock.On("BuildAndSendInitiateRequest", mock.AnythingOfType("*entities.NodebInfo"), mock.AnythingOfType("*models.RsmGeneralConfiguration"), enums.Enb1MeasurementId).Return(nil)
+
+ header := http.Header{}
+ header.Set("Content-Type", "application/json")
+ httpRequest, _ := http.NewRequest("PUT", "http://localhost:4800/v1/general/resourcestatus", strings.NewReader("{\"enableResourceStatus\":true}"))
+ httpRequest.Header = header
+
+ writer := httptest.NewRecorder()
+ controller.ResourceStatus(writer, httpRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetListEnbIds", 1)
+ resourceStatusServiceMock.AssertNumberOfCalls(t, "BuildAndSendInitiateRequest", 0)
+
+ assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
+}
+
+func TestResourceStatusFail(t *testing.T) {
+
+ controller, readerMock, rsmReaderMock, _, resourceStatusServiceMock := setupControllerTest(t)
+
+ rnibErr := &rsmerrors.RnibDbError{}
+
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(tests.GetRsmGeneralConfiguration(true), rnibErr)
+
+ header := http.Header{}
+ header.Set("Content-Type", "application/json")
+ httpRequest, _ := http.NewRequest("PUT", "http://localhost:4800/v1/general/resourcestatus", strings.NewReader("{\"enableResourceStatus\":true}"))
+ httpRequest.Header = header
+
+ writer := httptest.NewRecorder()
+ controller.ResourceStatus(writer, httpRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetListEnbIds", 0)
+ resourceStatusServiceMock.AssertNumberOfCalls(t, "BuildAndSendInitiateRequest", 0)
+
+ assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
}
func TestHeaderValidationFailed(t *testing.T) {
- controller, _, _ := setupControllerTest(t)
+ controller, _, _ ,_ , _:= setupControllerTest(t)
writer := httptest.NewRecorder()
header := &http.Header{}
assert.Equal(t, errorResponse.Code, err.Code)
assert.Equal(t, errorResponse.Message, err.Message)
}
-*/
-/*func TestHandleInternalError(t *testing.T) {
- controller, _, _ := setupControllerTest(t)
+
+func TestHandleInternalError(t *testing.T) {
+ controller, _, _,_ ,_ := setupControllerTest(t)
writer := httptest.NewRecorder()
err := rsmerrors.NewInternalError()
assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
assert.Equal(t, errorResponse.Code, err.Code)
assert.Equal(t, errorResponse.Message, err.Message)
-}*/
+}
-/*func TestValidateHeadersSuccess(t *testing.T) {
- controller, _, _ := setupControllerTest(t)
+func TestValidateHeadersSuccess(t *testing.T) {
+ controller, _, _,_ ,_ := setupControllerTest(t)
header := http.Header{}
header.Set("Content-Type", "application/json")
assert.Nil(t, result)
}
-*/
-/*func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
+
+func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
var errorResponse models.ErrorResponse
body, err := ioutil.ReadAll(r)
json.Unmarshal(body, &errorResponse)
return errorResponse
-}*/
-/*
+}
+
func TestHandleErrorResponse(t *testing.T) {
- controller, _, _ := setupControllerTest(t)
+ controller, _, _ ,_ , _:= setupControllerTest(t)
writer := httptest.NewRecorder()
controller.handleErrorResponse(rsmerrors.NewRnibDbError(), writer)
writer = httptest.NewRecorder()
controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
-}
-*/
+
+ writer = httptest.NewRecorder()
+ controller.handleErrorResponse(rsmerrors.NewRsmError(2), writer)
+ assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
+}
\ No newline at end of file
2: "RIC_TO_RAN",
}
-const (
- UNKNOWN_MESSAGE_DIRECTION MessageDirection = 0
- RAN_TO_RIC MessageDirection = 1
- RIC_TO_RAN MessageDirection = 2
-)
-
func (md MessageDirection) String() string {
s, ok := messageDirectionEnumName[int32(md)]
if ok {
const (
Registration_Request_start Registration_Request = iota
Registration_Request_stop
- Registration_Request_partial_stop
- Registration_Request_add
)
)
type RequestHandler interface {
- Handle(request models.Request) (models.IResponse, error)
-}
+ Handle(request models.Request) error
+}
\ No newline at end of file
--- /dev/null
+//
+// 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.
+//
+package httpmsghandlers
+
+import (
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+ "rsm/enums"
+ "rsm/logger"
+ "rsm/models"
+ "rsm/rsmerrors"
+ "rsm/services"
+)
+
+type ResourceStatusRequestHandler struct {
+ rNibDataService services.RNibDataService
+ logger *logger.Logger
+ resourceStatusService services.IResourceStatusService
+}
+
+func NewResourceStatusRequestHandler(logger *logger.Logger, rNibDataService services.RNibDataService, resourceStatusService services.IResourceStatusService) *ResourceStatusRequestHandler {
+ return &ResourceStatusRequestHandler{
+ resourceStatusService: resourceStatusService,
+ rNibDataService: rNibDataService,
+ logger: logger,
+ }
+}
+
+func (h ResourceStatusRequestHandler) Handle(request models.Request) error {
+
+ resourceStatusRequest := request.(models.ResourceStatusRequest)
+ config, err := h.rNibDataService.GetRsmGeneralConfiguration()
+ if err != nil {
+ return rsmerrors.NewRnibDbError()
+ }
+
+ config.EnableResourceStatus = resourceStatusRequest.EnableResourceStatus
+ err = h.rNibDataService.SaveRsmGeneralConfiguration(config)
+ if err != nil {
+ return rsmerrors.NewRnibDbError()
+ }
+
+ nbIdentityList, err := h.rNibDataService.GetListEnbIds()
+ if err != nil {
+ return rsmerrors.NewRnibDbError()
+ }
+
+ numberOfFails := 0
+ for _, nbIdentity := range nbIdentityList {
+
+ nodeb, err := h.rNibDataService.GetNodeb((*nbIdentity).GetInventoryName())
+ if err != nil {
+ numberOfFails++
+ continue
+ }
+
+ if nodeb.ConnectionStatus != entities.ConnectionStatus_CONNECTED {
+ h.logger.Infof("#ResourceStatusRequestHandler.Handle - RAN name: %s - connection status not CONNECTED, ignore", nodeb.RanName)
+ numberOfFails++
+ continue
+ }
+
+ err = h.saveAndSendRsmRanInfo(nodeb, config)
+ if err != nil {
+ numberOfFails++
+ }
+ }
+
+ if numberOfFails > 0 {
+ return rsmerrors.NewRsmError(numberOfFails)
+ }
+ return nil
+}
+
+func (h ResourceStatusRequestHandler) saveAndSendRsmRanInfo(nodebInfo *entities.NodebInfo, config *models.RsmGeneralConfiguration) error {
+
+ rsmRanInfo, err := h.rNibDataService.GetRsmRanInfo(nodebInfo.RanName)
+ if err != nil {
+ return err
+ }
+
+ if config.EnableResourceStatus {
+ err := h.handleNotStartedRsmRanInfo(nodebInfo, rsmRanInfo, config)
+ return err
+ }
+
+ //err = h.handleNotStoppedRsmRanInfo(nodebInfo, rsmRanInfo, config)
+ return nil
+}
+
+/*func (h ResourceStatusRequestHandler) handleNotStoppedRsmRanInfo(nodebInfo *entities.NodebInfo, rsmRanInfo *models.RsmRanInfo, config *models.RsmGeneralConfiguration) error {
+ if rsmRanInfo.Action == enums.Stop && rsmRanInfo.ActionStatus {
+ return nil
+ }
+
+ if rsmRanInfo.Action != enums.Stop {
+
+ err := h.saveRsmRanInfoStopFalse(rsmRanInfo)
+ if err != nil {
+ return err
+ }
+ }
+
+ err := h.resourceStatusService.BuildAndSendStopRequest(config, rsmRanInfo.RanName, rsmRanInfo.Enb1MeasurementId, rsmRanInfo.Enb2MeasurementId)
+ return err
+}*/
+
+func (h ResourceStatusRequestHandler) handleNotStartedRsmRanInfo(nodebInfo *entities.NodebInfo, rsmRanInfo *models.RsmRanInfo, config *models.RsmGeneralConfiguration) error {
+ if rsmRanInfo.Action == enums.Start && rsmRanInfo.ActionStatus {
+ return nil
+ }
+
+ if rsmRanInfo.Action != enums.Start {
+
+ err := h.saveRsmRanInfoStartFalse(rsmRanInfo)
+ if err != nil {
+ return err
+ }
+ }
+
+ err := h.resourceStatusService.BuildAndSendInitiateRequest(nodebInfo, config, rsmRanInfo.Enb1MeasurementId)
+ return err
+}
+
+/*func (h ResourceStatusRequestHandler) saveRsmRanInfoStopFalse(rsmRanInfo *models.RsmRanInfo) error {
+ rsmRanInfo.Action = enums.Stop
+ rsmRanInfo.ActionStatus = false
+
+ err := h.rNibDataService.SaveRsmRanInfo(rsmRanInfo)
+ if err != nil {
+ h.logger.Errorf("#ResourceStatusRequestHandler.saveRsmRanInfoStopFalse - failed to save rsm ran data to RNIB. Error: %s", err.Error())
+ return err
+ }
+ return nil
+}*/
+
+func (h ResourceStatusRequestHandler) saveRsmRanInfoStartFalse(rsmRanInfo *models.RsmRanInfo) error {
+ rsmRanInfo.Action = enums.Start
+ rsmRanInfo.ActionStatus = false
+ rsmRanInfo.Enb2MeasurementId = 0
+
+ err := h.rNibDataService.SaveRsmRanInfo(rsmRanInfo)
+ if err != nil {
+ return err
+ }
+ return nil
+}
--- /dev/null
+//
+// 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.
+//
+package httpmsghandlers_test
+
+import (
+ "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"
+ "github.com/stretchr/testify/mock"
+ "rsm/configuration"
+ "rsm/enums"
+ "rsm/handlers/httpmsghandlers"
+ "rsm/logger"
+ "rsm/mocks"
+ "rsm/models"
+ "rsm/rsmerrors"
+ "rsm/services"
+ "rsm/tests"
+ "testing"
+)
+
+func initTest(t *testing.T) (*httpmsghandlers.ResourceStatusRequestHandler, *mocks.RnibReaderMock, *mocks.RsmReaderMock, *mocks.RsmWriterMock, *mocks.ResourceStatusServiceMock) {
+ log, err := logger.InitLogger(logger.DebugLevel)
+ if err != nil {
+ t.Errorf("#... - failed to initialize logger, error: %s", err)
+ }
+
+ config, err := configuration.ParseConfiguration()
+ if err != nil {
+ t.Errorf("#... - failed to parse configuration error: %s", err)
+ }
+
+ resourceStatusServiceMock := &mocks.ResourceStatusServiceMock{}
+ rnibReaderMock := &mocks.RnibReaderMock{}
+ rsmReaderMock := &mocks.RsmReaderMock{}
+ rsmWriterMock := &mocks.RsmWriterMock{}
+
+ rnibDataService := services.NewRnibDataService(log, config, rnibReaderMock, rsmReaderMock, rsmWriterMock)
+ handler := httpmsghandlers.NewResourceStatusRequestHandler(log, rnibDataService, resourceStatusServiceMock)
+
+ return handler, rnibReaderMock, rsmReaderMock, rsmWriterMock, resourceStatusServiceMock
+}
+
+func TestResourceStatusRequestHandlerGetConfigError(t *testing.T) {
+
+ handler, _, rsmReaderMock, _, _ := initTest(t)
+
+ err := common.NewInternalError(errors.New("Error"))
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(tests.GetRsmGeneralConfiguration(true), err)
+
+ resourceStatusRequest := models.ResourceStatusRequest{EnableResourceStatus:true}
+ actualErr := handler.Handle(resourceStatusRequest)
+
+ rsmReaderMock.AssertNumberOfCalls(t, "SaveRsmGeneralConfiguration", 0)
+
+ assert.Equal(t, actualErr, rsmerrors.NewRnibDbError())
+}
+
+func TestResourceStatusRequestHandlerSaveConfigError(t *testing.T) {
+
+ handler, readerMock, rsmReaderMock, rsmWriterMock, _ := initTest(t)
+
+ err := common.NewInternalError(errors.New("Error"))
+ config := tests.GetRsmGeneralConfiguration(true)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(config, nil)
+ rsmWriterMock.On("SaveRsmGeneralConfiguration", config).Return(err)
+
+ resourceStatusRequest := models.ResourceStatusRequest{EnableResourceStatus:true}
+ actualErr := handler.Handle(resourceStatusRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetListEnbIds", 0)
+
+ assert.Equal(t, actualErr, rsmerrors.NewRnibDbError())
+}
+
+func TestResourceStatusRequestHandleGetListEnbIdsError(t *testing.T) {
+
+ handler, readerMock, rsmReaderMock, rsmWriterMock, _ := initTest(t)
+
+ err := common.NewInternalError(errors.New("Error"))
+ config := tests.GetRsmGeneralConfiguration(true)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(config, nil)
+ rsmWriterMock.On("SaveRsmGeneralConfiguration", config).Return(nil)
+
+ var nbIdentityList []*entities.NbIdentity
+ readerMock.On("GetListEnbIds").Return(nbIdentityList, err)
+
+ resourceStatusRequest := models.ResourceStatusRequest{EnableResourceStatus:true}
+ actualErr := handler.Handle(resourceStatusRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetNodeb", 0)
+
+ assert.Equal(t, actualErr, rsmerrors.NewRnibDbError())
+}
+
+func TestResourceStatusRequestHandlerTrueStartSuccess(t *testing.T) {
+
+ handler, readerMock, rsmReaderMock, rsmWriterMock, resourceStatusServiceMock := initTest(t)
+
+ config := tests.GetRsmGeneralConfiguration(true)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(config, nil)
+ rsmWriterMock.On("SaveRsmGeneralConfiguration", config).Return(nil)
+
+ nbIdentityList := CreateIdentityList()
+ readerMock.On("GetListEnbIds").Return(nbIdentityList, nil)
+
+ nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ nb3 := &entities.NodebInfo{RanName: "RanName_3", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
+ readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
+ readerMock.On("GetNodeb", "RanName_3").Return(nb3, nil)
+
+ rrInfo1 := &models.RsmRanInfo{RanName:"RanName_1", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Start, ActionStatus:false}
+ rrInfo2 := &models.RsmRanInfo{RanName:"RanName_2", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Start, ActionStatus:true}
+ rrInfo3 := &models.RsmRanInfo{RanName:"RanName_3", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Stop, ActionStatus:false}
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_1").Return(rrInfo1, nil)
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_2").Return(rrInfo2, nil)
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_3").Return(rrInfo3, nil)
+
+ rsmWriterMock.On("SaveRsmRanInfo", rrInfo3).Return(nil)
+
+ resourceStatusServiceMock.On("BuildAndSendInitiateRequest", nb1, config, enums.Enb1MeasurementId).Return(nil)
+ resourceStatusServiceMock.On("BuildAndSendInitiateRequest", nb3, config, enums.Enb1MeasurementId).Return(nil)
+
+
+ resourceStatusRequest := models.ResourceStatusRequest{EnableResourceStatus:true}
+ actualErr := handler.Handle(resourceStatusRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetNodeb", 3)
+ rsmWriterMock.AssertNumberOfCalls(t, "SaveRsmRanInfo", 1)
+ resourceStatusServiceMock.AssertNumberOfCalls(t, "BuildAndSendInitiateRequest", 2)
+
+ assert.Equal(t, actualErr, nil)
+}
+
+func TestResourceStatusRequestHandlerTrueNumberOfFails2(t *testing.T) {
+
+ handler, readerMock, rsmReaderMock, rsmWriterMock, resourceStatusServiceMock := initTest(t)
+
+ config := tests.GetRsmGeneralConfiguration(true)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(config, nil)
+ rsmWriterMock.On("SaveRsmGeneralConfiguration", config).Return(nil)
+
+ nbIdentityList := CreateIdentityList()
+ readerMock.On("GetListEnbIds").Return(nbIdentityList, nil)
+
+ nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,}
+ nb3 := &entities.NodebInfo{RanName: "RanName_3", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
+ readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
+ readerMock.On("GetNodeb", "RanName_3").Return(nb3, nil)
+
+ err := common.NewInternalError(errors.New("Error"))
+ rrInfo1 := &models.RsmRanInfo{RanName:"RanName_1", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Start, ActionStatus:false}
+ rrInfo3 := &models.RsmRanInfo{RanName:"RanName_3", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Stop, ActionStatus:false}
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_1").Return(rrInfo1, err)
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_3").Return(rrInfo3, nil)
+
+ rsmWriterMock.On("SaveRsmRanInfo", rrInfo3).Return(nil)
+
+ resourceStatusServiceMock.On("BuildAndSendInitiateRequest", nb3, mock.AnythingOfType("*models.RsmGeneralConfiguration"), enums.Enb1MeasurementId).Return(nil)
+
+
+ resourceStatusRequest := models.ResourceStatusRequest{EnableResourceStatus:true}
+ actualErr := handler.Handle(resourceStatusRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetNodeb", 3)
+ rsmWriterMock.AssertNumberOfCalls(t, "SaveRsmRanInfo", 1)
+ resourceStatusServiceMock.AssertNumberOfCalls(t, "BuildAndSendInitiateRequest", 1)
+
+ rsmError := rsmerrors.NewRsmError(2)
+ assert.Equal(t, actualErr, rsmError)
+ assert.Equal(t, actualErr.Error(), rsmError.Error())
+}
+
+func TestResourceStatusRequestHandlerTrueNumberOfFails3(t *testing.T) {
+
+ handler, readerMock, rsmReaderMock, rsmWriterMock, resourceStatusServiceMock := initTest(t)
+
+ config := tests.GetRsmGeneralConfiguration(true)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(config, nil)
+ rsmWriterMock.On("SaveRsmGeneralConfiguration", config).Return(nil)
+
+ nbIdentityList := CreateIdentityList()
+ readerMock.On("GetListEnbIds").Return(nbIdentityList, nil)
+
+ err := common.NewInternalError(errors.New("Error"))
+ nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ nb3 := &entities.NodebInfo{RanName: "RanName_3", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
+ readerMock.On("GetNodeb", "RanName_2").Return(nb2, err)
+ readerMock.On("GetNodeb", "RanName_3").Return(nb3, nil)
+
+ rrInfo1 := &models.RsmRanInfo{RanName:"RanName_1", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Start, ActionStatus:false}
+ rrInfo3 := &models.RsmRanInfo{RanName:"RanName_3", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Stop, ActionStatus:false}
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_1").Return(rrInfo1, nil)
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_3").Return(rrInfo3, nil)
+
+ rsmWriterMock.On("SaveRsmRanInfo", rrInfo3).Return(err)
+
+ resourceStatusServiceMock.On("BuildAndSendInitiateRequest", nb1, mock.AnythingOfType("*models.RsmGeneralConfiguration"), enums.Enb1MeasurementId).Return(errors.New("Error"))
+
+
+ resourceStatusRequest := models.ResourceStatusRequest{EnableResourceStatus:true}
+ actualErr := handler.Handle(resourceStatusRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetNodeb", 3)
+ rsmWriterMock.AssertNumberOfCalls(t, "SaveRsmRanInfo", 1)
+ resourceStatusServiceMock.AssertNumberOfCalls(t, "BuildAndSendInitiateRequest", 1)
+
+ rsmError := rsmerrors.NewRsmError(3)
+ assert.Equal(t, actualErr, rsmError)
+ assert.Equal(t, actualErr.Error(), rsmError.Error())
+}
+
+/*func TestResourceStatusRequestHandlerFalseStopSuccess(t *testing.T) {
+
+ handler, readerMock, rsmReaderMock, rsmWriterMock, resourceStatusServiceMock := initTest(t)
+
+ config := tests.GetRsmGeneralConfiguration(false)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(config, nil)
+ rsmWriterMock.On("SaveRsmGeneralConfiguration", config).Return(nil)
+
+ nbIdentityList := CreateIdentityList()
+ readerMock.On("GetListEnbIds").Return(nbIdentityList, nil)
+
+ nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ nb3 := &entities.NodebInfo{RanName: "RanName_3", ConnectionStatus: entities.ConnectionStatus_CONNECTED,}
+ readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
+ readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
+ readerMock.On("GetNodeb", "RanName_3").Return(nb3, nil)
+
+ rrInfo1 := &models.RsmRanInfo{RanName:"RanName_1", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Start, ActionStatus:false}
+ rrInfo2 := &models.RsmRanInfo{RanName:"RanName_2", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Start, ActionStatus:true}
+ rrInfo3 := &models.RsmRanInfo{RanName:"RanName_3", Enb1MeasurementId:enums.Enb1MeasurementId, Enb2MeasurementId:0, Action:enums.Stop, ActionStatus:false}
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_1").Return(rrInfo1, nil)
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_2").Return(rrInfo2, nil)
+ rsmReaderMock.On("GetRsmRanInfo", "RanName_3").Return(rrInfo3, nil)
+
+ rsmWriterMock.On("SaveRsmRanInfo", rrInfo3).Return(nil)
+
+ resourceStatusServiceMock.On("BuildAndSendStopRequest", nb1, config, enums.Enb1MeasurementId).Return(nil)
+ resourceStatusServiceMock.On("BuildAndSendStopRequest", nb3, config, enums.Enb1MeasurementId).Return(nil)
+
+
+ resourceStatusRequest := models.ResourceStatusRequest{EnableResourceStatus:true}
+ actualErr := handler.Handle(resourceStatusRequest)
+
+ readerMock.AssertNumberOfCalls(t, "GetNodeb", 3)
+ rsmWriterMock.AssertNumberOfCalls(t, "SaveRsmRanInfo", 1)
+ resourceStatusServiceMock.AssertNumberOfCalls(t, "BuildAndSendInitiateRequest", 2)
+
+ assert.Equal(t, actualErr, nil)
+}*/
+func CreateIdentityList() []*entities.NbIdentity {
+ nbIdentity1 := entities.NbIdentity{InventoryName: "RanName_1"}
+ nbIdentity2 := entities.NbIdentity{InventoryName: "RanName_2"}
+ nbIdentity3 := entities.NbIdentity{InventoryName: "RanName_3"}
+
+ var nbIdentityList []*entities.NbIdentity
+ nbIdentityList = append(nbIdentityList, &nbIdentity1)
+ nbIdentityList = append(nbIdentityList, &nbIdentity2)
+ nbIdentityList = append(nbIdentityList, &nbIdentity3)
+
+ return nbIdentityList
+}
\ No newline at end of file
"rsm/mocks"
"rsm/models"
"rsm/services"
+ "rsm/tests"
"testing"
"time"
)
const RanName = "test"
-func getRsmGeneralConfiguration(enableResourceStatus bool) *models.RsmGeneralConfiguration {
- return &models.RsmGeneralConfiguration{
- EnableResourceStatus: enableResourceStatus,
- PartialSuccessAllowed: true,
- PrbPeriodic: true,
- TnlLoadIndPeriodic: true,
- HwLoadIndPeriodic: true,
- AbsStatusPeriodic: true,
- RsrpMeasurementPeriodic: true,
- CsiPeriodic: true,
- PeriodicityMs: enums.ReportingPeriodicity_one_thousand_ms,
- PeriodicityRsrpMeasurementMs: enums.ReportingPeriodicityRSRPMR_four_hundred_80_ms,
- PeriodicityCsiMs: enums.ReportingPeriodicityCSIR_ms20,
- }
-}
func initRanConnectedNotificationHandlerTest(t *testing.T, requestName string) (ResourceStatusInitiateNotificationHandler, *mocks.RnibReaderMock, *mocks.ResourceStatusServiceMock, *mocks.RsmWriterMock, *mocks.RsmReaderMock) {
log, err := logger.InitLogger(logger.DebugLevel)
func TestEnableResourceStatusFalse(t *testing.T) {
h, _, resourceStatusServiceMock, rsmWriterMock, rsmReaderMock := initRanConnectedNotificationHandlerTest(t, "RanConnected")
var err error
- rsmReaderMock.On("GetRsmGeneralConfiguration").Return(getRsmGeneralConfiguration(false), err)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(tests.GetRsmGeneralConfiguration(false), err)
rsmRanInfo := models.RsmRanInfo{RanName, 0, 0, enums.Stop, true}
rsmWriterMock.On("SaveRsmRanInfo", &rsmRanInfo).Return(err)
func TestEnableResourceStatusFalseSaveRsmRanInfoFailure(t *testing.T) {
h, _, resourceStatusServiceMock, rsmWriterMock, rsmReaderMock := initRanConnectedNotificationHandlerTest(t, "RanConnected")
var err error
- rsmReaderMock.On("GetRsmGeneralConfiguration").Return(getRsmGeneralConfiguration(false), err)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(tests.GetRsmGeneralConfiguration(false), err)
rsmRanInfo := models.RsmRanInfo{RanName, 0, 0, enums.Stop, true}
rsmWriterMock.On("SaveRsmRanInfo", &rsmRanInfo).Return(common.NewInternalError(errors.New("Error")))
rmrReq := &models.RmrRequest{RanName: RanName, Payload: payload, Len: len(payload), StartTime: time.Now()}
var err error
- rsmReaderMock.On("GetRsmGeneralConfiguration").Return(getRsmGeneralConfiguration(true), err)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(tests.GetRsmGeneralConfiguration(true), err)
var nodebInfo *entities.NodebInfo
rnibReaderMock.On("GetNodeb", RanName).Return(nodebInfo, common.NewInternalError(errors.New("Error")))
func TestInvalidConnectionStatus(t *testing.T) {
h, rnibReaderMock, resourceStatusServiceMock, rsmWriterMock, rsmReaderMock := initRanConnectedNotificationHandlerTest(t, "RanConnected")
var err error
- rsmReaderMock.On("GetRsmGeneralConfiguration").Return(getRsmGeneralConfiguration(true), err)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(tests.GetRsmGeneralConfiguration(true), err)
rnibReaderMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}, err)
rsmRanInfo := models.RsmRanInfo{RanName, 0, 0, enums.Stop, true}
rsmWriterMock.On("SaveRsmRanInfo", &rsmRanInfo).Return(err)
rmrReq := &models.RmrRequest{RanName: RanName, Payload: payload, Len: len(payload), StartTime: time.Now()}
var err error
- rsmReaderMock.On("GetRsmGeneralConfiguration").Return(getRsmGeneralConfiguration(true), err)
+ rsmReaderMock.On("GetRsmGeneralConfiguration").Return(tests.GetRsmGeneralConfiguration(true), err)
rnibReaderMock.On("GetNodeb", RanName).Return(&entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}, err)
rsmRanInfo := models.RsmRanInfo{RanName, enums.Enb1MeasurementId, 0, enums.Start, false}
rsmWriterMock.On("SaveRsmRanInfo", &rsmRanInfo).Return(common.NewInternalError(errors.New("Error")))
rmrReq := &models.RmrRequest{RanName: RanName, Payload: payload, Len: len(payload), StartTime: time.Now()}
var err error
- rgc := getRsmGeneralConfiguration(true)
+ rgc := tests.GetRsmGeneralConfiguration(true)
rsmReaderMock.On("GetRsmGeneralConfiguration").Return(rgc, err)
nodebInfo := &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
rnibReaderMock.On("GetNodeb", RanName).Return(nodebInfo, err)
h, rnibReaderMock, resourceStatusServiceMock, rsmWriterMock, rsmReaderMock := initRanConnectedNotificationHandlerTest(t, "RanConnected")
var err error
nodebInfo := &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
- rgc := getRsmGeneralConfiguration(true)
+ rgc := tests.GetRsmGeneralConfiguration(true)
rsmReaderMock.On("GetRsmGeneralConfiguration").Return(rgc, err)
rnibReaderMock.On("GetNodeb", RanName).Return(nodebInfo, err)
rsmRanInfoStart := models.RsmRanInfo{RanName, enums.Enb1MeasurementId, 0, enums.Start, false}
"rsm/controllers"
)
-func Run(port int, controller controllers.IRootController) error {
+func Run(port int, rootController controllers.IRootController, controller controllers.IController) error {
router := mux.NewRouter()
- initializeRoutes(router, controller)
+ initializeRoutes(router, rootController, controller)
addr := fmt.Sprintf(":%d", port)
return fmt.Errorf("#http_server.Run - Fail initiating HTTP server. Error: %v", err)
}
-func initializeRoutes(router *mux.Router, rootController controllers.IRootController) {
+func initializeRoutes(router *mux.Router, rootController controllers.IRootController, controller controllers.IController) {
r := router.PathPrefix("/v1").Subrouter()
r.HandleFunc("/health", rootController.HandleHealthCheckRequest).Methods("GET")
-}
+
+ rr := r.PathPrefix("/general").Subrouter()
+ rr.HandleFunc("/resourcestatus", controller.ResourceStatus).Methods("PUT")
+}
\ No newline at end of file
"time"
)
-func setupRouterAndMocks() (*mux.Router, *mocks.RootControllerMock) {
+func setupRouterAndMocks() (*mux.Router, *mocks.RootControllerMock, *mocks.ControllerMock) {
rootControllerMock := &mocks.RootControllerMock{}
rootControllerMock.On("HandleHealthCheckRequest").Return(nil)
+ controllerMock := &mocks.ControllerMock{}
+ controllerMock.On("ResourceStatus").Return(nil)
+
router := mux.NewRouter()
- initializeRoutes(router, rootControllerMock)
- return router, rootControllerMock
+ initializeRoutes(router, rootControllerMock, controllerMock)
+ return router, rootControllerMock, controllerMock
+}
+func TestResourceStatus(t *testing.T) {
+ router, _, controllerMock := setupRouterAndMocks()
+
+ req, err := http.NewRequest("PUT", "/v1/general/resourcestatus", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ rr := httptest.NewRecorder()
+ router.ServeHTTP(rr, req)
+
+ controllerMock.AssertNumberOfCalls(t, "ResourceStatus", 1)
}
func TestRouteGetHealth(t *testing.T) {
- router, rootControllerMock := setupRouterAndMocks()
+ router, rootControllerMock, _ := setupRouterAndMocks()
req, err := http.NewRequest("GET", "/v1/health", nil)
if err != nil {
}
func TestRouteNotFound(t *testing.T) {
- router, _ := setupRouterAndMocks()
+ router, _, _ := setupRouterAndMocks()
req, err := http.NewRequest("GET", "/v1/no/such/route", nil)
if err != nil {
}
func TestRunError(t *testing.T) {
- rootControllerMock := &mocks.RootControllerMock{}
+ _, rootControllerMock, controllerMock := setupRouterAndMocks()
- err := Run(111222333, rootControllerMock)
+ err := Run(111222333, rootControllerMock, controllerMock)
assert.NotNil(t, err)
}
func TestRun(t *testing.T) {
- rootControllerMock := &mocks.RootControllerMock{}
- rootControllerMock.On("HandleHealthCheckRequest").Return(nil)
+ _, rootControllerMock, controllerMock := setupRouterAndMocks()
- go Run(11223, rootControllerMock)
+ go Run(11223, rootControllerMock, controllerMock)
time.Sleep(time.Millisecond * 100)
resp, err := http.Get("http://localhost:11223/v1/health")
t.Fatalf("failed to perform GET to http://localhost:11223/v1/health")
}
assert.Equal(t, 200, resp.StatusCode)
-}
+}
\ No newline at end of file
import (
"github.com/stretchr/testify/mock"
+ "net/http"
)
type ControllerMock struct {
mock.Mock
}
+
+func (c *ControllerMock) ResourceStatus(writer http.ResponseWriter, r *http.Request){
+ writer.Header().Set("Content-Type", "application/json")
+ writer.WriteHeader(http.StatusOK)
+
+ c.Called()
+}
\ No newline at end of file
--- /dev/null
+//
+// 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.
+//
+
+package models
+
+type ResourceStatusRequest struct {
+ EnableResourceStatus bool `json:"enableResourceStatus"`
+}
package httpmsghandlerprovider
import (
- "rsm/configuration"
"rsm/handlers/httpmsghandlers"
"rsm/logger"
"rsm/rsmerrors"
"rsm/services"
- "rsm/services/rmrsender"
)
type IncomingRequest string
const (
- ResourceStatusInitiation = "ResourceStatusInitiation"
+ ResourceStatusRequest = "ResourceStatusRequest"
)
type RequestHandlerProvider struct {
- requestMap map[IncomingRequest]*httpmsghandlers.RequestHandler
+ requestMap map[IncomingRequest]httpmsghandlers.RequestHandler
logger *logger.Logger
}
-func NewRequestHandlerProvider(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rNibDataService services.RNibDataService) *RequestHandlerProvider {
+func NewRequestHandlerProvider(logger *logger.Logger, rNibDataService services.RNibDataService, resourceStatusService services.IResourceStatusService) *RequestHandlerProvider {
return &RequestHandlerProvider{
- requestMap: initRequestHandlerMap(logger, rmrSender, config, rNibDataService),
+ requestMap: initRequestHandlerMap(logger, rNibDataService, resourceStatusService),
logger: logger,
}
}
-func initRequestHandlerMap(logger *logger.Logger, rmrSender *rmrsender.RmrSender, config *configuration.Configuration, rNibDataService services.RNibDataService) map[IncomingRequest]*httpmsghandlers.RequestHandler {
+func initRequestHandlerMap(logger *logger.Logger, rNibDataService services.RNibDataService, resourceStatusService services.IResourceStatusService) map[IncomingRequest]httpmsghandlers.RequestHandler {
- return map[IncomingRequest]*httpmsghandlers.RequestHandler{}
+ return map[IncomingRequest]httpmsghandlers.RequestHandler{
+ ResourceStatusRequest: httpmsghandlers.NewResourceStatusRequestHandler(logger, rNibDataService, resourceStatusService),
+ }
}
-func (provider RequestHandlerProvider) GetHandler(requestType IncomingRequest) (*httpmsghandlers.RequestHandler, error) {
+func (provider RequestHandlerProvider) GetHandler(requestType IncomingRequest) (httpmsghandlers.RequestHandler, error) {
handler, ok := provider.requestMap[requestType]
if !ok {
}
return handler, nil
-}
+}
\ No newline at end of file
"github.com/stretchr/testify/assert"
"reflect"
"rsm/configuration"
+ "rsm/handlers/httpmsghandlers"
+ "rsm/logger"
+ "rsm/mocks"
"rsm/rsmerrors"
- "rsm/tests/testhelper"
+ "rsm/services"
"testing"
)
func setupTest(t *testing.T) *RequestHandlerProvider {
+ log, err := logger.InitLogger(logger.DebugLevel)
+ if err != nil {
+ t.Errorf("#... - failed to initialize logger, error: %s", err)
+ }
+
config, err := configuration.ParseConfiguration()
if err != nil {
t.Errorf("#... - failed to parse configuration error: %s", err)
}
- rnibDataService, rmrSender, log := testhelper.InitTestCase(t)
- return NewRequestHandlerProvider(log, rmrSender, config, rnibDataService)
+
+ resourceStatusServiceMock := &mocks.ResourceStatusServiceMock{}
+ rnibReaderMock := &mocks.RnibReaderMock{}
+ rsmReaderMock := &mocks.RsmReaderMock{}
+ rsmWriterMock := &mocks.RsmWriterMock{}
+
+ rnibDataService := services.NewRnibDataService(log, config, rnibReaderMock, rsmReaderMock, rsmWriterMock)
+ return NewRequestHandlerProvider(log, rnibDataService, resourceStatusServiceMock)
}
func TestNewRequestHandlerProvider(t *testing.T) {
assert.NotNil(t, provider)
}
+func TestResourceStatusRequestHandler(t *testing.T) {
+ provider := setupTest(t)
+ handler, err := provider.GetHandler(ResourceStatusRequest)
+
+ assert.NotNil(t, provider)
+ assert.Nil(t, err)
+
+ _, ok := handler.(*httpmsghandlers.ResourceStatusRequestHandler)
+
+ assert.True(t, ok)
+}
+
func TestNewRequestHandlerProvider_InternalError(t *testing.T) {
provider := setupTest(t)
if reflect.TypeOf(actual) != reflect.TypeOf(expected) {
t.Errorf("Error actual = %v, and Expected = %v.", actual, expected)
}
-}
+}
\ No newline at end of file
type IResourceStatusService interface {
BuildAndSendInitiateRequest(nodeb *entities.NodebInfo, config *models.RsmGeneralConfiguration, enb1MeasurementId int64) error
+ //BuildAndSendStopRequest(config *models.RsmGeneralConfiguration, ranName string, enb1MeasurementId int64, enb2MeasurementId int64) error
}
func NewResourceStatusService(logger *logger.Logger, rmrSender *rmrsender.RmrSender) *ResourceStatusService {
return m.rmrSender.Send(rmrMsg)
}
+/*func (m *ResourceStatusService) BuildAndSendStopRequest(config *models.RsmGeneralConfiguration, ranName string, enb1MeasurementId int64, enb2MeasurementId int64) error {
+
+ requestParams := &e2pdus.ResourceStatusRequestData{
+ MeasurementID: e2pdus.Measurement_ID(enb1MeasurementId),
+ MeasurementID2: e2pdus.Measurement_ID(enb2MeasurementId),
+ }
+
+ payload, payloadAsString, err := e2pdus.BuildPackedResourceStatusRequest(enums.Registration_Request_stop, requestParams, e2pdus.MaxAsn1PackedBufferSize, e2pdus.MaxAsn1CodecMessageBufferSize, m.logger.DebugEnabled())
+
+ if err != nil {
+ m.logger.Errorf("#ResourceStatusService.BuildAndSendStopRequest - RAN name: %s. Failed to build and pack resource status stop request. error: %s", ranName, err)
+ return err
+ }
+
+ m.logger.Debugf("#ResourceStatusService.BuildAndSendStopRequest - RAN name: %s. Successfully build packed payload: %s", ranName, payloadAsString)
+ rmrMsg := models.NewRmrMessage(rmrcgo.RicResStatusReq, ranName, payload)
+
+ return m.rmrSender.Send(rmrMsg)
+}*/
+
func (m *ResourceStatusService) extractCellIdList(nodeb *entities.NodebInfo) ([]string, error) {
enb, ok := nodeb.Configuration.(*entities.NodebInfo_Enb)
type RNibDataService interface {
GetRsmGeneralConfiguration() (*models.RsmGeneralConfiguration, error)
+ SaveRsmGeneralConfiguration(config *models.RsmGeneralConfiguration) error
GetRsmRanInfo(ranName string) (*models.RsmRanInfo, error)
SaveRsmRanInfo(rsmData *models.RsmRanInfo) error
GetNodeb(ranName string) (*entities.NodebInfo, error)
GetListNodebIds() ([]*entities.NbIdentity, error)
+ GetListEnbIds() ([]*entities.NbIdentity, error)
PingRnib() bool
}
return rsmGeneralConfiguration, err
}
+func (w *rNibDataService) SaveRsmGeneralConfiguration(config *models.RsmGeneralConfiguration) error {
+ w.logger.Infof("#RnibDataService.SaveRsmGeneralConfiguration - configuration: %+v", *config)
+
+ err := w.retry("SaveRsmGeneralConfiguration", func() (err error) {
+ err = w.rsmWriter.SaveRsmGeneralConfiguration(config)
+ return
+ })
+
+ return err
+}
+
func (w *rNibDataService) GetRsmRanInfo(ranName string) (*models.RsmRanInfo, error) {
var rsmRanInfo *models.RsmRanInfo = nil
return nodeb, err
}
+func (w *rNibDataService) GetListEnbIds() ([]*entities.NbIdentity, error) {
+ w.logger.Infof("#RnibDataService.GetListEnbIds")
+
+ var nodeIds []*entities.NbIdentity = nil
+
+ err := w.retry("GetListEnbIds", func() (err error) {
+ nodeIds, err = w.rnibReader.GetListEnbIds()
+ return
+ })
+
+ return nodeIds, err
+}
+
func (w *rNibDataService) GetListNodebIds() ([]*entities.NbIdentity, error) {
w.logger.Infof("#RnibDataService.GetListNodebIds")
res := rnibDataService.PingRnib()
readerMock.AssertNumberOfCalls(t, "GetListNodebIds", 1)
assert.True(t, res)
-}
+}
\ No newline at end of file
"bytes"
"encoding/json"
"net/http"
+ "rsm/enums"
+ "rsm/models"
"strconv"
)
req, _ := http.NewRequest("POST", "https://localhost:3800/request", b)
return req
}
+
+func GetRsmGeneralConfiguration(enableResourceStatus bool) *models.RsmGeneralConfiguration {
+ return &models.RsmGeneralConfiguration{
+ EnableResourceStatus: enableResourceStatus,
+ PartialSuccessAllowed: true,
+ PrbPeriodic: true,
+ TnlLoadIndPeriodic: true,
+ HwLoadIndPeriodic: true,
+ AbsStatusPeriodic: true,
+ RsrpMeasurementPeriodic: true,
+ CsiPeriodic: true,
+ PeriodicityMs: enums.ReportingPeriodicity_one_thousand_ms,
+ PeriodicityRsrpMeasurementMs: enums.ReportingPeriodicityRSRPMR_four_hundred_80_ms,
+ PeriodicityCsiMs: enums.ReportingPeriodicityCSIR_ms20,
+ }
+}
\ No newline at end of file
+++ /dev/null
-//
-// 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.
-//
-
-package tests
-
-// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/
-// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec
-// #include <asn1codec_utils.h>
-// #include <SuccessfulOutcome.h>
-//
-// bool
-// build_pack_x2_reset_response(size_t* packed_buf_size, unsigned char* packed_buf, size_t err_buf_size, char* err_buf){
-// bool rc = true;
-// E2AP_PDU_t *pdu = calloc(1, sizeof(E2AP_PDU_t));
-// SuccessfulOutcome_t *successfulOutcome = calloc(1, sizeof(SuccessfulOutcome_t));
-// ResetResponse_t *resetResponse;
-// ResetResponse_IEs_t *resetResponse_IEs = calloc(1, sizeof(ResetResponse_IEs_t));
-//
-// assert(pdu != 0);
-// assert(successfulOutcome != 0);
-// assert(resetResponse_IEs != 0);
-//
-// pdu->present = E2AP_PDU_PR_successfulOutcome;
-// pdu->choice.successfulOutcome = successfulOutcome;
-//
-// successfulOutcome->procedureCode = ProcedureCode_id_reset;
-// successfulOutcome->criticality = Criticality_reject;
-// successfulOutcome->value.present = SuccessfulOutcome__value_PR_ResetResponse;
-// resetResponse = &successfulOutcome->value.choice.ResetResponse;
-//
-// CriticalityDiagnostics_IE_List_t *critList = calloc(1, sizeof(CriticalityDiagnostics_IE_List_t));
-// assert(critList != 0);
-// resetResponse_IEs->id = ProtocolIE_ID_id_CriticalityDiagnostics;
-// resetResponse_IEs->criticality = Criticality_ignore;
-// resetResponse_IEs->value.present = ResetResponse_IEs__value_PR_CriticalityDiagnostics;
-// ASN_SEQUENCE_ADD(resetResponse_IEs->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics,critList);
-//
-// CriticalityDiagnostics_IE_List__Member *member= calloc(1, sizeof(CriticalityDiagnostics_IE_List__Member));
-// assert(member != 0);
-// ASN_SEQUENCE_ADD(critList ,member);
-//
-// ASN_SEQUENCE_ADD(&resetResponse->protocolIEs, resetResponse_IEs);
-//
-// rc = per_pack_pdu(pdu, packed_buf_size, packed_buf,err_buf_size, err_buf);
-//
-// ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pdu);
-// return rc;
-// }
-import "C"
-import (
- "errors"
- "fmt"
- "unsafe"
-)
-
-const PackedBufferSize = 4096
-
-func BuildPackedX2ResetResponse() ([]byte, error) {
- payloadSize := C.ulong(PackedBufferSize)
- packedBuffer := [PackedBufferSize]C.uchar{}
- errorBuffer := [PackedBufferSize]C.char{}
- res := bool(C.build_pack_x2_reset_response(&payloadSize, &packedBuffer[0], PackedBufferSize, &errorBuffer[0]))
- if !res {
- return nil, errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errorBuffer[0])))
- }
- return C.GoBytes(unsafe.Pointer(&packedBuffer), C.int(payloadSize)), nil
-}
apiRoot:
default: 'localhost:?'
paths:
- /health:
+ '/health':
get:
tags:
- Health Check
responses:
'204':
description: OK
+ '/general/resourcestatus':
+ put:
+ summary: enable/disable resource status
+ tags:
+ - Resource Status
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/ResourceStatus'
+ required: true
+ responses:
+ '204':
+ description: Success
+ '500':
+ description: Internal error
+ content:
+ application/problem+json:
+ schema:
+ $ref: '#/components/schemas/ErrorResponse'
components:
schemas:
+ ResourceStatus:
+ type: object
+ required:
+ - enableResourceStatus
+ properties:
+ enableResourceStatus:
+ type: boolean
ErrorResponse:
type: object
required:
properties:
errorCode:
type: string
- description: '401 - corrupted json, 402 - validation error, 403 - RAN in wrong state, 404 - resource not found, 500 - RNIB error, 501 - internal problem, 502 - RMR error'
+ description: '401 - corrupted json, 402 - validation error, 403 - RAN in wrong state, 404 - resource not found, 500 - RNIB error, 501 - internal problem, 502 - RMR error, 503 - RSM error'
errorMessage:
type: string
description: Human readable text