Release of Routing Manager v0.3.0
[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 /*
20   Mnemonic:     rpe.go
21   Abstract:     Contains RPE (Route Policy Engine) module definitions and generic RPE components
22   Date:         16 March 2019
23 */
24
25 package rpe
26
27 import (
28         "errors"
29         "routing-manager/pkg/rtmgr"
30         "strconv"
31 )
32
33 var (
34         SupportedRpes = []*RpeEngineConfig{
35                 &RpeEngineConfig{
36                         Name:        "rmrpub",
37                         Version:     "pubsub",
38                         Protocol:    "rmruta",
39                         Instance:    NewRmrPub(),
40                         IsAvailable: true,
41                 },
42                 &RpeEngineConfig{
43                         Name:        "rmrpush",
44                         Version:     "pubsush",
45                         Protocol:    "rmruta",
46                         Instance:    NewRmrPush(),
47                         IsAvailable: true,
48                 },
49         }
50 )
51
52 func GetRpe(rpeName string) (RpeEngine, error) {
53         for _, rpe := range SupportedRpes {
54                 if rpe.Name == rpeName && rpe.IsAvailable {
55                         return rpe.Instance, nil
56                 }
57         }
58         return nil, errors.New("SBI:" + rpeName + " is not supported or still not a available")
59 }
60
61 type Rpe struct {
62 }
63
64 /*
65 Gets the raw xApp list and generates the list of sender endpoints and receiver endpoint groups
66 Returns the Tx EndpointList map where the key is the messge type and also returns the nested map of Rx EndpointList's map where keys are message type and xapp type
67 Endpoint object's message type already transcoded to integer id
68 */
69
70 func (r *Rpe) getRouteRxTxLists(eps rtmgr.Endpoints) (*map[string]rtmgr.EndpointList, *map[string]map[string]rtmgr.EndpointList) {
71         txlist := make(map[string]rtmgr.EndpointList)
72         rxgroups := make(map[string]map[string]rtmgr.EndpointList)
73         for _, ep := range eps {
74                 for _, message := range ep.RxMessages {
75                         messageid := rtmgr.MESSAGETYPES[message]
76                         if _, ok := rxgroups[messageid]; !ok {
77                                 rxgroups[messageid] = make(map[string]rtmgr.EndpointList)
78                         }
79                         rxgroups[messageid][ep.XAppType] = append(rxgroups[messageid][ep.XAppType], (*ep))
80                 }
81                 for _, message := range ep.TxMessages {
82                         messageid := rtmgr.MESSAGETYPES[message]
83                         txlist[messageid] = append(txlist[messageid], (*ep))
84                 }
85         }
86         return &txlist, &rxgroups
87 }
88
89 /*
90 Gets the raw xapp list and creates a route table for
91 Returns the array of route table entries
92 */
93 func (r *Rpe) getRouteTable(eps rtmgr.Endpoints) *rtmgr.RouteTable {
94         tx, rx := r.getRouteRxTxLists(eps)
95         var rt rtmgr.RouteTable
96         for _, messagetype := range rtmgr.MESSAGETYPES {
97                 /*if _, ok := (*tx)[messagetype]; !ok {
98                         continue
99                 }
100                 if _, ok := (*rx)[messagetype]; !ok {
101                         continue
102                 }*/
103                 txList, ok := (*tx)[messagetype]
104                 if !ok {
105                         txList = rtmgr.EndpointList{}
106                 }
107                 var rxgroups []rtmgr.EndpointList
108                 for _, endpointlist := range (*rx)[messagetype] {
109                         rxgroups = append(rxgroups, endpointlist)
110                 }
111                 if len(txList) > 0 || len(rxgroups) > 0 {
112                         rte := rtmgr.RouteTableEntry{
113                                 messagetype,
114                                 txList,
115                                 rxgroups,
116                                 -1,
117                         }
118                         rt = append(rt, rte)
119                 }
120         }
121         r.addStaticRoutes(eps, &rt)
122         r.addSubscriptionRoutes(eps, &rt, &rtmgr.Subs)
123         return &rt
124 }
125
126 /*
127 Adds specific static routes to the route table
128 which cannot be calculated with endpoint tx/rx message types.
129 */
130 func (r *Rpe) addStaticRoutes(eps rtmgr.Endpoints, rt *rtmgr.RouteTable) {
131         var uemanep, submanep *rtmgr.Endpoint
132         for _, ep := range eps {
133                 if ep.Name == "UEMAN" {
134                         uemanep = ep
135                 }
136                 if ep.Name == "SUBMAN" {
137                         submanep = ep
138                 }
139         }
140
141         if uemanep != nil && submanep != nil {
142                 txlist := rtmgr.EndpointList{*uemanep}
143                 rxlist := []rtmgr.EndpointList{[]rtmgr.Endpoint{*submanep}}
144                 rte1 := rtmgr.RouteTableEntry{
145                         rtmgr.MESSAGETYPES["RIC_SUB_REQ"],
146                         txlist,
147                         rxlist,
148                         -1,
149                 }
150                 rte2 := rtmgr.RouteTableEntry{
151                         rtmgr.MESSAGETYPES["RIC_SUB_DEL_REQ"],
152                         txlist,
153                         rxlist,
154                         -1,
155                 }
156                 *rt = append(*rt, rte1)
157                 *rt = append(*rt, rte2)
158         } else {
159                 rtmgr.Logger.Warn("Cannot get the static route details of the platform components UEMAN/SUBMAN")
160         }
161 }
162
163 func getEndpointByName(eps *rtmgr.Endpoints, name string) *rtmgr.Endpoint {
164         for _, ep := range *eps {
165                 if ep.Name == name {
166                         rtmgr.Logger.Debug("name: %s", ep.Name)
167                         rtmgr.Logger.Debug("ep: %v", ep)
168                         return ep
169                 }
170         }
171         return nil
172 }
173
174 func getEndpointByUuid(eps *rtmgr.Endpoints, uuid string) *rtmgr.Endpoint {
175         for _, ep := range *eps {
176                 if ep.Uuid == uuid {
177                         rtmgr.Logger.Debug("name: %s", ep.Uuid)
178                         rtmgr.Logger.Debug("ep: %v", ep)
179                         return ep
180                 }
181         }
182         return nil
183 }
184 func (r *Rpe) addSubscriptionRoutes(eps rtmgr.Endpoints, rt *rtmgr.RouteTable, subs *rtmgr.SubscriptionList) {
185         rtmgr.Logger.Debug("rpe.addSubscriptionRoutes invoked")
186         rtmgr.Logger.Debug("params: %v", eps)
187         var e2termep, submanep, xappEp *rtmgr.Endpoint
188         var xappName string
189         e2termep = getEndpointByName(&eps, "E2TERM")
190         submanep = getEndpointByName(&eps, "SUBMAN")
191         if e2termep != nil && submanep != nil {
192                 // looping through the subscription list, add routes one by one
193                 for _, sub := range *subs {
194                         // SubMan -> XApp
195                         xappName = sub.Fqdn + ":" + strconv.Itoa(int(sub.Port))
196                         xappEp = getEndpointByUuid(&eps, xappName)
197                         if xappEp == nil {
198                                 rtmgr.Logger.Error("XApp not found: %s", xappName)
199                                 rtmgr.Logger.Debug("Endpoints: %v", eps)
200                         } else {
201                                 txlist := rtmgr.EndpointList{*submanep}
202                                 rxlist := []rtmgr.EndpointList{[]rtmgr.Endpoint{*xappEp}}
203                                 subManMsgs := []string{"RIC_SUB_RESP", "RIC_SUB_FAILURE", "RIC_SUB_DEL_RESP", "RIC_SUB_DEL_FAILURE"}
204                                 for _, entry := range subManMsgs {
205                                         rte := rtmgr.RouteTableEntry{
206                                                 rtmgr.MESSAGETYPES[entry],
207                                                 txlist,
208                                                 rxlist,
209                                                 sub.SubID,
210                                         }
211                                         *rt = append(*rt, rte)
212                                 }
213                                 // E2Term -> XApp
214                                 txlist = rtmgr.EndpointList{*e2termep}
215                                 rxlist = []rtmgr.EndpointList{[]rtmgr.Endpoint{*xappEp}}
216                                 e2apMsgs := []string{"RIC_CONTROL_ACK", "RIC_CONTROL_FAILURE", "RIC_INDICATION"}
217                                 for _, entry := range e2apMsgs {
218                                         rte := rtmgr.RouteTableEntry{
219                                                 rtmgr.MESSAGETYPES[entry],
220                                                 txlist,
221                                                 rxlist,
222                                                 sub.SubID,
223                                         }
224                                         *rt = append(*rt, rte)
225                                 }
226                         }
227                 }
228                 rtmgr.Logger.Debug("addSubscriptionRoutes eps: %v", eps)
229         } else {
230                 rtmgr.Logger.Warn("Subscription route update failure: Cannot get the static route details of the platform components E2TERM/SUBMAN")
231         }
232
233 }