MEID table corruption due to index mismatch
[ric-plt/rtmgr.git] / pkg / rpe / rmr.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:     rmr.go
26   Abstract:     RMR Route Policy implementation
27                 Produces RMR (RIC Management Routing) formatted route messages
28   Date:         16 March 2019
29 */
30
31 package rpe
32
33 import (
34         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
35         "routing-manager/pkg/models"
36         "routing-manager/pkg/rtmgr"
37         "strconv"
38         "strings"
39 )
40
41 type Rmr struct {
42         Rpe
43 }
44
45 type RmrPush struct {
46         Rmr
47 }
48
49 func NewRmrPush() *RmrPush {
50         instance := new(RmrPush)
51         return instance
52 }
53
54 /*
55 Produces the raw route message consumable by RMR
56 */
57 func (r *Rmr) generateRMRPolicies(eps rtmgr.Endpoints, rcs *rtmgr.RicComponents, key string) *[]string {
58         rawrt := []string{key + "newrt|start\n"}
59         rt := r.generateRouteTable(eps)
60         for _, rte := range *rt {
61                 rawrte := key + "mse|" + rte.MessageType
62                 for _, tx := range rte.TxList {
63                         rawrte += "," + tx.Ip + ":" + strconv.Itoa(int(tx.Port))
64                 }
65                 rawrte += "|" + strconv.Itoa(int(rte.SubID)) + "|"
66                 group := ""
67                 for _, rxg := range rte.RxGroups {
68                         member := ""
69                         for _, rx := range rxg {
70                                 if member == "" {
71                                         member += rx.Ip + ":" + strconv.Itoa(int(rx.Port))
72                                 } else {
73                                         member += "," + rx.Ip + ":" + strconv.Itoa(int(rx.Port))
74                                 }
75                         }
76                         if group == "" {
77                                 group += member
78                         } else {
79                                 group += ";" + member
80                         }
81                 }
82
83                 if rte.RouteType == "%meid" {
84                         rawrte += "%" + "meid"
85                 } else {
86                         rawrte += group
87                 }
88
89                 rawrt = append(rawrt, rawrte+"\n")
90         }
91         for _, val := range rtmgr.DynamicRouteList {
92                 rawrt = append(rawrt, val)
93         }
94
95         rawrt = append(rawrt, key+"newrt|end\n")
96         count := 0
97
98         rawrt = append(rawrt, key+"meid_map|start\n")
99         keys := make(map[string]RouteIndex)
100         for _, value := range rcs.MeidMap {
101                 if _, v := keys[key+value+"\n"]; !v {
102                         rawrt = append(rawrt, key+value+"\n")
103                         appendedindex := uint16(len(rawrt) - 1)
104                         keys[key+value+"\n"] = RouteIndex{true, appendedindex}
105                         count++
106                 }
107                 if strings.Contains(value, "mme_ar") {
108                         tmpstr := strings.Split(value, "|")
109
110                         //MEID entry for mme_ar must always contain 3 strings speartred by | i.e "mme_ar|<string1>|<string2>"
111                         MEID := strings.TrimSuffix(tmpstr[2], "\n")
112
113                         mapindex := "mme_del|" + MEID + "\n"
114                         i := keys[mapindex].index
115                         if keys[mapindex].flag {
116                                 //copy(rawrt[i:], rawrt[i+1:])
117                                 //rawrt[len(rawrt)-1] = ""
118                                 //rawrt = rawrt[:len(rawrt)-1]
119                                 rawrt[i] = ""
120                                 delete(keys, mapindex)
121                                 count--
122                         }
123                 }
124         }
125         rawrt = removeEmptyStrings(rawrt)
126         rawrt = append(rawrt, key+"meid_map|end|"+strconv.Itoa(count)+"\n")
127
128         xapp.Logger.Debug("rmr.GeneratePolicies returns: %v", rawrt)
129         xapp.Logger.Debug("rmr.GeneratePolicies returns: %v", rcs)
130         return &rawrt
131 }
132
133 /*
134 Produces the raw route message consumable by RMR
135 */
136 func (r *Rmr) generatePartialRMRPolicies(eps rtmgr.Endpoints, xappSubData *models.XappSubscriptionData, key string, updatetype rtmgr.RMRUpdateType) *[]string {
137         rawrt := []string{key + "updatert|start\n"}
138         rt := r.generatePartialRouteTable(eps, xappSubData, updatetype)
139         for _, rte := range *rt {
140                 rawrte := key + "mse|" + rte.MessageType
141                 for _, tx := range rte.TxList {
142                         rawrte += "," + tx.Ip + ":" + strconv.Itoa(int(tx.Port))
143                 }
144                 rawrte += "|" + strconv.Itoa(int(rte.SubID)) + "|"
145                 group := ""
146                 for _, rxg := range rte.RxGroups {
147                         member := ""
148                         for _, rx := range rxg {
149                                 if member == "" {
150                                         member += rx.Ip + ":" + strconv.Itoa(int(rx.Port))
151                                 } else {
152                                         member += "," + rx.Ip + ":" + strconv.Itoa(int(rx.Port))
153                                 }
154                         }
155                         if group == "" {
156                                 group += member
157                         } else {
158                                 group += ";" + member
159                         }
160                 }
161
162                 if rte.RouteType == "%meid" {
163                         rawrte += "%" + "meid"
164                 } else {
165                         rawrte += group
166                 }
167
168                 rawrt = append(rawrt, rawrte+"\n")
169         }
170
171         rawrt = append(rawrt, key+"updatert|end\n")
172         //count := 0
173
174         xapp.Logger.Debug("rmr.GeneratePolicies returns: %v", rawrt)
175         return &rawrt
176 }
177 func (r *RmrPush) GeneratePolicies(eps rtmgr.Endpoints, rcs *rtmgr.RicComponents) *[]string {
178         xapp.Logger.Debug("Invoked rmr.GeneratePolicies, args: %v: ", eps)
179         return r.generateRMRPolicies(eps, rcs, "")
180 }
181
182 func (r *RmrPush) GenerateRouteTable(eps rtmgr.Endpoints) *rtmgr.RouteTable {
183         return r.generateRouteTable(eps)
184 }
185
186 func (r *RmrPush) GeneratePartialPolicies(eps rtmgr.Endpoints, xappSubData *models.XappSubscriptionData, updatetype rtmgr.RMRUpdateType) *[]string {
187         xapp.Logger.Debug("Invoked rmr.GeneratePartialPolicies, args: %v: ", eps)
188         return r.generatePartialRMRPolicies(eps, xappSubData, "", updatetype)
189 }
190
191 func removeEmptyStrings(s []string) []string {
192         var r []string
193         for _, str := range s {
194                 if str != "" {
195                         r = append(r, str)
196                 }
197         }
198         return r
199 }