| // |
| // 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 rNibWriter |
| |
| import ( |
| "e2mgr/configuration" |
| "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/golang/protobuf/proto" |
| ) |
| |
| const ( |
| E2TAddressesKey = "E2TAddresses" |
| RanAddedEvent = "ADDED" |
| RanUpdatedEvent = "UPDATED" |
| RanDeletedEvent = "DELETED" |
| ) |
| |
| type rNibWriterInstance struct { |
| sdl common.ISdlInstance |
| rnibWriterConfig configuration.RnibWriterConfig |
| } |
| |
| /* |
| RNibWriter interface allows saving data to the redis DB |
| */ |
| type RNibWriter interface { |
| SaveNodeb(nodebInfo *entities.NodebInfo) error |
| UpdateNodebInfo(nodebInfo *entities.NodebInfo) error |
| UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error |
| SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error |
| SaveE2TInstance(e2tInstance *entities.E2TInstance) error |
| SaveE2TAddresses(addresses []string) error |
| RemoveE2TInstance(e2tAddress string) error |
| UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error |
| RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error |
| UpdateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, ent string) error |
| SaveGeneralConfiguration(config *entities.GeneralConfiguration) error |
| RemoveEnb(nodebInfo *entities.NodebInfo) error |
| RemoveServedCells(inventoryName string, servedCells []*entities.ServedCellInfo) error |
| UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error |
| AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error |
| RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error |
| AddEnb(nodebInfo *entities.NodebInfo) error |
| } |
| |
| /* |
| GetRNibWriter returns reference to RNibWriter |
| */ |
| |
| func GetRNibWriter(sdl common.ISdlInstance, rnibWriterConfig configuration.RnibWriterConfig) RNibWriter { |
| return &rNibWriterInstance{sdl: sdl, rnibWriterConfig: rnibWriterConfig} |
| } |
| |
| func getChannelsAndEventsPair(channel string, ranName string, event string) []string { |
| return []string{channel, fmt.Sprintf("%s_%s", ranName, event)} |
| } |
| |
| func (w *rNibWriterInstance) AddNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error { |
| nbIdData, err := proto.Marshal(nbIdentity) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| err = w.sdl.AddMember(nodeType.String(), nbIdData) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) RemoveServedNrCells(inventoryName string, servedNrCells []*entities.ServedNRCell) error { |
| cellKeysToRemove := buildServedNRCellKeysToRemove(inventoryName, servedNrCells) |
| |
| err := w.sdl.Remove(cellKeysToRemove) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) RemoveServedCells(inventoryName string, servedCells []*entities.ServedCellInfo) error { |
| cellKeysToRemove := buildServedCellInfoKeysToRemove(inventoryName, servedCells) |
| |
| err := w.sdl.Remove(cellKeysToRemove) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) SaveGeneralConfiguration(config *entities.GeneralConfiguration) error { |
| |
| err := w.SaveWithKeyAndMarshal(common.BuildGeneralConfigurationKey(), config) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| /* |
| SaveNodeb saves nodeB entity data in the redis DB according to the specified data model |
| */ |
| func (w *rNibWriterInstance) SaveNodeb(nodebInfo *entities.NodebInfo) error { |
| |
| data, err := proto.Marshal(nodebInfo) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| var pairs []interface{} |
| key, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.RanName) |
| |
| if rNibErr != nil { |
| return rNibErr |
| } |
| |
| pairs = append(pairs, key, data) |
| |
| if nodebInfo.GlobalNbId != nil { |
| |
| key, rNibErr = common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId()) |
| if rNibErr != nil { |
| return rNibErr |
| } |
| pairs = append(pairs, key, data) |
| } |
| |
| if nodebInfo.GetEnb() != nil { |
| pairs, rNibErr = appendEnbCells(nodebInfo.RanName, nodebInfo.GetEnb().GetServedCells(), pairs) |
| if rNibErr != nil { |
| return rNibErr |
| } |
| } |
| |
| if nodebInfo.GetGnb() != nil { |
| pairs, rNibErr = appendGnbCells(nodebInfo.RanName, nodebInfo.GetGnb().GetServedNrCells(), pairs) |
| if rNibErr != nil { |
| return rNibErr |
| } |
| } |
| |
| err = w.sdl.Set(pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) AddEnb(nodebInfo *entities.NodebInfo) error { |
| |
| data, err := proto.Marshal(nodebInfo) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| var pairs []interface{} |
| key, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.RanName) |
| |
| if rNibErr != nil { |
| return rNibErr |
| } |
| |
| pairs = append(pairs, key, data) |
| |
| if nodebInfo.GlobalNbId != nil { |
| |
| key, rNibErr = common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId()) |
| if rNibErr != nil { |
| return rNibErr |
| } |
| pairs = append(pairs, key, data) |
| } |
| |
| pairs, rNibErr = appendEnbCells(nodebInfo.RanName, nodebInfo.GetEnb().GetServedCells(), pairs) |
| if rNibErr != nil { |
| return rNibErr |
| } |
| |
| channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanAddedEvent) |
| err = w.sdl.SetAndPublish(channelsAndEvents, pairs) |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) UpdateGnbCells(nodebInfo *entities.NodebInfo, servedNrCells []*entities.ServedNRCell) error { |
| |
| pairs, err := buildUpdateNodebInfoPairs(nodebInfo) |
| |
| if err != nil { |
| return err |
| } |
| |
| pairs, err = appendGnbCells(nodebInfo.RanName, servedNrCells, pairs) |
| |
| if err != nil { |
| return err |
| } |
| |
| channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent) |
| err = w.sdl.SetAndPublish(channelsAndEvents, pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func buildServedNRCellKeysToRemove(inventoryName string, servedNrCellsToRemove []*entities.ServedNRCell) []string { |
| |
| var cellKeysToRemove []string |
| |
| for _, cell := range servedNrCellsToRemove { |
| |
| key, _ := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId()) |
| |
| if len(key) != 0 { |
| cellKeysToRemove = append(cellKeysToRemove, key) |
| } |
| |
| key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci()) |
| |
| if len(key) != 0 { |
| cellKeysToRemove = append(cellKeysToRemove, key) |
| } |
| } |
| |
| return cellKeysToRemove |
| } |
| |
| func buildServedCellInfoKeysToRemove(inventoryName string, servedCellsToRemove []*entities.ServedCellInfo) []string { |
| |
| var cellKeysToRemove []string |
| |
| for _, cell := range servedCellsToRemove { |
| |
| key, _ := common.ValidateAndBuildCellIdKey(cell.GetCellId()) |
| |
| if len(key) != 0 { |
| cellKeysToRemove = append(cellKeysToRemove, key) |
| } |
| |
| key, _ = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetPci()) |
| |
| if len(key) != 0 { |
| cellKeysToRemove = append(cellKeysToRemove, key) |
| } |
| } |
| |
| return cellKeysToRemove |
| } |
| |
| func buildUpdateNodebInfoPairs(nodebInfo *entities.NodebInfo) ([]interface{}, error) { |
| nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName()) |
| |
| if rNibErr != nil { |
| return []interface{}{}, rNibErr |
| } |
| |
| nodebIdKey, buildNodebIdKeyError := common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId()) |
| |
| data, err := proto.Marshal(nodebInfo) |
| |
| if err != nil { |
| return []interface{}{}, common.NewInternalError(err) |
| } |
| |
| pairs := []interface{}{nodebNameKey, data} |
| |
| if buildNodebIdKeyError == nil { |
| pairs = append(pairs, nodebIdKey, data) |
| } |
| |
| return pairs, nil |
| } |
| |
| func (w *rNibWriterInstance) buildRemoveEnbKeys(nodebInfo *entities.NodebInfo) ([]string, error) { |
| keys := buildServedCellInfoKeysToRemove(nodebInfo.GetRanName(), nodebInfo.GetEnb().GetServedCells()) |
| |
| nodebNameKey, rNibErr := common.ValidateAndBuildNodeBNameKey(nodebInfo.GetRanName()) |
| |
| if rNibErr != nil { |
| return []string{}, rNibErr |
| } |
| |
| keys = append(keys, nodebNameKey) |
| |
| nodebIdKey, buildNodebIdKeyError := common.ValidateAndBuildNodeBIdKey(nodebInfo.GetNodeType().String(), nodebInfo.GlobalNbId.GetPlmnId(), nodebInfo.GlobalNbId.GetNbId()) |
| |
| if buildNodebIdKeyError == nil { |
| keys = append(keys, nodebIdKey) |
| } |
| |
| return keys, nil |
| } |
| |
| func (w *rNibWriterInstance) RemoveNbIdentity(nodeType entities.Node_Type, nbIdentity *entities.NbIdentity) error { |
| nbIdData, err := proto.Marshal(nbIdentity) |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| err = w.sdl.RemoveMember(nodeType.String(), nbIdData) |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) updateNodebInfo(nodebInfo *entities.NodebInfo, publish bool) error { |
| |
| pairs, err := buildUpdateNodebInfoPairs(nodebInfo) |
| |
| if err != nil { |
| return err |
| } |
| |
| if publish { |
| channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent) |
| err = w.sdl.SetAndPublish(channelsAndEvents, pairs) |
| } else { |
| err = w.sdl.Set(pairs) |
| } |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| /* |
| UpdateNodebInfo... |
| */ |
| func (w *rNibWriterInstance) UpdateNodebInfo(nodebInfo *entities.NodebInfo) error { |
| return w.updateNodebInfo(nodebInfo, false) |
| } |
| |
| /* |
| UpdateNodebInfoAndPublish... |
| */ |
| func (w *rNibWriterInstance) UpdateNodebInfoAndPublish(nodebInfo *entities.NodebInfo) error { |
| return w.updateNodebInfo(nodebInfo, true) |
| } |
| |
| |
| /* |
| SaveRanLoadInformation stores ran load information for the provided ran |
| */ |
| func (w *rNibWriterInstance) SaveRanLoadInformation(inventoryName string, ranLoadInformation *entities.RanLoadInformation) error { |
| |
| key, rnibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName) |
| |
| if rnibErr != nil { |
| return rnibErr |
| } |
| |
| data, err := proto.Marshal(ranLoadInformation) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| var pairs []interface{} |
| pairs = append(pairs, key, data) |
| |
| err = w.sdl.Set(pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) SaveE2TInstance(e2tInstance *entities.E2TInstance) error { |
| |
| key, rnibErr := common.ValidateAndBuildE2TInstanceKey(e2tInstance.Address) |
| |
| if rnibErr != nil { |
| return rnibErr |
| } |
| |
| data, err := json.Marshal(e2tInstance) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| var pairs []interface{} |
| pairs = append(pairs, key, data) |
| |
| err = w.sdl.Set(pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) SaveE2TAddresses(addresses []string) error { |
| |
| data, err := json.Marshal(addresses) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| var pairs []interface{} |
| pairs = append(pairs, E2TAddressesKey, data) |
| |
| err = w.sdl.Set(pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) RemoveE2TInstance(address string) error { |
| key, rNibErr := common.ValidateAndBuildE2TInstanceKey(address) |
| if rNibErr != nil { |
| return rNibErr |
| } |
| err := w.sdl.Remove([]string{key}) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) SaveWithKeyAndMarshal(key string, entity interface{}) error { |
| |
| data, err := json.Marshal(entity) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| var pairs []interface{} |
| pairs = append(pairs, key, data) |
| |
| err = w.sdl.Set(pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| /* |
| UpdateNodebInfoOnConnectionStatusInversion... |
| */ |
| func (w *rNibWriterInstance) UpdateNodebInfoOnConnectionStatusInversion(nodebInfo *entities.NodebInfo, event string) error { |
| |
| pairs, err := buildUpdateNodebInfoPairs(nodebInfo) |
| |
| if err != nil { |
| return err |
| } |
| |
| err = w.sdl.SetAndPublish([]string{w.rnibWriterConfig.StateChangeMessageChannel, event}, pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) RemoveEnb(nodebInfo *entities.NodebInfo) error { |
| keysToRemove, err := w.buildRemoveEnbKeys(nodebInfo) |
| if err != nil { |
| return err |
| } |
| |
| channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanDeletedEvent) |
| err = w.sdl.RemoveAndPublish(channelsAndEvents, keysToRemove) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| func (w *rNibWriterInstance) UpdateEnb(nodebInfo *entities.NodebInfo, servedCells []*entities.ServedCellInfo) error { |
| |
| pairs, err := buildUpdateNodebInfoPairs(nodebInfo) |
| |
| if err != nil { |
| return err |
| } |
| |
| pairs, err = appendEnbCells(nodebInfo.RanName, servedCells, pairs) |
| |
| if err != nil { |
| return err |
| } |
| |
| channelsAndEvents := getChannelsAndEventsPair(w.rnibWriterConfig.RanManipulationMessageChannel, nodebInfo.RanName, RanUpdatedEvent) |
| err = w.sdl.SetAndPublish(channelsAndEvents, pairs) |
| |
| if err != nil { |
| return common.NewInternalError(err) |
| } |
| |
| return nil |
| } |
| |
| /* |
| Close the writer |
| */ |
| func Close() { |
| //Nothing to do |
| } |
| |
| func appendEnbCells(inventoryName string, cells []*entities.ServedCellInfo, pairs []interface{}) ([]interface{}, error) { |
| for _, cell := range cells { |
| cellEntity := entities.Cell{Type: entities.Cell_LTE_CELL, Cell: &entities.Cell_ServedCellInfo{ServedCellInfo: cell}} |
| cellData, err := proto.Marshal(&cellEntity) |
| if err != nil { |
| return pairs, common.NewInternalError(err) |
| } |
| key, rNibErr := common.ValidateAndBuildCellIdKey(cell.GetCellId()) |
| if rNibErr != nil { |
| return pairs, rNibErr |
| } |
| pairs = append(pairs, key, cellData) |
| key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetPci()) |
| if rNibErr != nil { |
| return pairs, rNibErr |
| } |
| pairs = append(pairs, key, cellData) |
| } |
| return pairs, nil |
| } |
| |
| func appendGnbCells(inventoryName string, cells []*entities.ServedNRCell, pairs []interface{}) ([]interface{}, error) { |
| for _, cell := range cells { |
| cellEntity := entities.Cell{Type: entities.Cell_NR_CELL, Cell: &entities.Cell_ServedNrCell{ServedNrCell: cell}} |
| cellData, err := proto.Marshal(&cellEntity) |
| if err != nil { |
| return pairs, common.NewInternalError(err) |
| } |
| key, rNibErr := common.ValidateAndBuildNrCellIdKey(cell.GetServedNrCellInformation().GetCellId()) |
| if rNibErr != nil { |
| return pairs, rNibErr |
| } |
| pairs = append(pairs, key, cellData) |
| key, rNibErr = common.ValidateAndBuildCellNamePciKey(inventoryName, cell.GetServedNrCellInformation().GetNrPci()) |
| if rNibErr != nil { |
| return pairs, rNibErr |
| } |
| pairs = append(pairs, key, cellData) |
| } |
| return pairs, nil |
| } |