return nil, errors.New("allocation failure (pdu)")
}
- r.logger.Infof("#x2apPdu_asn1_unpacker.UnpackX2apPdu - Packed pdu(%d):%x", len(packedBuf), packedBuf)
-
errBuf := make([]C.char, r.maxMessageBufferSize)
if !C.per_unpack_pdu(pdu, C.ulong(len(packedBuf)), (*C.uchar)(unsafe.Pointer(&packedBuf[0])), C.ulong(len(errBuf)), &errBuf[0]) {
return nil, errors.New(fmt.Sprintf("unpacking error: %s", C.GoString(&errBuf[0])))
packedBufSize := C.ulong(len(packedBuf))
pduAsString := ""
- pLMNIdentities := make([]*C.char, len(request.CellIdList))
- eUTRANCellIdentifiers := make([]*C.char, len(request.CellIdList))
+ pLMNIdentities := make([]*C.uchar, len(request.CellIdList))
+ eUTRANCellIdentifiers := make([]*C.uchar, len(request.CellIdList))
for i, cellID := range request.CellIdList {
- var pLMNIdentity, eUTRANCellIdentifier string
+ var pLMNIdentity, eUTRANCellIdentifier []byte
if _, err := fmt.Sscanf(cellID, "%x:%x", &pLMNIdentity, &eUTRANCellIdentifier); err != nil {
return nil, "", fmt.Errorf("BuildPackedResourceStatusRequest() - unexpected CellID value [%s]@%d (want: \"<PLMNIdentifier>:<eUTRANCellIdentifier>\"), err: %s", cellID, i, err)
}
- pLMNIdentities[i], eUTRANCellIdentifiers[i] = C.CString(pLMNIdentity), C.CString(eUTRANCellIdentifier)
+ pLMNIdentities[i], eUTRANCellIdentifiers[i] = (*C.uchar)(C.CBytes(pLMNIdentity)), (*C.uchar)(C.CBytes(eUTRANCellIdentifier))
}
defer func() {
h.logger.Errorf("#ResourceStatusFailureHandler.Handle - RAN name: %s - unpack failed. Error: %v", request.RanName, err)
return
}
- h.logger.Infof("#ResourceStatusFailureHandler.Handle - RAN name: %s - message: %s", request.RanName, pduAsString)
+ h.logger.Debugf("#ResourceStatusFailureHandler.Handle - RAN name: %s - message: %s", request.RanName, pduAsString)
}
response, err := h.converter.Convert(request.Payload)
if err != nil {
args := m.Called(rsmRanInfo)
return args.Error(0)
}
+
+func (m *RsmWriterMock) SaveRsmGeneralConfiguration(cfg *models.RsmGeneralConfiguration) error {
+ args := m.Called(cfg)
+ return args.Error(0)
+}
"encoding/json"
"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
"reflect"
- "rsm/enums"
"rsm/models"
)
sdl common.ISdlInstance
}
-/*
-RNibReader interface allows retrieving data from redis BD by various keys
-*/
+// RsmReader interface allows retrieving data from redis BD by various keys
type RsmReader interface {
GetRsmGeneralConfiguration() (*models.RsmGeneralConfiguration, error)
GetRsmRanInfo(ranName string) (*models.RsmRanInfo, error)
}
-/*
-GetRNibReader returns reference to RNibReader
-*/
+// GetRsmReader returns reference to RsmReader
func GetRsmReader(sdl common.ISdlInstance) RsmReader {
return &rsmReaderInstance{sdl: sdl}
}
+// GetRsmRanInfo returns the rsm data associated with ran 'ranName'
func (r *rsmReaderInstance) GetRsmRanInfo(ranName string) (*models.RsmRanInfo, error) {
key, err := common.ValidateAndBuildNodeBNameKey(ranName)
return rsmRanInfo, nil
}
-// TODO: implement
+// GetRsmGeneralConfiguration returns resource status request related configuration
func (r *rsmReaderInstance) GetRsmGeneralConfiguration() (*models.RsmGeneralConfiguration, error) {
- return &models.RsmGeneralConfiguration{
- EnableResourceStatus: true,
- 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,
- }, nil
+ cfg := &models.RsmGeneralConfiguration{}
+ err := r.getByKeyAndUnmarshal(buildRsmGeneralConfigurationKey(), cfg)
+ return cfg, err
}
+// getByKeyAndUnmarshal returns the value that is associated with key 'key' as a Go structure
func (r *rsmReaderInstance) getByKeyAndUnmarshal(key string, entity interface{}) error {
data, err := r.sdl.Get([]string{key})
if err != nil {
}
return common.NewResourceNotFoundErrorf("#rsmReader.getByKeyAndUnmarshal - entity of type %s not found. Key: %s", reflect.TypeOf(entity).String(), key)
}
+
+func buildRsmGeneralConfigurationKey() string {
+ return "CFG:GENERAL:v1.0.0"
+}
--- /dev/null
+/*******************************************************************************
+ *
+ * Copyright (c) 2019 AT&T Intellectual Property.
+ *
+ * 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 rsmdb
+
+import (
+ "fmt"
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+// "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
+ "github.com/stretchr/testify/assert"
+// "os"
+ "rsm/enums"
+ "rsm/mocks"
+ "rsm/models"
+ "testing"
+)
+
+func TestGetRsmRanInfo(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ reader := GetRsmReader(sdl)
+ ranName := "test1"
+ key, _ := common.ValidateAndBuildNodeBNameKey(ranName)
+ infoAsGoType := models.RsmRanInfo{
+ RanName: ranName,
+ Enb1MeasurementId: 1,
+ Enb2MeasurementId: 2,
+ Action: enums.Start,
+ ActionStatus: false,
+ }
+ infoAsDbType:= "{\"ranName\":\"test1\",\"enb1MeasurementId\":1,\"enb2MeasurementId\":2,\"action\":\"start\",\"actionStatus\":false}"
+ sdl.On("Get", []string{key}).Return(map[string]interface{}{key: infoAsDbType}, nil)
+ info, err := reader.GetRsmRanInfo(ranName)
+ if err != nil {
+ t.Errorf("want: success, got: error: %v\n", err)
+ }
+ assert.Equal(t, info, &infoAsGoType)
+}
+
+func TestGetRsmRanInfoValidationError(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ reader := GetRsmReader(sdl)
+ ranName := ""
+ key, _ := common.ValidateAndBuildNodeBNameKey(ranName)
+ sdl.On("Get", []string{key}).Return(map[string]interface{}{key: ""}, nil)
+ _, err := reader.GetRsmRanInfo(ranName)
+ assert.NotNil(t, err)
+ assert.Equal(t, err.Error(), "#utils.ValidateAndBuildNodeBNameKey - an empty inventory name received")
+}
+
+func TestGetRsmRanInfoDbError(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ reader := GetRsmReader(sdl)
+ ranName := "test1"
+ key, _ := common.ValidateAndBuildNodeBNameKey(ranName)
+ sdl.On("Get", []string{key}).Return((map[string]interface{})(nil), fmt.Errorf("db error"))
+ _, err := reader.GetRsmRanInfo(ranName)
+ assert.NotNil(t, err)
+ assert.Equal(t, err.Error(), "db error")
+}
+
+func TestGetGeneralConfiguration(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ reader := GetRsmReader(sdl)
+ var testCases = []struct {
+ cfgAsGoType models.RsmGeneralConfiguration
+ cfgAsDbType string
+ }{
+ {
+ cfgAsGoType: models.RsmGeneralConfiguration{
+ EnableResourceStatus: true,
+ 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,
+ },
+
+ cfgAsDbType: "{\"enableResourceStatus\":true,\"partialSuccessAllowed\":true,\"prbPeriodic\":true,\"tnlLoadIndPeriodic\":true,\"wwLoadIndPeriodic\":true,\"absStatusPeriodic\":true,\"rsrpMeasurementPeriodic\":true,\"csiPeriodic\":true,\"periodicityMs\":1,\"periodicityRsrpMeasurementMs\":3,\"periodicityCsiMs\":3}",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.cfgAsDbType, func(t *testing.T) {
+ key := buildRsmGeneralConfigurationKey()
+ sdl.On("Get", []string{key}).Return(map[string]interface{}{key: tc.cfgAsDbType}, nil)
+ cfg, err := reader.GetRsmGeneralConfiguration()
+ if err != nil {
+ t.Errorf("want: success, got: error: %v\n", err)
+ }
+ assert.Equal(t, cfg, &tc.cfgAsGoType)
+ })
+ }
+}
+
+func TestGetGeneralConfigurationNotFound(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ reader := GetRsmReader(sdl)
+
+ key := buildRsmGeneralConfigurationKey()
+ sdl.On("Get", []string{key}).Return((map[string]interface{})(nil), nil)
+ _, err := reader.GetRsmGeneralConfiguration()
+ assert.NotNil(t, err)
+ assert.Equal(t, err.Error(), "#rsmReader.getByKeyAndUnmarshal - entity of type *models.RsmGeneralConfiguration not found. Key: CFG:GENERAL:v1.0.0")
+}
+
+func TestGetGeneralConfigurationDbError(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ reader := GetRsmReader(sdl)
+
+ key := buildRsmGeneralConfigurationKey()
+ sdl.On("Get", []string{key}).Return((map[string]interface{})(nil), fmt.Errorf("db error"))
+ _, err := reader.GetRsmGeneralConfiguration()
+ assert.NotNil(t, err)
+ assert.Equal(t, err.Error(), "db error")
+}
+
+func TestGetGeneralConfigurationUnmarshalError(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ reader := GetRsmReader(sdl)
+ cfgAsDbTYpe := "{\"enableResourceStatus\":true, partialSuccessAllowed\":true,\"prbPeriodic\":true,\"tnlLoadIndPeriodic\":true,\"wwLoadIndPeriodic\":true,\"absStatusPeriodic\":true,\"rsrpMeasurementPeriodic\":true,\"csiPeriodic\":true,\"periodicityMs\":1,\"periodicityRsrpMeasurementMs\":3,\"periodicityCsiMs\":3}"
+ key := buildRsmGeneralConfigurationKey()
+ sdl.On("Get", []string{key}).Return(map[string]interface{}{key: cfgAsDbTYpe}, nil)
+ _, err := reader.GetRsmGeneralConfiguration()
+ assert.NotNil(t, err)
+ assert.Equal(t, err.Error(), "invalid character 'p' looking for beginning of object key string")
+}
+
+/*
+Test against redis.
+Test execution depends on the existence of the environment variable DBAAS_SERVICE_HOST.
+*
+
+func TestGetGeneralConfigurationIntegration(t *testing.T) {
+ if len(os.Getenv("DBAAS_SERVICE_HOST")) == 0 {
+ return
+ }
+ db := sdlgo.NewDatabase()
+ sdl := sdlgo.NewSdlInstance("rsm", db)
+ reader := GetRsmReader(sdl)
+ cfgAsGoType := models.RsmGeneralConfiguration{
+ EnableResourceStatus: true,
+ 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,
+ }
+ cfg, err := reader.GetRsmGeneralConfiguration()
+ if err != nil {
+ t.Errorf("want: success, got: error: %v\n", err)
+ }
+
+ assert.Equal(t, &cfgAsGoType, cfg)
+}
+*/
\ No newline at end of file
sdl common.ISdlInstance
}
-/*
-RNibReader interface allows retrieving data from redis BD by various keys
-*/
+// RsmWriter interface allows inserting/updating data to/in redis BD with various keys
type RsmWriter interface {
SaveRsmRanInfo(rsmRanInfo *models.RsmRanInfo) error
+ SaveRsmGeneralConfiguration(cfg *models.RsmGeneralConfiguration) error
}
-/*
-GetRNibReader returns reference to RNibReader
-*/
+// GetRsmWriter returns reference to RsmWriter
func GetRsmWriter(sdl common.ISdlInstance) RsmWriter {
return &rsmWriterInstance{sdl: sdl}
}
+// SaveRsmRanInfo saves the ran related rsm data with key RanName
func (r *rsmWriterInstance) SaveRsmRanInfo(rsmRanInfo *models.RsmRanInfo) error {
nodebNameKey, err := common.ValidateAndBuildNodeBNameKey(rsmRanInfo.RanName)
return err
}
- data, err := json.Marshal(rsmRanInfo)
+ return r.SaveWithKeyAndMarshal(nodebNameKey, rsmRanInfo)
+}
+
+// SaveRsmGeneralConfiguration saves the resource status request related configuration
+func (r *rsmWriterInstance) SaveRsmGeneralConfiguration(cfg *models.RsmGeneralConfiguration) error {
+
+ return r.SaveWithKeyAndMarshal(buildRsmGeneralConfigurationKey(), cfg)
+}
+
+
+// SaveWithKeyAndMarshal marshals
+func (r *rsmWriterInstance) SaveWithKeyAndMarshal(key string, entity interface{}) error {
+
+ data, err := json.Marshal(entity)
if err != nil {
return common.NewInternalError(err)
}
var pairs []interface{}
- pairs = append(pairs, nodebNameKey, data)
+ pairs = append(pairs, key, data)
err = r.sdl.Set(pairs)
--- /dev/null
+/*******************************************************************************
+ *
+ * Copyright (c) 2019 AT&T Intellectual Property.
+ *
+ * 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 rsmdb
+
+import (
+ "fmt"
+ "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+ "github.com/stretchr/testify/assert"
+ "rsm/enums"
+ "rsm/mocks"
+ "rsm/models"
+ "testing"
+)
+
+func TestSaveRsmRanInfo(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ writer := GetRsmWriter(sdl)
+ ranName := "test1"
+ key, _ := common.ValidateAndBuildNodeBNameKey(ranName)
+ infoAsGoType := models.RsmRanInfo{
+ RanName: ranName,
+ Enb1MeasurementId: 1,
+ Enb2MeasurementId: 2,
+ Action: enums.Start,
+ ActionStatus: false,
+ }
+ infoAsDbType:= "{\"ranName\":\"test1\",\"enb1MeasurementId\":1,\"enb2MeasurementId\":2,\"action\":\"start\",\"actionStatus\":false}"
+ sdl.On("Set",[]interface{}{[]interface{}{key, []byte(infoAsDbType)}}).Return(nil)
+ err := writer.SaveRsmRanInfo(&infoAsGoType)
+ if err != nil {
+ t.Errorf("want: success, got: error: %v\n", err)
+ }
+ sdl.AssertNumberOfCalls(t, "Set",1)
+}
+
+
+func TestSaveRsmRanInfoValidationError(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ writer := GetRsmWriter(sdl)
+ ranName := ""
+ key, _ := common.ValidateAndBuildNodeBNameKey(ranName)
+ infoAsGoType := models.RsmRanInfo{
+ RanName: ranName,
+ Enb1MeasurementId: 1,
+ Enb2MeasurementId: 2,
+ Action: enums.Start,
+ ActionStatus: false,
+ }
+ infoAsDbType:= "{\"ranName\":\"test1\",\"enb1MeasurementId\":1,\"enb2MeasurementId\":2,\"action\":\"start\",\"actionStatus\":false}"
+ sdl.On("Set",[]interface{}{[]interface{}{key, []byte(infoAsDbType)}}).Return(nil)
+ err := writer.SaveRsmRanInfo(&infoAsGoType)
+ assert.NotNil(t, err)
+ assert.Equal(t, err.Error(), "#utils.ValidateAndBuildNodeBNameKey - an empty inventory name received")
+}
+
+
+func TestSaveGeneralConfiguration(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ writer := GetRsmWriter(sdl)
+ var testCases = []struct {
+ cfgAsGoType models.RsmGeneralConfiguration
+ cfgAsDbType string
+ }{
+ {
+ cfgAsGoType: models.RsmGeneralConfiguration{
+ EnableResourceStatus: true,
+ 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,
+ },
+
+ cfgAsDbType: "{\"enableResourceStatus\":true,\"partialSuccessAllowed\":true,\"prbPeriodic\":true,\"tnlLoadIndPeriodic\":true,\"wwLoadIndPeriodic\":true,\"absStatusPeriodic\":true,\"rsrpMeasurementPeriodic\":true,\"csiPeriodic\":true,\"periodicityMs\":1,\"periodicityRsrpMeasurementMs\":3,\"periodicityCsiMs\":3}",
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.cfgAsDbType, func(t *testing.T) {
+ key:= buildRsmGeneralConfigurationKey()
+ sdl.On("Set",[]interface{}{[]interface{}{key, []byte(tc.cfgAsDbType)}}).Return(nil)
+ err := writer.SaveRsmGeneralConfiguration(&tc.cfgAsGoType)
+ if err != nil {
+ t.Errorf("want: success, got: error: %v\n", err)
+ }
+
+ sdl.AssertNumberOfCalls(t, "Set",1)
+ })
+ }
+}
+
+
+func TestSaveGeneralConfigurationDbError(t *testing.T) {
+ sdl := &mocks.MockSdlInstance{}
+ writer := GetRsmWriter(sdl)
+
+ cfgAsGoType:= models.RsmGeneralConfiguration{
+ EnableResourceStatus: true,
+ 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,
+ }
+ cfgAsDbTYpe:= "{\"enableResourceStatus\":true,\"partialSuccessAllowed\":true,\"prbPeriodic\":true,\"tnlLoadIndPeriodic\":true,\"wwLoadIndPeriodic\":true,\"absStatusPeriodic\":true,\"rsrpMeasurementPeriodic\":true,\"csiPeriodic\":true,\"periodicityMs\":1,\"periodicityRsrpMeasurementMs\":3,\"periodicityCsiMs\":3}"
+ key:= buildRsmGeneralConfigurationKey()
+ sdl.On("Set",[]interface{}{[]interface{}{key, []byte(cfgAsDbTYpe)}}).Return(fmt.Errorf("db error"))
+ err := writer.SaveRsmGeneralConfiguration(&cfgAsGoType)
+ assert.NotNil(t, err)
+ assert.Equal(t, err.Error(), "db error")
+}