Fix MType which sending e2nodeConfig response
[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
60         e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - RIC_E2_Node_Config_Update parsed successfully %+v", e2NodeConfig)
61
62         nodebInfo, err := e.rNibDataService.GetNodeb(request.RanName)
63
64         if err != nil {
65                 switch v := err.(type) {
66                 case *common.ResourceNotFoundError:
67                         e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - failed to get nodeB, E2nodeConfigUpdate will not be processed further.")
68                 default:
69                         e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - nobeB entity of RanName:%s absent in RNIB. Error: %s", request.RanName, v)
70                 }
71                 return
72         }
73         e.updateE2nodeConfig(e2NodeConfig, nodebInfo)
74         e.handleSuccessfulResponse(e2NodeConfig, request, nodebInfo)
75 }
76
77 func (e *E2nodeConfigUpdateNotificationHandler) updateE2nodeConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
78         e.handleAddConfig(e2nodeConfig, nodebInfo)
79         e.handleUpdateConfig(e2nodeConfig, nodebInfo)
80         e.handleDeleteConfig(e2nodeConfig, nodebInfo)
81         e.rNibDataService.UpdateNodebInfoAndPublish(nodebInfo)
82 }
83
84 func (e *E2nodeConfigUpdateNotificationHandler) compareConfigIDs(n1, n2 entities.E2NodeComponentConfig) bool {
85         if n1.E2NodeComponentInterfaceType != n2.E2NodeComponentInterfaceType {
86                 return false
87         }
88
89         switch n1.E2NodeComponentInterfaceType {
90         case entities.E2NodeComponentInterfaceType_ng:
91                 return n1.GetE2NodeComponentInterfaceTypeNG().GetAmfName() == n2.GetE2NodeComponentInterfaceTypeNG().GetAmfName()
92         case entities.E2NodeComponentInterfaceType_xn:
93                 // TODO -- Not supported yet
94                 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type Xn is not supported")
95         case entities.E2NodeComponentInterfaceType_e1:
96                 return n1.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId() == n2.GetE2NodeComponentInterfaceTypeE1().GetGNBCuCpId()
97         case entities.E2NodeComponentInterfaceType_f1:
98                 return n1.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId() == n2.GetE2NodeComponentInterfaceTypeF1().GetGNBDuId()
99         case entities.E2NodeComponentInterfaceType_w1:
100                 return n1.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId() == n2.GetE2NodeComponentInterfaceTypeW1().GetNgenbDuId()
101         case entities.E2NodeComponentInterfaceType_s1:
102                 return n1.GetE2NodeComponentInterfaceTypeS1().GetMmeName() == n2.GetE2NodeComponentInterfaceTypeS1().GetMmeName()
103
104         case entities.E2NodeComponentInterfaceType_x2:
105                 // TODO -- Not supported yet
106                 e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type X2 is not supported")
107         default:
108                 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - Interface type not supported")
109         }
110         return false
111 }
112
113 func (e *E2nodeConfigUpdateNotificationHandler) handleAddConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
114         var result []*entities.E2NodeComponentConfig
115
116         additionList := e2nodeConfig.ExtractConfigAdditionList()
117         for i, _ := range additionList {
118                 result = append(result, &additionList[i])
119         }
120
121         if nodebInfo.NodeType == entities.Node_ENB {
122                 nodebInfo.GetEnb().NodeConfigs = append(result, nodebInfo.GetEnb().NodeConfigs...)
123
124         } else {
125                 nodebInfo.GetGnb().NodeConfigs = append(result, nodebInfo.GetGnb().NodeConfigs...)
126         }
127 }
128
129 func (e *E2nodeConfigUpdateNotificationHandler) handleUpdateConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
130         updateList := e2nodeConfig.ExtractConfigUpdateList()
131         if nodebInfo.GetNodeType() == entities.Node_GNB {
132                 for i := 0; i < len(updateList); i++ {
133                         u := updateList[i]
134                         if nodebInfo.GetNodeType() == entities.Node_GNB {
135                                 for j := 0; j < len(nodebInfo.GetGnb().NodeConfigs); j++ {
136                                         if e.compareConfigIDs(u, *nodebInfo.GetGnb().NodeConfigs[j]) {
137                                                 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
138                                                 nodebInfo.GetGnb().NodeConfigs[i] = &u
139                                                 break
140                                         } else {
141                                                 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - dint match")
142                                         }
143                                 }
144                         }
145                 }
146         } else {
147                 for i := 0; i < len(updateList); i++ {
148                         u := updateList[i]
149                         if nodebInfo.GetNodeType() == entities.Node_ENB {
150                                 for j := 0; j < len(nodebInfo.GetEnb().NodeConfigs); j++ {
151                                         v := nodebInfo.GetEnb().NodeConfigs[j]
152                                         if e.compareConfigIDs(u, *v) {
153                                                 e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - item at position [%d] should be updated", i)
154                                                 nodebInfo.GetEnb().NodeConfigs[i] = &u
155                                                 break
156                                         }
157                                 }
158                         }
159
160                 }
161         }
162 }
163
164 func (e *E2nodeConfigUpdateNotificationHandler) handleDeleteConfig(e2nodeConfig *models.E2nodeConfigurationUpdateMessage, nodebInfo *entities.NodebInfo) {
165         deleteList := e2nodeConfig.ExtractConfigDeletionList()
166
167         for _, u := range deleteList {
168                 if nodebInfo.GetNodeType() == entities.Node_ENB {
169                         for i, v := range nodebInfo.GetEnb().NodeConfigs {
170                                 if e.compareConfigIDs(u, *v) {
171                                         nodebInfo.GetEnb().NodeConfigs = removeIndex(nodebInfo.GetEnb().GetNodeConfigs(), i)
172                                         break
173                                 }
174                         }
175                 }
176
177                 if nodebInfo.GetNodeType() == entities.Node_GNB {
178                         for i, v := range nodebInfo.GetGnb().NodeConfigs {
179                                 if e.compareConfigIDs(u, *v) {
180                                         nodebInfo.GetGnb().NodeConfigs = removeIndex(nodebInfo.GetGnb().GetNodeConfigs(), i)
181                                         break
182                                 }
183                         }
184                 }
185         }
186 }
187
188 func removeIndex(s []*entities.E2NodeComponentConfig, index int) []*entities.E2NodeComponentConfig {
189         if index < len(s) {
190                 return append(s[:index], s[index+1:]...)
191         }
192         return s
193 }
194
195 func (e *E2nodeConfigUpdateNotificationHandler) parseE2NodeConfigurationUpdate(payload []byte) (*models.E2nodeConfigurationUpdateMessage, error) {
196         e2nodeConfig := models.E2nodeConfigurationUpdateMessage{}
197         err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2nodeConfig.E2APPDU))
198
199         if err != nil {
200                 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.Handle - error in parsing request message: %+v", err)
201                 return nil, err
202         }
203         e.logger.Debugf("#E2nodeConfigUpdateNotificationHandler.Handle - Unmarshalling is successful %v", e2nodeConfig.E2APPDU.InitiatingMessage.ProcedureCode)
204         return &e2nodeConfig, nil
205 }
206
207 func (e *E2nodeConfigUpdateNotificationHandler) handleSuccessfulResponse(e2NodeConfigUpdate *models.E2nodeConfigurationUpdateMessage, request *models.NotificationRequest, nodebInfo *entities.NodebInfo) error {
208         e2nodeConfigUpdateResp := models.NewE2nodeConfigurationUpdateSuccessResponseMessage(e2NodeConfigUpdate)
209         payLoad, err := xml.Marshal(e2nodeConfigUpdateResp)
210         if err != nil {
211                 e.logger.Errorf("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Error marshalling RIC_SERVICE_UPDATE_ACK. Payload: %s", payLoad)
212         }
213
214         payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, toReplaceTags)
215         e.logger.Infof("#E2nodeConfigUpdateNotificationHandler.sendUpdateAck - Sending RIC_E2nodeConfigUpdate_ACK to RAN name: %s with payload %s", nodebInfo.RanName, payLoad)
216         msg := models.NewRmrMessage(rmrCgo.RIC_E2NODE_CONFIG_UPDATE_ACK, nodebInfo.RanName, payLoad, request.TransactionId, request.GetMsgSrc())
217         err = e.rmrSender.Send(msg)
218         return err
219 }