J release: Release container Image
[ric-plt/e2mgr.git] / E2Manager / handlers / rmrmsghandlers / e2_reset_request_handler.go
1 //\r
2 // Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved.\r
3 //\r
4 // Licensed under the Apache License, Version 2.0 (the "License");\r
5 // you may not use this file except in compliance with the License.\r
6 // You may obtain a copy of the License at\r
7 //\r
8 //      http://www.apache.org/licenses/LICENSE-2.0\r
9 //\r
10 // Unless required by applicable law or agreed to in writing, software\r
11 // distributed under the License is distributed on an "AS IS" BASIS,\r
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13 // See the License for the specific language governing permissions and\r
14 // limitations under the License.\r
15 \r
16 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)\r
17 //  platform project (RICP).\r
18 \r
19 package rmrmsghandlers\r
20 \r
21 import (\r
22         "e2mgr/configuration"\r
23         "e2mgr/logger"\r
24         "e2mgr/managers"\r
25         "e2mgr/models"\r
26         "e2mgr/rmrCgo"\r
27         "e2mgr/services"\r
28         "e2mgr/services/rmrsender"\r
29         "e2mgr/utils"\r
30         "encoding/xml"\r
31         "time"\r
32 \r
33         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"\r
34 )\r
35 \r
36 const E2ResetRequestLogInfoElapsedTime = "#E2ResetRequestNotificationHandler.Handle - Summary: elapsed time for receiving and handling reset request message from E2 terminator: %f ms"\r
37 \r
38 var (\r
39         resetRequestEmptyTagsToReplaceToSelfClosingTags = []string{"reject", "ignore", "protocolIEs", "procedureCode", "ResetResponse", "ResetResponseIEs", "id", "criticality", "TransactionID"}\r
40 )\r
41 \r
42 type E2ResetRequestNotificationHandler struct {\r
43         logger                            *logger.Logger\r
44         rnibDataService                   services.RNibDataService\r
45         config                            *configuration.Configuration\r
46         rmrSender                         *rmrsender.RmrSender\r
47         ranResetManager                   *managers.RanResetManager\r
48         changeStatusToConnectedRanManager *managers.ChangeStatusToConnectedRanManager\r
49 }\r
50 \r
51 func NewE2ResetRequestNotificationHandler(logger *logger.Logger, rnibDataService services.RNibDataService, config *configuration.Configuration, rmrSender *rmrsender.RmrSender, ranResetManager *managers.RanResetManager, changeStatusToConnectedRanManager *managers.ChangeStatusToConnectedRanManager) *E2ResetRequestNotificationHandler {\r
52         return &E2ResetRequestNotificationHandler{\r
53                 logger:                            logger,\r
54                 rnibDataService:                   rnibDataService,\r
55                 config:                            config,\r
56                 rmrSender:                         rmrSender,\r
57                 ranResetManager:                   ranResetManager,\r
58                 changeStatusToConnectedRanManager: changeStatusToConnectedRanManager,\r
59         }\r
60 }\r
61 \r
62 func (e *E2ResetRequestNotificationHandler) Handle(request *models.NotificationRequest) {\r
63 \r
64         e.logger.Infof("#E2ResetRequestNotificationHandler.Handle - RAN name: %s - received E2_Reset. Payload: %x", request.RanName, request.Payload)\r
65 \r
66         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - RIC_E2_Node_Reset parsed successfully ")\r
67 \r
68         nodebInfo, err := e.getNodebInfo(request.RanName)\r
69         if err != nil {\r
70                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - failed to retrieve nodeB entity. RanName: %s. Error: %s", request.RanName, err.Error())\r
71                 e.logger.Infof(E2ResetRequestLogInfoElapsedTime, utils.ElapsedTime(request.StartTime))\r
72                 return\r
73         }\r
74 \r
75         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - nodeB entity retrieved. RanName %s, ConnectionStatus %s", nodebInfo.RanName, nodebInfo.ConnectionStatus)\r
76 \r
77         nodebInfo.ConnectionStatus = entities.ConnectionStatus_UNDER_RESET\r
78 \r
79         ranName := request.RanName\r
80         isResetDone, err := e.ranResetManager.ResetRan(ranName)\r
81         if err != nil {\r
82                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - failed to update and notify connection status of nodeB entity. RanName: %s. Error: %s", request.RanName, err.Error())\r
83         } else {\r
84                 if isResetDone {\r
85                         nodebInfoupdated, err1 := e.getNodebInfo(request.RanName)\r
86                         if err1 != nil {\r
87                                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - failed to get updated nodeB entity. RanName: %s. Error: %s", request.RanName, err1.Error())\r
88                         }\r
89                         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - Reset Done Successfully ran: %s , Connection status updated : %s", ranName, nodebInfoupdated.ConnectionStatus)\r
90                 } else {\r
91                         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - Reset Failed")\r
92                 }\r
93         }\r
94 \r
95         if err != nil {\r
96                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - failed to update connection status of nodeB entity. RanName: %s. Error: %s", request.RanName, err.Error())\r
97         }\r
98 \r
99         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - nodeB entity under reset state. RanName %s, ConnectionStatus %s", nodebInfo.RanName, nodebInfo.ConnectionStatus)\r
100 \r
101         e.logger.Infof(E2ResetRequestLogInfoElapsedTime, utils.ElapsedTime(request.StartTime))\r
102 \r
103         e.waitfortimertimeout(request)\r
104 \r
105         resetRequest, err := e.parseE2ResetMessage(request.Payload)\r
106         if err != nil {\r
107                 e.logger.Errorf(err.Error())\r
108                 return\r
109         }\r
110         e.logger.Infof("#E2ResetRequestNotificationHandler.Handle - RIC_RESET_REQUEST has been parsed successfully %+v", resetRequest)\r
111         e.handleSuccessfulResponse(ranName, request, resetRequest)\r
112 \r
113         isConnectedStatus, err := e.changeStatusToConnectedRanManager.ChangeStatusToConnectedRan(ranName)\r
114         if err != nil {\r
115                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - failed to update and notify connection status of nodeB entity. RanName: %s. Error: %s", request.RanName, err.Error())\r
116         } else {\r
117                 if isConnectedStatus {\r
118                         nodebInfoupdated, err1 := e.getNodebInfo(request.RanName)\r
119                         if err1 != nil {\r
120                                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - failed to get updated nodeB entity. RanName: %s. Error: %s", request.RanName, err1.Error())\r
121                         }\r
122                         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - Connection status Set Successfully ran: %s , Connection status updated : %s", ranName, nodebInfoupdated.ConnectionStatus)\r
123                 } else {\r
124                         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - Connection status Setting Failed")\r
125                 }\r
126         }\r
127 \r
128         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - nodeB entity connected state. RanName %s, ConnectionStatus %s", nodebInfo.RanName, nodebInfo.ConnectionStatus)\r
129 \r
130 }\r
131 \r
132 func (e *E2ResetRequestNotificationHandler) getNodebInfo(ranName string) (*entities.NodebInfo, error) {\r
133 \r
134         nodebInfo, err := e.rnibDataService.GetNodeb(ranName)\r
135         if err != nil {\r
136                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - failed to retrieve nodeB entity. RanName: %s. Error: %s", ranName, err.Error())\r
137                 return nil, err\r
138         }\r
139         return nodebInfo, err\r
140 }\r
141 \r
142 func (e *E2ResetRequestNotificationHandler) waitfortimertimeout(request *models.NotificationRequest) {\r
143         timeout := e.config.E2ResetTimeOutSec\r
144         for {\r
145                 timeElapsed := utils.ElapsedTime(request.StartTime)\r
146                 e.logger.Infof(E2ResetRequestLogInfoElapsedTime, utils.ElapsedTime(request.StartTime))\r
147                 if int(timeElapsed) > timeout {\r
148                         break\r
149                 }\r
150                 time.Sleep(time.Duration(timeout/100) * time.Millisecond)\r
151         }\r
152 }\r
153 \r
154 func (e *E2ResetRequestNotificationHandler) parseE2ResetMessage(payload []byte) (*models.E2ResetRequestMessage, error) {\r
155         e2resetMessage := models.E2ResetRequestMessage{}\r
156         err := xml.Unmarshal(utils.NormalizeXml(payload), &(e2resetMessage.E2ApPDU))\r
157 \r
158         if err != nil {\r
159                 e.logger.Errorf("#E2ResetRequestNotificationHandler.Handle - error in parsing request message: %+v", err)\r
160                 return nil, err\r
161         }\r
162         e.logger.Debugf("#E2ResetRequestNotificationHandler.Handle - Unmarshalling is successful %v", e2resetMessage.E2ApPDU.InitiatingMessage.ProcedureCode)\r
163         return &e2resetMessage, nil\r
164 }\r
165 \r
166 func (h *E2ResetRequestNotificationHandler) handleSuccessfulResponse(ranName string, req *models.NotificationRequest, resetRequest *models.E2ResetRequestMessage) {\r
167 \r
168         successResponse := models.NewE2ResetResponseMessage(resetRequest)\r
169         h.logger.Debugf("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - E2_RESET_RESPONSE has been built successfully %+v", successResponse)\r
170 \r
171         responsePayload, err := xml.Marshal(&successResponse.E2ApPdu)\r
172         if err != nil {\r
173                 h.logger.Warnf("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - Error marshalling RIC_E2_RESET_RESP. Payload: %s", ranName, responsePayload)\r
174         }\r
175 \r
176         responsePayload = utils.ReplaceEmptyTagsWithSelfClosing(responsePayload, resetRequestEmptyTagsToReplaceToSelfClosingTags)\r
177 \r
178         h.logger.Infof("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - payload: %s", responsePayload)\r
179 \r
180         msg := models.NewRmrMessage(rmrCgo.RIC_E2_RESET_RESP, ranName, responsePayload, req.TransactionId, req.GetMsgSrc())\r
181         h.logger.Infof("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - RIC_E2_RESET_RESP message has been built successfully. Message: %x", ranName, msg)\r
182         err = h.rmrSender.Send(msg)\r
183         if err != nil {\r
184                 h.logger.Errorf("#E2ResetRequestNotificationHandler.handleSuccessfulResponse - RAN name: %s - Error sending e2 success response %+v", ranName, msg)\r
185         }\r
186 }\r