Added route entry to e2t to handle e2 reset from e2
[ric-plt/rtmgr.git] / pkg / rpe / rpe.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17
18
19    This source code is part of the near-RT RIC (RAN Intelligent Controller)
20    platform project (RICP).
21
22 ==================================================================================
23 */
24 /*
25   Mnemonic:     rpe.go
26   Abstract:     Contains RPE (Route Policy Engine) module definitions and generic RPE components
27   Date:         16 March 2019
28 */
29
30 package rpe
31
32 import (
33         "errors"
34         "routing-manager/pkg/models"
35         "routing-manager/pkg/rtmgr"
36         "routing-manager/pkg/sbi"
37         "runtime"
38         "strconv"
39
40         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
41 )
42
43 var (
44         SupportedRpes = []*EngineConfig{
45                 {
46                         Name:        "rmrpush",
47                         Version:     "pubsush",
48                         Protocol:    "rmruta",
49                         Instance:    NewRmrPush(),
50                         IsAvailable: true,
51                 },
52         }
53 )
54
55 func GetRpe(rpeName string) (Engine, error) {
56         for _, rpe := range SupportedRpes {
57                 if rpe.Name == rpeName && rpe.IsAvailable {
58                         return rpe.Instance, nil
59                 }
60         }
61         return nil, errors.New("SBI:" + rpeName + " is not supported or still not a available")
62 }
63
64 type Rpe struct {
65 }
66
67 func getEndpointByName(eps *rtmgr.Endpoints, name string) *rtmgr.Endpoint {
68         for _, ep := range *eps {
69                 if ep.Name == name {
70                         xapp.Logger.Debug("name: %s", ep.Name)
71                         xapp.Logger.Debug("ep: %v", ep)
72                         return ep
73                 }
74         }
75         return nil
76 }
77
78 func getEndpointListByName(eps *rtmgr.Endpoints, name string) []rtmgr.Endpoint {
79         var eplist []rtmgr.Endpoint
80
81         for _, ep := range *eps {
82                 if ep.Name == name {
83                         xapp.Logger.Debug("name: %s", ep.Name)
84                         xapp.Logger.Debug("ep: %v", ep)
85                         eplist = append(eplist, *ep)
86                 }
87         }
88         return eplist
89 }
90
91 func getEndpointByUuid(uuid string) *rtmgr.Endpoint {
92         endPoints := rtmgr.Eps
93         for _, ep := range endPoints {
94                 if ep.Uuid == uuid {
95                         xapp.Logger.Debug("name: %s", ep.Uuid)
96                         xapp.Logger.Debug("ep: %v", ep)
97                         return ep
98                 }
99         }
100         return nil
101 }
102
103 func (r *Rpe) addRoute(messageType string, tx *rtmgr.Endpoint, rx *rtmgr.Endpoint, routeTable *rtmgr.RouteTable, subId int32, routeType string) {
104         txList := rtmgr.EndpointList{}
105         rxList := []rtmgr.EndpointList{}
106
107         if tx == nil && rx == nil {
108                 pc, _, _, ok := runtime.Caller(1)
109                 details := runtime.FuncForPC(pc)
110                 if ok && details != nil {
111                         xapp.Logger.Error("Addition of route skipped due to either TX or RX endpoint not present. Caller function is %s", details.Name())
112                 }
113         } else {
114                 if tx != nil {
115                         txList = rtmgr.EndpointList{*tx}
116                 }
117                 if rx != nil {
118                         rxList = []rtmgr.EndpointList{[]rtmgr.Endpoint{*rx}}
119                 }
120                 //messageId := strconv.Itoa(xapp.RICMessageTypes[messageType])
121                 messageId := rtmgr.Mtype[messageType]
122                 route := rtmgr.RouteTableEntry{
123                         MessageType: messageId,
124                         TxList:      txList,
125                         RxGroups:    rxList,
126                         SubID:       subId,
127                         RouteType:   routeType}
128                 *routeTable = append(*routeTable, route)
129                 //              xapp.Logger.Debug("Route added: MessageType: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx.Uuid, rx.Uuid, subId)
130                 //              xapp.Logger.Trace("Route added: MessageType: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx, rx, subId)
131         }
132 }
133
134 func (r *Rpe) addRoute_rx_list(messageType string, tx *rtmgr.Endpoint, rx []rtmgr.Endpoint, routeTable *rtmgr.RouteTable, subId int32, routeType string) {
135         txList := rtmgr.EndpointList{}
136         rxList := []rtmgr.EndpointList{}
137
138         if tx != nil {
139                 txList = rtmgr.EndpointList{*tx}
140         }
141
142         if rx != nil {
143                 for _, item := range rx {
144                         ep := []rtmgr.Endpoint{item}
145                         rxList = append(rxList, ep)
146                 }
147         }
148
149         //messageId := strconv.Itoa(xapp.RICMessageTypes[messageType])
150         messageId := rtmgr.Mtype[messageType]
151         route := rtmgr.RouteTableEntry{
152                 MessageType: messageId,
153                 TxList:      txList,
154                 RxGroups:    rxList,
155                 SubID:       subId,
156                 RouteType:   routeType}
157         *routeTable = append(*routeTable, route)
158         //      xapp.Logger.Debug("Route added: MessageType: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx.Uuid, rx.Uuid, SubId)
159         //      xapp.Logger.Trace("Route added: MessageType: %v, Tx: %v, Rx: %v, SubId: %v", messageId, tx, rx, SubId)
160 }
161
162 func (r *Rpe) generateXappRoutes(xAppEp *rtmgr.Endpoint, subManEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
163         xapp.Logger.Debug("rpe.generateXappRoutes invoked")
164         xapp.Logger.Debug("Endpoint: %v, xAppType: %v", xAppEp.Name, xAppEp.XAppType)
165         if xAppEp.XAppType != sbi.PlatformType && (len(xAppEp.TxMessages) > 0 || len(xAppEp.RxMessages) > 0) {
166                 /// TODO ---
167                 //xApp -> Subscription Manager
168                 r.addRoute("RIC_SUB_REQ", xAppEp, subManEp, routeTable, -1, "")
169                 r.addRoute("RIC_SUB_DEL_REQ", xAppEp, subManEp, routeTable, -1, "")
170                 //xApp -> E2 Termination
171                 //              r.addRoute("RIC_CONTROL_REQ", xAppEp, e2TermEp, routeTable, -1, "")
172                 r.addRoute("RIC_CONTROL_REQ", xAppEp, nil, routeTable, -1, "%meid")
173                 //E2 Termination -> xApp
174                 ///             r.addRoute("RIC_CONTROL_ACK", e2TermEp, xAppEp, routeTable, -1, "")
175                 ///             r.addRoute("RIC_CONTROL_FAILURE", e2TermEp, xAppEp, routeTable, -1, "")
176                 r.addRoute("RIC_CONTROL_ACK", nil, xAppEp, routeTable, -1, "")
177                 r.addRoute("RIC_CONTROL_FAILURE", nil, xAppEp, routeTable, -1, "")
178         }
179         //xApp->A1Mediator
180         if xAppEp.XAppType != sbi.PlatformType && len(xAppEp.Policies) > 0 {
181                 xapp.Logger.Debug("rpe.generateXappRoutes found policies section")
182                 for _, policy := range xAppEp.Policies {
183                         r.addRoute("A1_POLICY_REQ", nil, xAppEp, routeTable, policy, "")
184                 }
185         }
186
187 }
188
189 func (r *Rpe) generateXappToXappRoutes(RecvxAppEp *rtmgr.Endpoint, endPointList rtmgr.Endpoints, routeTable *rtmgr.RouteTable) {
190         xapp.Logger.Debug("rpe.generateXappToXappRoutes invoked")
191
192         for _, rxmsg := range RecvxAppEp.RxMessages {
193
194                 var src_present bool
195                 identicalMsg := false
196                 var RxGrp []rtmgr.Endpoint
197                 xapp.Logger.Debug("RecvxAppEp.RxMessages Endpoint: %v, xAppType: %v and rxmsg: %v ", RecvxAppEp.Name, RecvxAppEp.XAppType, rxmsg)
198                 if rxmsg != "RIC_SUB_RESP" && rxmsg != "RIC_SUB_FAILURE" && rxmsg != "RIC_SUB_DEL_RESP" && rxmsg != "RIC_SUB_DEL_FAILURE" && rxmsg != "RIC_INDICATION" && rxmsg != "RIC_CONTROL_ACK" && rxmsg != "RIC_CONTROL_FAILURE" && rxmsg != "A1_POLICY_REQ" && rxmsg != "RIC_SUB_DEL_REQUIRED" {
199                         for _, SrcxAppEp := range endPointList {
200                                 if SrcxAppEp.XAppType != sbi.PlatformType && (len(SrcxAppEp.TxMessages) > 0) && SrcxAppEp.Name != RecvxAppEp.Name {
201                                         for _, txmsg := range SrcxAppEp.TxMessages {
202                                                 if rxmsg == txmsg {
203                                                         r.addRoute(rxmsg, SrcxAppEp, RecvxAppEp, routeTable, -1, "")
204                                                         src_present = true
205                                                         break
206                                                 }
207                                         }
208                                 }
209                         }
210                         for _, SrcxAppEp := range endPointList {
211
212                                 if SrcxAppEp.XAppType != sbi.PlatformType && (len(SrcxAppEp.RxMessages) > 0) && SrcxAppEp.Name != RecvxAppEp.Name {
213                                         for _, newrxmsg := range SrcxAppEp.RxMessages {
214                                                 if newrxmsg == rxmsg {
215                                                         RxGrp = append(RxGrp, *SrcxAppEp)
216                                                         identicalMsg = true
217                                                 }
218                                         }
219                                 }
220                         }
221                         if src_present == false && identicalMsg == false {
222                                 xapp.Logger.Debug("Message type %v,for SrcxAppEp.Name %v", rxmsg, RecvxAppEp)
223                                 r.addRoute(rxmsg, nil, RecvxAppEp, routeTable, -1, "")
224                         }
225                         if identicalMsg == true {
226                                 xapp.Logger.Debug("Appending Message type %v,for SrcxAppEp.Name %v", rxmsg, RecvxAppEp)
227                                 RxGrp = append(RxGrp, *RecvxAppEp)
228                                 r.addRoute_rx_list(rxmsg, nil, RxGrp, routeTable, -1, "")
229                                 //return
230                         }
231                 }
232         }
233 }
234
235 func (r *Rpe) generateSubscriptionRoutes(selectedxAppEp *rtmgr.Endpoint, subManEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
236         xapp.Logger.Debug("rpe.addSubscriptionRoutes invoked")
237         subscriptionList := &rtmgr.Subs
238         for _, subscription := range *subscriptionList {
239                 xapp.Logger.Debug("Subscription: %v", subscription)
240                 xAppUuid := subscription.Fqdn + ":" + strconv.Itoa(int(subscription.Port))
241                 xapp.Logger.Debug("xApp UUID: %v", xAppUuid)
242                 xAppEp := getEndpointByUuid(xAppUuid)
243                 if xAppEp != nil {
244                         if xAppEp.Uuid == selectedxAppEp.Uuid {
245                                 xapp.Logger.Debug("xApp UUID is matched for selected xApp.UUID: %v and xApp.Name: %v", selectedxAppEp.Uuid, selectedxAppEp.Name)
246                                 /// TODO
247                                 //Subscription Manager -> xApp
248                                 r.addRoute("RIC_SUB_RESP", subManEp, xAppEp, routeTable, subscription.SubID, "")
249                                 r.addRoute("RIC_SUB_FAILURE", subManEp, xAppEp, routeTable, subscription.SubID, "")
250                                 r.addRoute("RIC_SUB_DEL_RESP", subManEp, xAppEp, routeTable, subscription.SubID, "")
251                                 r.addRoute("RIC_SUB_DEL_FAILURE", subManEp, xAppEp, routeTable, subscription.SubID, "")
252
253                                 //E2 Termination -> xApp
254                                 r.addRoute("RIC_INDICATION", nil, xAppEp, routeTable, subscription.SubID, "")
255                                 r.addRoute("RIC_CONTROL_ACK", nil, xAppEp, routeTable, subscription.SubID, "")
256                                 r.addRoute("RIC_CONTROL_FAILURE", nil, xAppEp, routeTable, subscription.SubID, "")
257                         }
258                 } else {
259                         xapp.Logger.Error("generateSubscriptionRoutes xAppEp is nil, xApp UUID: %v", xAppUuid)
260                 }
261         }
262 }
263
264 func (r *Rpe) generatePartialSubscriptionTable(xappSubData *models.XappSubscriptionData, subManEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
265         xapp.Logger.Debug("rpe.addSingleSubscriptionRoutes invoked")
266         xAppUuid := *xappSubData.Address + ":" + strconv.Itoa(int(*xappSubData.Port))
267         xapp.Logger.Debug("xApp UUID: %v", xAppUuid)
268         xAppEp := getEndpointByUuid(xAppUuid)
269         if xAppEp != nil {
270                 //Subscription Manager -> xApp
271                 r.addRoute("RIC_SUB_RESP", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
272                 r.addRoute("RIC_SUB_FAILURE", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
273                 r.addRoute("RIC_SUB_DEL_RESP", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
274                 r.addRoute("RIC_SUB_DEL_FAILURE", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
275
276                 //E2 Termination -> xApp
277                 r.addRoute("RIC_INDICATION", nil, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
278                 r.addRoute("RIC_CONTROL_ACK", nil, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
279                 r.addRoute("RIC_CONTROL_FAILURE", nil, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
280         } else {
281                 xapp.Logger.Error("generateSubscriptionRoutes xAppEp is nil, xApp UUID: %v", xAppUuid)
282         }
283 }
284
285 func (r *Rpe) generatePlatformRoutes(e2TermEp []rtmgr.Endpoint, subManEp *rtmgr.Endpoint, e2ManEp *rtmgr.Endpoint, a1mediatorEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
286         xapp.Logger.Debug("rpe.generatePlatformRoutes invoked")
287         //Platform Routes --- Subscription Routes
288         //Subscription Manager -> E2 Termination
289         if rtmgr.PrsCfg == nil {
290                 xapp.Logger.Info("No static routes configuration")
291                 return
292         }
293         for _, routes := range *rtmgr.PrsCfg {
294                 var sendEp *rtmgr.Endpoint
295                 var Ep *rtmgr.Endpoint
296                 switch routes.SenderEndPoint {
297                 case "SUBMAN":
298                         sendEp = subManEp
299                 case "E2MAN":
300                         sendEp = e2ManEp
301                 //case "RSM":,
302                 //      sendEp = rsmEp
303                 case "A1MEDIATOR":
304                         sendEp = a1mediatorEp
305                 }
306                 switch routes.EndPoint {
307                 case "SUBMAN":
308                         Ep = subManEp
309                 case "E2MAN":
310                         Ep = e2ManEp
311                 //case "UEMAN":
312                 //      Ep = ueManEp
313                 //case "RSM":
314                 //      Ep = rsmEp
315                 case "A1MEDIATOR":
316                         Ep = a1mediatorEp
317                 }
318
319                 r.addRoute(routes.MessageType, sendEp, Ep, routeTable, routes.SubscriptionId, routes.Meid)
320         }
321
322         if len(e2TermEp) > 0 {
323                 r.addRoute_rx_list("RIC_SCTP_CLEAR_ALL", e2ManEp, e2TermEp, routeTable, -1, "")
324                 r.addRoute_rx_list("E2_TERM_KEEP_ALIVE_REQ", e2ManEp, e2TermEp, routeTable, -1, "")
325                 r.addRoute_rx_list("RIC_E2_SETUP_RESP", e2ManEp, e2TermEp, routeTable, -1, "")
326                 r.addRoute_rx_list("RIC_E2_SETUP_FAILURE", e2ManEp, e2TermEp, routeTable, -1, "")
327                 r.addRoute_rx_list("RIC_SERVICE_UPDATE_ACK", e2ManEp, e2TermEp, routeTable, -1, "")
328                 r.addRoute_rx_list("RIC_SERVICE_UPDATE_FAILURE", e2ManEp, e2TermEp, routeTable, -1, "")
329                 r.addRoute_rx_list("RIC_E2NODE_CONFIG_UPDATE_ACK", e2ManEp, e2TermEp, routeTable, -1, "")
330                 r.addRoute_rx_list("RIC_E2NODE_CONFIG_UPDATE_FAILURE", e2ManEp, e2TermEp, routeTable, -1, "")
331
332                 r.addRoute("RIC_E2_RESET_REQ", nil, e2ManEp, routeTable, -1, "")
333
334                 r.addRoute_rx_list("RIC_E2_RESET_RESP", e2ManEp, e2TermEp, routeTable, -1, "")
335         }
336
337 }
338
339 func (r *Rpe) generatePartialRouteTable(endPointList rtmgr.Endpoints, xappSubData *models.XappSubscriptionData, updatetype rtmgr.RMRUpdateType) *rtmgr.RouteTable {
340         xapp.Logger.Debug("rpe.generatePartialRouteTable invoked")
341         xapp.Logger.Debug("Endpoint List:  %v", endPointList)
342         routeTable := &rtmgr.RouteTable{}
343         subManEp := getEndpointByName(&endPointList, "SUBMAN")
344         if subManEp == nil {
345                 xapp.Logger.Error("Platform component not found: %v", "Subscription Manager")
346                 xapp.Logger.Debug("Endpoints: %v", endPointList)
347         }
348         /*e2TermListEp := getEndpointListByName(&endPointList, "E2TERMINST")
349         if len(e2TermListEp) == 0 {
350                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination List")
351                 xapp.Logger.Debug("Endpoints: %v", endPointList)
352         }
353         e2ManEp := getEndpointByName(&endPointList, "E2MAN")
354         if e2ManEp == nil {
355                 xapp.Logger.Error("Platform component not found: %v", "E2 Manager")
356                 xapp.Logger.Debug("Endpoints: %v", endPointList)
357         }*/
358
359         if xappSubData != nil && updatetype == rtmgr.SubsType {
360                 xapp.Logger.Info("Updating partial subscription routes")
361                 r.generatePartialSubscriptionTable(xappSubData, subManEp, routeTable)
362         }
363         /*if updatetype == rtmgr.XappType {
364                 xapp.Logger.Info("Updating partial xapp routes")
365                 for _, endPoint := range endPointList {
366                         xapp.Logger.Debug("Endpoint: %v, xAppType: %v", endPoint.Name, endPoint.XAppType)
367                         if endPoint.XAppType != sbi.PlatformType && (len(endPoint.TxMessages) > 0 || len(endPoint.RxMessages) > 0) {
368                                 r.generateXappRoutes(endPoint, subManEp, routeTable)
369                                 r.generateXappToXappRoutes(endPoint, endPointList, routeTable)
370                         }
371                 }
372         }
373         if updatetype == rtmgr.E2Type {
374                 xapp.Logger.Info("Updating partial E2 routes")
375                 if len(e2TermListEp) > 0 {
376                         r.addRoute_rx_list("RIC_SCTP_CLEAR_ALL", e2ManEp, e2TermListEp, routeTable, -1, "")
377                         r.addRoute_rx_list("E2_TERM_KEEP_ALIVE_REQ", e2ManEp, e2TermListEp, routeTable, -1, "")
378                         r.addRoute_rx_list("RIC_E2_SETUP_RESP", e2ManEp, e2TermListEp, routeTable, -1, "")
379                         r.addRoute_rx_list("RIC_E2_SETUP_FAILURE", e2ManEp, e2TermListEp, routeTable, -1, "")
380                 }
381         }*/
382
383         return routeTable
384
385 }
386
387 func (r *Rpe) generateRouteTable(endPointList rtmgr.Endpoints) *rtmgr.RouteTable {
388         xapp.Logger.Debug("rpe.generateRouteTable invoked")
389         xapp.Logger.Debug("Endpoint List:  %v", endPointList)
390         routeTable := &rtmgr.RouteTable{}
391         /*e2TermEp := getEndpointByName(&endPointList, "E2TERM")
392         if e2TermEp == nil {
393                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination")
394                 xapp.Logger.Debug("Endpoints: %v", endPointList)
395         }*/
396         subManEp := getEndpointByName(&endPointList, "SUBMAN")
397         if subManEp == nil {
398                 xapp.Logger.Error("Platform component not found: %v", "Subscription Manager")
399                 xapp.Logger.Debug("Endpoints: %v", endPointList)
400         }
401         e2ManEp := getEndpointByName(&endPointList, "E2MAN")
402         if e2ManEp == nil {
403                 xapp.Logger.Error("Platform component not found: %v", "E2 Manager")
404                 xapp.Logger.Debug("Endpoints: %v", endPointList)
405         }
406         /*rsmEp := getEndpointByName(&endPointList, "RSM")
407         if rsmEp == nil {
408                 xapp.Logger.Error("Platform component not found: %v", "Resource Status Manager")
409                 xapp.Logger.Debug("Endpoints: %v", endPointList)
410         }*/
411         A1MediatorEp := getEndpointByName(&endPointList, "A1MEDIATOR")
412         if A1MediatorEp == nil {
413                 xapp.Logger.Error("Platform component not found: %v", "A1Mediator")
414                 xapp.Logger.Debug("Endpoints: %v", endPointList)
415         }
416
417         e2TermListEp := getEndpointListByName(&endPointList, "E2TERMINST")
418         if len(e2TermListEp) == 0 {
419                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination List")
420                 xapp.Logger.Debug("Endpoints: %v", endPointList)
421         }
422         r.generatePlatformRoutes(e2TermListEp, subManEp, e2ManEp, A1MediatorEp, routeTable)
423
424         for _, endPoint := range endPointList {
425                 xapp.Logger.Debug("Endpoint: %v, xAppType: %v", endPoint.Name, endPoint.XAppType)
426                 if endPoint.XAppType != sbi.PlatformType && (len(endPoint.TxMessages) > 0 || len(endPoint.RxMessages) > 0) {
427                         r.generateXappRoutes(endPoint, subManEp, routeTable)
428                         r.generateSubscriptionRoutes(endPoint, subManEp, routeTable)
429                         r.generateXappToXappRoutes(endPoint, endPointList, routeTable)
430
431                 }
432         }
433         return routeTable
434 }