fa8efc5b7becaf0cc5e0cbdcb6aeaa5d9172b1b6
[ric-plt/e2mgr.git] / E2Manager / handlers / rmrmsghandlers / e2_node_config_update_notification_handler.go
1 //
2 // Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 //  platform project (RICP).
18
19 package rmrmsghandlers
20
21 import (
22         "e2mgr/logger"
23         "e2mgr/models"
24         "e2mgr/rmrCgo"
25         "e2mgr/services"
26         "e2mgr/services/rmrsender"
27         "e2mgr/utils"
28         "encoding/xml"
29
30         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
31         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
32 )
33
34 var (
35         toReplaceTags = []string{"reject", "ignore", "procedureCode", "id", "RANfunctionID-Item", "RANfunctionsID-List", "success", "s1", "ng", "e1", "f1", "w1", "x1", "xn"}
36 )
37
38 type E2nodeConfigUpdateNotificationHandler struct {
39         logger          *logger.Logger
40         rNibDataService services.RNibDataService
41         rmrSender       *rmrsender.RmrSender
42 }
43
44 func NewE2nodeConfigUpdateNotificationHandler(logger *logger.Logger, rNibDataService services.RNibDataService, rmrSender *rmrsender.RmrSender) *E2nodeConfigUpdateNotificationHandler {
45         return &E2nodeConfigUpdateNotificationHandler{
46                 logger:          logger,
47                 rNibDataService: rNibDataService,
48                 rmrSender:       rmrSender,
49         }
50 }
51
52 func (e *E2nodeConfigUpdateNotificationHandler) Handle(request *models.NotificationRequest) {
53         e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - RAN name: %s - received E2_Config_Update. Payload: %x", request.RanName, request.Payload)
54         e2NodeConfig, err := e.parseE2NodeConfigurationUpdate(request.Payload)
55         if err != nil {
56                 e.logger.Errorf(err.Error())
57                 return
58         }
59         e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - RIC_E2_Node_Config_Update parsed successfully")
60
61         nodebInfo, err := e.rNibDataService.GetNodeb(request.RanName)
62
63         if err != nil {
64                 switch v := err.(type) {
65                 case *common.ResourceNotFoundError:
66                         e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - failed to get nodeB, E2nodeConfigUpdate will not be processed further.")
67                 default:
68                         e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", request.RanName, v)
69                 }
70                 return
71         }
72         e.updateE2nodeConfig(e2NodeConfig, nodebInfo)
73         e.handleSuccessfulResponse(e2NodeConfig, request, nodebInfo)
74 }
75
76 func (e *E2nodeConfigUpdateNotificationHandler) updateE2nodeConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
77         e.handleAddConfig(e2nodeConfig, nodebInfo)
78         e.handleUpdateConfig(e2nodeConfig, nodebInfo)
79         e.handleDeleteConfig(e2nodeConfig, nodebInfo)
80         e.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
81 }
82
83 func (e *E2nodeConfigUpdateNotificationHandler) compareConfigIDs(n1, n2 entities.E2NodeComponentConfig) bool {
84         if n1.E2NodeComponentInterfaceType != n2.E2NodeComponentInterfaceType {
85                 return false
86         }
87
88         switch n1.E2NodeComponentInterfaceType {
89         case entities.E2NodeComponentInterfaceType_ng:
90                 return n1.GetE2NodeComponentInterfaceTypeNG().GetAmfName() == n2.GetE2NodeComponentInterfaceTypeNG().GetAmfName()
91         case entities.E2NodeComponentInterfaceType_xn:
92                 // TODO -- Not supported yet
93                 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type Xn is not supported")
94         case entities.E2NodeComponentInterfaceType_e1:
95                 return n1.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId() == n2.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId()
96         case entities.E2NodeComponentInterfaceType_f1:
97                 return n1.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId() == n2.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId()
98         case entities.E2NodeComponentInterfaceType_w1:
99                 return n1.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId() == n2.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId()
100         case entities.E2NodeComponentInterfaceType_s1:
101                 return n1.GetE2NodeComponentInterfaceTypeS1().GetMmeName() == n2.GetE2NodeComponentInterfaceTypeS1().GetMmeName()
102
103         case entities.E2NodeComponentInterfaceType_x2:
104                 // TODO -- Not supported yet
105                 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type X2 is not supported")
106         default:
107                 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type not supported")
108         }
109         return false
110 }
111
112 func (e *E2nodeConfigUpdateNotificationHandler) handleAddConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
113         var result []*entities.E2NodeComponentConfig
114
115         additionList := e2nodeConfig.ExtractConfigAdditionList()
116         for i, _ := range additionList {
117                 result = append(result, &additionList[i])
118         }
119
120         if nodebInfo.NodeType == entities.Node_ENB {
121                 nodebInfo.GetEnb().NodeConfigs = append(result, nodebInfo.GetEnb().NodeConfigs...)
122
123         } else {
124                 nodebInfo.GetGnb().NodeConfigs = append(result, nodebInfo.GetGnb().NodeConfigs...)
125         }
126 }
127
128 func (e *E2nodeConfigUpdateNotificationHandler) handleUpdateConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
129         updateList := e2nodeConfig.ExtractConfigUpdateList()
130         if nodebInfo.GetNodeType() == entities.Node_GNB {
131                 for i := 0; i < len(updateList); i++ {
132                         u := updateList[i]
133                         if nodebInfo.GetNodeType() == entities.Node_GNB {
134                                 for j := 0; j < len(nodebInfo.GetGnb().NodeConfigs); j++ {
135                                         if e.compareConfigIDs(u, *nodebInfo.GetGnb().NodeConfigs[j]) {
136                                                 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
137                                                 nodebInfo.GetGnb().NodeConfigs[i] = &u
138                                                 break
139                                         } else {
140                                                 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - dint match")
141                                         }
142                                 }
143                         }
144                 }
145         } else {
146                 for i := 0; i < len(updateList); i++ {
147                         u := updateList[i]
148                         if nodebInfo.GetNodeType() == entities.Node_ENB {
149                                 for j := 0; j < len(nodebInfo.GetEnb().NodeConfigs); j++ {
150                                         v := nodebInfo.GetEnb().NodeConfigs[j]
151                                         if e.compareConfigIDs(u, *v) {
152                                                 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
153                                                 nodebInfo.GetEnb().NodeConfigs[i] = &u
154                                                 break
155                                         }
156                                 }
157                         }
158
159                 }
160         }
161 }
162
163 func (e *E2nodeConfigUpdateNotificationHandler) handleDeleteConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
164         deleteList := e2nodeConfig.ExtractConfigDeletionList()
165
166         for _, u := range deleteList {
167                 if nodebInfo.GetNodeType() == entities.Node_ENB {
168                         for i, v := range nodebInfo.GetEnb().NodeConfigs {
169                                 if e.compareConfigIDs(u, *v) {
170                                         nodebInfo.GetEnb().NodeConfigs = removeIndex(nodebInfo.GetEnb().GetNodeConfigs(), i)
171                                         break
172                                 }
173                         }
174                 }
175
176                 if nodebInfo.GetNodeType() == entities.Node_GNB {
177                         for i, v := range nodebInfo.GetGnb().NodeConfigs {
178                                 if e.compareConfigIDs(u, *v) {
179                                         nodebInfo.GetGnb().NodeConfigs = removeIndex(nodebInfo.GetGnb().GetNodeConfigs(), i)
180                                         break
181                                 }
182                         }
183                 }
184         }
185 }
186
187 func removeIndex(s []*entities.E2NodeComponentConfig, index int) []*entities.E2NodeComponentConfig {
188         if index < len(s) {
189                 return append(s[:index], s[index+1:]...)
190         }
191         return s
192 }
193
194 func (e *E2nodeConfigUpdateNotificationHandler) parseE2NodeConfigurationUpdate(payload []byte) (*models.E2nodeConfigurationUpdateMessage, error) {
195         e2nodeConfig := models.E2nodeConfigurationUpdateMessage{}
196         err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2nodeConfig.E2APPDU))
197
198         if err != nil {
199                 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - error in parsing request message: %+v", err)
200                 return nil, err
201         }
202         e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - Unmarshalling is successful %v", e2nodeConfig.E2APPDU.InitiatingMessage.ProcedureCode)
203         return &e2nodeConfig, nil
204 }
205
206 func (e *E2nodeConfigUpdateNotificationHandler) handleSuccessfulResponse(e2NodeConfigUpdate *models.E2nodeConfigurationUpdateMessage, request *models.NotificationRequest, nodebInfo *entities.NodebInfo) error {
207         e2nodeConfigUpdateResp := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(e2NodeConfigUpdate)
208         payLoad, err := xml.Marshal(e2nodeConfigUpdateResp)
209         if err != nil {
210                 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", payLoad)
211         }
212
213         payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
214         e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Sending RIC_SERVICE_UPDATE_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
215         msg := models.NewRmrMessage(rmrCgo.RIC_SERVICE_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
216         err = e.rmrSender.Send(msg)
217         return err
218 }