b763316ed22fcbf285d57322e8c2a2e055b7e14b
[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" {
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                                 //E2 Termination -> xApp
253                                 r.addRoute("RIC_INDICATION", nil, xAppEp, routeTable, subscription.SubID, "")
254                                 r.addRoute("RIC_CONTROL_ACK", nil, xAppEp, routeTable, subscription.SubID, "")
255                                 r.addRoute("RIC_CONTROL_FAILURE", nil, xAppEp, routeTable, subscription.SubID, "")
256                         }
257                 } else {
258                         xapp.Logger.Error("generateSubscriptionRoutes xAppEp is nil, xApp UUID: %v", xAppUuid)
259                 }
260         }
261 }
262
263 func (r *Rpe) generatePartialSubscriptionTable(xappSubData *models.XappSubscriptionData, subManEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
264         xapp.Logger.Debug("rpe.addSingleSubscriptionRoutes invoked")
265         xAppUuid := *xappSubData.Address + ":" + strconv.Itoa(int(*xappSubData.Port))
266         xapp.Logger.Debug("xApp UUID: %v", xAppUuid)
267         xAppEp := getEndpointByUuid(xAppUuid)
268         if xAppEp != nil {
269                 //Subscription Manager -> xApp
270                 r.addRoute("RIC_SUB_RESP", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
271                 r.addRoute("RIC_SUB_FAILURE", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
272                 r.addRoute("RIC_SUB_DEL_RESP", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
273                 r.addRoute("RIC_SUB_DEL_FAILURE", subManEp, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
274                 //E2 Termination -> xApp
275                 r.addRoute("RIC_INDICATION", nil, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
276                 r.addRoute("RIC_CONTROL_ACK", nil, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
277                 r.addRoute("RIC_CONTROL_FAILURE", nil, xAppEp, routeTable, *xappSubData.SubscriptionID, "")
278         } else {
279                 xapp.Logger.Error("generateSubscriptionRoutes xAppEp is nil, xApp UUID: %v", xAppUuid)
280         }
281 }
282
283 func (r *Rpe) generatePlatformRoutes(e2TermEp []rtmgr.Endpoint, subManEp *rtmgr.Endpoint, e2ManEp *rtmgr.Endpoint, a1mediatorEp *rtmgr.Endpoint, routeTable *rtmgr.RouteTable) {
284         xapp.Logger.Debug("rpe.generatePlatformRoutes invoked")
285         //Platform Routes --- Subscription Routes
286         //Subscription Manager -> E2 Termination
287         if rtmgr.PrsCfg == nil {
288                 xapp.Logger.Info("No static routes configuration")
289                 return
290         }
291         for _, routes := range *rtmgr.PrsCfg {
292                 var sendEp *rtmgr.Endpoint
293                 var Ep *rtmgr.Endpoint
294                 switch routes.SenderEndPoint {
295                 case "SUBMAN":
296                         sendEp = subManEp
297                 case "E2MAN":
298                         sendEp = e2ManEp
299                 //case "RSM":,
300                 //      sendEp = rsmEp
301                 case "A1MEDIATOR":
302                         sendEp = a1mediatorEp
303                 }
304                 switch routes.EndPoint {
305                 case "SUBMAN":
306                         Ep = subManEp
307                 case "E2MAN":
308                         Ep = e2ManEp
309                 //case "UEMAN":
310                 //      Ep = ueManEp
311                 //case "RSM":
312                 //      Ep = rsmEp
313                 case "A1MEDIATOR":
314                         Ep = a1mediatorEp
315                 }
316
317                 r.addRoute(routes.MessageType, sendEp, Ep, routeTable, routes.SubscriptionId, routes.Meid)
318         }
319
320         if len(e2TermEp) > 0 {
321                 r.addRoute_rx_list("RIC_SCTP_CLEAR_ALL", e2ManEp, e2TermEp, routeTable, -1, "")
322                 r.addRoute_rx_list("E2_TERM_KEEP_ALIVE_REQ", e2ManEp, e2TermEp, routeTable, -1, "")
323                 r.addRoute_rx_list("RIC_E2_SETUP_RESP", e2ManEp, e2TermEp, routeTable, -1, "")
324                 r.addRoute_rx_list("RIC_E2_SETUP_FAILURE", e2ManEp, e2TermEp, routeTable, -1, "")
325                 r.addRoute_rx_list("RIC_SERVICE_UPDATE_ACK", e2ManEp, e2TermEp, routeTable, -1, "")
326                 r.addRoute_rx_list("RIC_SERVICE_UPDATE_FAILURE", e2ManEp, e2TermEp, routeTable, -1, "")
327                 r.addRoute_rx_list("RIC_E2NODE_CONFIG_UPDATE_ACK", e2ManEp, e2TermEp, routeTable, -1, "")
328                 r.addRoute_rx_list("RIC_E2NODE_CONFIG_UPDATE_FAILURE", e2ManEp, e2TermEp, routeTable, -1, "")
329         }
330 }
331
332 func (r *Rpe) generatePartialRouteTable(endPointList rtmgr.Endpoints, xappSubData *models.XappSubscriptionData, updatetype rtmgr.RMRUpdateType) *rtmgr.RouteTable {
333         xapp.Logger.Debug("rpe.generatePartialRouteTable invoked")
334         xapp.Logger.Debug("Endpoint List:  %v", endPointList)
335         routeTable := &rtmgr.RouteTable{}
336         subManEp := getEndpointByName(&endPointList, "SUBMAN")
337         if subManEp == nil {
338                 xapp.Logger.Error("Platform component not found: %v", "Subscription Manager")
339                 xapp.Logger.Debug("Endpoints: %v", endPointList)
340         }
341         /*e2TermListEp := getEndpointListByName(&endPointList, "E2TERMINST")
342         if len(e2TermListEp) == 0 {
343                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination List")
344                 xapp.Logger.Debug("Endpoints: %v", endPointList)
345         }
346         e2ManEp := getEndpointByName(&endPointList, "E2MAN")
347         if e2ManEp == nil {
348                 xapp.Logger.Error("Platform component not found: %v", "E2 Manager")
349                 xapp.Logger.Debug("Endpoints: %v", endPointList)
350         }*/
351
352         if xappSubData != nil && updatetype == rtmgr.SubsType {
353                 xapp.Logger.Info("Updating partial subscription routes")
354                 r.generatePartialSubscriptionTable(xappSubData, subManEp, routeTable)
355         }
356         /*if updatetype == rtmgr.XappType {
357                 xapp.Logger.Info("Updating partial xapp routes")
358                 for _, endPoint := range endPointList {
359                         xapp.Logger.Debug("Endpoint: %v, xAppType: %v", endPoint.Name, endPoint.XAppType)
360                         if endPoint.XAppType != sbi.PlatformType && (len(endPoint.TxMessages) > 0 || len(endPoint.RxMessages) > 0) {
361                                 r.generateXappRoutes(endPoint, subManEp, routeTable)
362                                 r.generateXappToXappRoutes(endPoint, endPointList, routeTable)
363                         }
364                 }
365         }
366         if updatetype == rtmgr.E2Type {
367                 xapp.Logger.Info("Updating partial E2 routes")
368                 if len(e2TermListEp) > 0 {
369                         r.addRoute_rx_list("RIC_SCTP_CLEAR_ALL", e2ManEp, e2TermListEp, routeTable, -1, "")
370                         r.addRoute_rx_list("E2_TERM_KEEP_ALIVE_REQ", e2ManEp, e2TermListEp, routeTable, -1, "")
371                         r.addRoute_rx_list("RIC_E2_SETUP_RESP", e2ManEp, e2TermListEp, routeTable, -1, "")
372                         r.addRoute_rx_list("RIC_E2_SETUP_FAILURE", e2ManEp, e2TermListEp, routeTable, -1, "")
373                 }
374         }*/
375
376         return routeTable
377
378 }
379
380 func (r *Rpe) generateRouteTable(endPointList rtmgr.Endpoints) *rtmgr.RouteTable {
381         xapp.Logger.Debug("rpe.generateRouteTable invoked")
382         xapp.Logger.Debug("Endpoint List:  %v", endPointList)
383         routeTable := &rtmgr.RouteTable{}
384         /*e2TermEp := getEndpointByName(&endPointList, "E2TERM")
385         if e2TermEp == nil {
386                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination")
387                 xapp.Logger.Debug("Endpoints: %v", endPointList)
388         }*/
389         subManEp := getEndpointByName(&endPointList, "SUBMAN")
390         if subManEp == nil {
391                 xapp.Logger.Error("Platform component not found: %v", "Subscription Manager")
392                 xapp.Logger.Debug("Endpoints: %v", endPointList)
393         }
394         e2ManEp := getEndpointByName(&endPointList, "E2MAN")
395         if e2ManEp == nil {
396                 xapp.Logger.Error("Platform component not found: %v", "E2 Manager")
397                 xapp.Logger.Debug("Endpoints: %v", endPointList)
398         }
399         /*rsmEp := getEndpointByName(&endPointList, "RSM")
400         if rsmEp == nil {
401                 xapp.Logger.Error("Platform component not found: %v", "Resource Status Manager")
402                 xapp.Logger.Debug("Endpoints: %v", endPointList)
403         }*/
404         A1MediatorEp := getEndpointByName(&endPointList, "A1MEDIATOR")
405         if A1MediatorEp == nil {
406                 xapp.Logger.Error("Platform component not found: %v", "A1Mediator")
407                 xapp.Logger.Debug("Endpoints: %v", endPointList)
408         }
409
410         e2TermListEp := getEndpointListByName(&endPointList, "E2TERMINST")
411         if len(e2TermListEp) == 0 {
412                 xapp.Logger.Error("Platform component not found: %v", "E2 Termination List")
413                 xapp.Logger.Debug("Endpoints: %v", endPointList)
414         }
415         r.generatePlatformRoutes(e2TermListEp, subManEp, e2ManEp, A1MediatorEp, routeTable)
416
417         for _, endPoint := range endPointList {
418                 xapp.Logger.Debug("Endpoint: %v, xAppType: %v", endPoint.Name, endPoint.XAppType)
419                 if endPoint.XAppType != sbi.PlatformType && (len(endPoint.TxMessages) > 0 || len(endPoint.RxMessages) > 0) {
420                         r.generateXappRoutes(endPoint, subManEp, routeTable)
421                         r.generateSubscriptionRoutes(endPoint, subManEp, routeTable)
422                         r.generateXappToXappRoutes(endPoint, endPointList, routeTable)
423
424                 }
425         }
426         return routeTable
427 }