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