RIC-851: Updated rtmgr to create xapp routes
[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                 r.addRoute_rx_list("RIC_E2_RESET_RESP", e2ManEp, e2TermEp, routeTable, -1, "")
332         }
333 }
334
335 func (r *Rpe) generatePartialRouteTable(endPointList rtmgr.Endpoints, xappSubData *models.XappSubscriptionData, updatetype rtmgr.RMRUpdateType) *rtmgr.RouteTable {
336         xapp.Logger.Debug("rpe.generatePartialRouteTable invoked")
337         xapp.Logger.Debug("Endpoint List:  %v", endPointList)
338         routeTable := &rtmgr.RouteTable{}
339         subManEp := getEndpointByName(&endPointList, "SUBMAN")
340         if subManEp == nil {
341                 xapp.Logger.Error("Platform component not found: %v", "Subscription Manager")
342                 xapp.Logger.Debug("Endpoints: %v", endPointList)
343         }
344         /*e2TermListEp := getEndpointListByName(&endPointList, "E2TERMINST")
345         if len(e2TermListEp) == 0 {
346                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination List")
347                 xapp.Logger.Debug("Endpoints: %v", endPointList)
348         }
349         e2ManEp := getEndpointByName(&endPointList, "E2MAN")
350         if e2ManEp == nil {
351                 xapp.Logger.Error("Platform component not found: %v", "E2 Manager")
352                 xapp.Logger.Debug("Endpoints: %v", endPointList)
353         }*/
354
355         if xappSubData != nil && updatetype == rtmgr.SubsType {
356                 xapp.Logger.Info("Updating partial subscription routes")
357                 r.generatePartialSubscriptionTable(xappSubData, subManEp, routeTable)
358         }
359         /*if updatetype == rtmgr.XappType {
360                 xapp.Logger.Info("Updating partial xapp routes")
361                 for _, endPoint := range endPointList {
362                         xapp.Logger.Debug("Endpoint: %v, xAppType: %v", endPoint.Name, endPoint.XAppType)
363                         if endPoint.XAppType != sbi.PlatformType && (len(endPoint.TxMessages) > 0 || len(endPoint.RxMessages) > 0) {
364                                 r.generateXappRoutes(endPoint, subManEp, routeTable)
365                                 r.generateXappToXappRoutes(endPoint, endPointList, routeTable)
366                         }
367                 }
368         }
369         if updatetype == rtmgr.E2Type {
370                 xapp.Logger.Info("Updating partial E2 routes")
371                 if len(e2TermListEp) > 0 {
372                         r.addRoute_rx_list("RIC_SCTP_CLEAR_ALL", e2ManEp, e2TermListEp, routeTable, -1, "")
373                         r.addRoute_rx_list("E2_TERM_KEEP_ALIVE_REQ", e2ManEp, e2TermListEp, routeTable, -1, "")
374                         r.addRoute_rx_list("RIC_E2_SETUP_RESP", e2ManEp, e2TermListEp, routeTable, -1, "")
375                         r.addRoute_rx_list("RIC_E2_SETUP_FAILURE", e2ManEp, e2TermListEp, routeTable, -1, "")
376                 }
377         }*/
378
379         return routeTable
380
381 }
382
383 func (r *Rpe) generateRouteTable(endPointList rtmgr.Endpoints) *rtmgr.RouteTable {
384         xapp.Logger.Debug("rpe.generateRouteTable invoked")
385         xapp.Logger.Debug("Endpoint List:  %v", endPointList)
386         routeTable := &rtmgr.RouteTable{}
387         /*e2TermEp := getEndpointByName(&endPointList, "E2TERM")
388         if e2TermEp == nil {
389                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination")
390                 xapp.Logger.Debug("Endpoints: %v", endPointList)
391         }*/
392         subManEp := getEndpointByName(&endPointList, "SUBMAN")
393         if subManEp == nil {
394                 xapp.Logger.Error("Platform component not found: %v", "Subscription Manager")
395                 xapp.Logger.Debug("Endpoints: %v", endPointList)
396         }
397         e2ManEp := getEndpointByName(&endPointList, "E2MAN")
398         if e2ManEp == nil {
399                 xapp.Logger.Error("Platform component not found: %v", "E2 Manager")
400                 xapp.Logger.Debug("Endpoints: %v", endPointList)
401         }
402         /*rsmEp := getEndpointByName(&endPointList, "RSM")
403         if rsmEp == nil {
404                 xapp.Logger.Error("Platform component not found: %v", "Resource Status Manager")
405                 xapp.Logger.Debug("Endpoints: %v", endPointList)
406         }*/
407         A1MediatorEp := getEndpointByName(&endPointList, "A1MEDIATOR")
408         if A1MediatorEp == nil {
409                 xapp.Logger.Error("Platform component not found: %v", "A1Mediator")
410                 xapp.Logger.Debug("Endpoints: %v", endPointList)
411         }
412
413         e2TermListEp := getEndpointListByName(&endPointList, "E2TERMINST")
414         if len(e2TermListEp) == 0 {
415                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination List")
416                 xapp.Logger.Debug("Endpoints: %v", endPointList)
417         }
418         r.generatePlatformRoutes(e2TermListEp, subManEp, e2ManEp, A1MediatorEp, routeTable)
419
420         for _, endPoint := range endPointList {
421                 xapp.Logger.Debug("Endpoint: %v, xAppType: %v", endPoint.Name, endPoint.XAppType)
422                 if endPoint.XAppType != sbi.PlatformType && (len(endPoint.TxMessages) > 0 || len(endPoint.RxMessages) > 0) {
423                         r.generateXappRoutes(endPoint, subManEp, routeTable)
424                         r.generateSubscriptionRoutes(endPoint, subManEp, routeTable)
425                         r.generateXappToXappRoutes(endPoint, endPointList, routeTable)
426
427                 }
428         }
429         return routeTable
430 }