RIC:1060: Change in PTL
[ric-plt/rtmgr.git] / pkg / nbi / httprestful.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:     httprestful.go
26   Abstract:     HTTP Restful API NBI implementation
27                 Based on Swagger generated code
28   Date:         25 March 2019
29 */
30
31 package nbi
32
33 //noinspection GoUnresolvedReference,GoUnresolvedReference,GoUnresolvedReference,GoUnresolvedReference,GoUnresolvedReference,GoUnresolvedReference
34 import (
35         "encoding/json"
36         "errors"
37         "fmt"
38         xfmodel "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
39         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
40         //"github.com/go-openapi/loads"
41         //"github.com/go-openapi/runtime/middleware"
42         "net"
43         //"net/url"
44         //"os"
45         "routing-manager/pkg/models"
46         //"routing-manager/pkg/restapi"
47         //"routing-manager/pkg/restapi/operations"
48         //"routing-manager/pkg/restapi/operations/debug"
49         //"routing-manager/pkg/restapi/operations/handle"
50         "routing-manager/pkg/rpe"
51         "routing-manager/pkg/rtmgr"
52         "routing-manager/pkg/sbi"
53         "routing-manager/pkg/sdl"
54         "strconv"
55         "strings"
56         "sync"
57         "time"
58 )
59
60 type HttpRestful struct {
61         Engine
62         //LaunchRest          LaunchRestHandler
63         RetrieveStartupData RetrieveStartupDataHandler
64 }
65
66 func NewHttpRestful() *HttpRestful {
67         instance := new(HttpRestful)
68         //instance.LaunchRest = launchRest
69         instance.RetrieveStartupData = retrieveStartupData
70         return instance
71 }
72
73 func recvXappCallbackData(xappData *models.XappCallbackData) (*[]rtmgr.XApp, error) {
74         if nil != xappData {
75                 var xapps []rtmgr.XApp
76                 err := json.Unmarshal([]byte(xappData.XApps), &xapps)
77                 return &xapps, err
78         } else {
79                 xapp.Logger.Info("No data")
80         }
81
82         xapp.Logger.Debug("Nothing received on the Http interface")
83         return nil, nil
84 }
85
86 func recvNewE2Tdata(e2tData *models.E2tData) (*rtmgr.E2TInstance, string, error) {
87         var str string
88         xapp.Logger.Info("Data received")
89
90         if nil != e2tData {
91
92                 e2tinst := rtmgr.E2TInstance{
93                         Ranlist: make([]string, len(e2tData.RanNamelist)),
94                 }
95
96                 e2tinst.Fqdn = *e2tData.E2TAddress
97                 e2tinst.Name = "E2TERMINST"
98                 copy(e2tinst.Ranlist, e2tData.RanNamelist)
99                 if len(e2tData.RanNamelist) > 0 {
100                         var meidar string
101                         for _, meid := range e2tData.RanNamelist {
102                                 meidar += meid + " "
103                         }
104                         str = "mme_ar|" + *e2tData.E2TAddress + "|" + strings.TrimSuffix(meidar, " ")
105                 }
106                 return &e2tinst, str, nil
107
108         } else {
109                 xapp.Logger.Info("No data")
110         }
111
112         xapp.Logger.Debug("Nothing received on the Http interface")
113         return nil, str, nil
114 }
115
116 func validateXappCallbackData(callbackData *models.XappCallbackData) error {
117         if len(callbackData.XApps) == 0 {
118                 return fmt.Errorf("invalid Data field: \"%s\"", callbackData.XApps)
119         }
120         var xapps []rtmgr.XApp
121         err := json.Unmarshal([]byte(callbackData.XApps), &xapps)
122         if err != nil {
123                 return fmt.Errorf("unmarshal failed: \"%s\"", err.Error())
124         }
125         return nil
126 }
127
128 func ProvideXappHandleHandlerImpl(data *models.XappCallbackData) error {
129         if data == nil {
130                 xapp.Logger.Debug("Received callback data")
131                 return nil
132         }
133         err := validateXappCallbackData(data)
134         if err != nil {
135                 xapp.Logger.Warn("XApp callback data validation failed: " + err.Error())
136                 return err
137         } else {
138                 appdata, err := recvXappCallbackData(data)
139                 if err != nil {
140                         xapp.Logger.Error("Cannot get data from rest api dute to: " + err.Error())
141                 } else if appdata != nil {
142                         xapp.Logger.Debug("Fetching all xApps deployed in xApp Manager through GET operation")
143                         alldata, err1 := httpGetXApps(xapp.Config.GetString("xmurl"))
144                         if alldata != nil && err1 == nil {
145                                 m.Lock()
146                                 sdlEngine.WriteXApps(xapp.Config.GetString("rtfile"), alldata)
147                                 m.Unlock()
148                                 updateEp()
149                                 return sendRoutesToAll()
150                                 //return sendPartialRoutesToAll(nil, rtmgr.XappType)
151                         }
152                 }
153
154                 return nil
155         }
156 }
157
158 func validateXappSubscriptionData(data *models.XappSubscriptionData) error {
159         var err = fmt.Errorf("XApp instance not found: %v:%v", *data.Address, *data.Port)
160         for _, ep := range rtmgr.Eps {
161                 if ep.Ip == *data.Address && ep.Port == *data.Port {
162                         err = nil
163                         break
164                 }
165         }
166         return err
167 }
168
169 func validateE2tData(data *models.E2tData) (error, bool) {
170
171         e2taddress_key := *data.E2TAddress
172         if e2taddress_key == "" {
173                 return fmt.Errorf("E2TAddress is empty!!!"), false
174         }
175         stringSlice := strings.Split(e2taddress_key, ":")
176         if len(stringSlice) == 1 {
177                 return fmt.Errorf("E2T E2TAddress is not a proper format like ip:port, %v", e2taddress_key), false
178         }
179
180         _, err := net.LookupIP(stringSlice[0])
181         if err != nil {
182                 return fmt.Errorf("E2T E2TAddress DNS look up failed, E2TAddress: %v", stringSlice[0]), false
183         }
184
185         if checkValidaE2TAddress(e2taddress_key) {
186                 return fmt.Errorf("E2TAddress already exist!!!, E2TAddress: %v", e2taddress_key), true
187         }
188
189         return nil, false
190 }
191
192 func validateDeleteE2tData(data *models.E2tDeleteData) error {
193
194         if *data.E2TAddress == "" {
195                 return fmt.Errorf("E2TAddress is empty!!!")
196         }
197
198         for _, element := range data.RanAssocList {
199                 e2taddress_key := *element.E2TAddress
200                 stringSlice := strings.Split(e2taddress_key, ":")
201
202                 if len(stringSlice) == 1 {
203                         return fmt.Errorf("E2T Delete - RanAssocList E2TAddress is not a proper format like ip:port, %v", e2taddress_key)
204                 }
205
206                 if !checkValidaE2TAddress(e2taddress_key) {
207                         return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v", e2taddress_key)
208                 }
209
210         }
211         return nil
212 }
213
214 func checkValidaE2TAddress(e2taddress string) bool {
215
216         _, exist := rtmgr.Eps[e2taddress]
217         return exist
218
219 }
220
221 func ProvideXappSubscriptionHandleImpl(data *models.XappSubscriptionData) error {
222         xapp.Logger.Debug("Invoked provideXappSubscriptionHandleImpl")
223         err := validateXappSubscriptionData(data)
224         if err != nil {
225                 xapp.Logger.Error(err.Error())
226                 return err
227         }
228         xapp.Logger.Debug("Received xApp subscription data")
229         addSubscription(&rtmgr.Subs, data)
230         xapp.Logger.Debug("Endpoints: %v", rtmgr.Eps)
231         updateEp()
232         return sendPartialRoutesToAll(data, rtmgr.SubsType)
233 }
234
235 func subscriptionExists(data *models.XappSubscriptionData) bool {
236         present := false
237         sub := rtmgr.Subscription{SubID: *data.SubscriptionID, Fqdn: *data.Address, Port: *data.Port}
238         for _, elem := range rtmgr.Subs {
239                 if elem == sub {
240                         present = true
241                         break
242                 }
243         }
244         return present
245 }
246
247 func DeleteXappSubscriptionHandleImpl(data *models.XappSubscriptionData) error {
248         xapp.Logger.Debug("Invoked deleteXappSubscriptionHandleImpl")
249         err := validateXappSubscriptionData(data)
250         if err != nil {
251                 xapp.Logger.Error(err.Error())
252                 return err
253         }
254
255         if !subscriptionExists(data) {
256                 xapp.Logger.Warn("Subscription not found: %d", *data.SubscriptionID)
257                 err := fmt.Errorf("Subscription not found: %d", *data.SubscriptionID)
258                 return err
259         }
260
261         xapp.Logger.Debug("Received xApp subscription delete data")
262         delSubscription(&rtmgr.Subs, data)
263         updateEp()
264         return sendRoutesToAll()
265
266 }
267
268 func UpdateXappSubscriptionHandleImpl(data *models.XappList, subid uint16) error {
269         xapp.Logger.Debug("Invoked updateXappSubscriptionHandleImpl")
270
271         var fqdnlist []rtmgr.FqDn
272         for _, item := range *data {
273                 fqdnlist = append(fqdnlist, rtmgr.FqDn(*item))
274         }
275         xapplist := rtmgr.XappList{SubscriptionID: subid, FqdnList: fqdnlist}
276         var subdata models.XappSubscriptionData
277         var id int32
278         id = int32(subid)
279         subdata.SubscriptionID = &id
280         for _, items := range fqdnlist {
281                 subdata.Address = items.Address
282                 subdata.Port = items.Port
283                 err := validateXappSubscriptionData(&subdata)
284                 if err != nil {
285                         xapp.Logger.Error(err.Error())
286                         return err
287                 }
288         }
289         xapp.Logger.Debug("Received XApp subscription Merge data")
290         updateSubscription(&xapplist)
291         updateEp()
292         return sendRoutesToAll()
293 }
294
295 func CreateNewE2tHandleHandlerImpl(data *models.E2tData) error {
296         xapp.Logger.Debug("Invoked createNewE2tHandleHandlerImpl")
297         err, IsDuplicate := validateE2tData(data)
298         if IsDuplicate == true {
299                 updateEp()
300                 //return sendPartialRoutesToAll(nil, rtmgr.E2Type)
301                 return sendRoutesToAll()
302         }
303
304         if err != nil {
305                 xapp.Logger.Error(err.Error())
306                 return err
307         }
308         //e2taddchan <- data
309         e2data, meiddata, _ := recvNewE2Tdata(data)
310         xapp.Logger.Debug("Received create New E2T data")
311         m.Lock()
312         sdlEngine.WriteNewE2TInstance(xapp.Config.GetString("rtfile"), e2data, meiddata)
313         m.Unlock()
314         updateEp()
315         //sendPartialRoutesToAll(nil, rtmgr.E2Type)
316         sbi.Conn.Lock()
317         rtmgr.RMRConnStatus[*data.E2TAddress] = false
318         sbi.Conn.Unlock()
319
320         sendRoutesToAll()
321         time.Sleep(10 * time.Second)
322         if rtmgr.RMRConnStatus[*data.E2TAddress] == true {
323                 sbi.Conn.Lock()
324                 delete(rtmgr.RMRConnStatus, *data.E2TAddress)
325                 sbi.Conn.Unlock()
326                 xapp.Logger.Debug("RMRConnStatus Map after = %v", rtmgr.RMRConnStatus)
327                 return nil
328         }
329
330         return errors.New("Error while adding new E2T " + *data.E2TAddress)
331
332 }
333
334 func validateE2TAddressRANListData(assRanE2tData models.RanE2tMap) error {
335
336         xapp.Logger.Debug("Invoked.validateE2TAddressRANListData : %v", assRanE2tData)
337
338         for _, element := range assRanE2tData {
339                 if *element.E2TAddress == "" {
340                         return fmt.Errorf("E2T Instance - E2TAddress is empty!!!")
341                 }
342
343                 e2taddress_key := *element.E2TAddress
344                 if !checkValidaE2TAddress(e2taddress_key) {
345                         return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v", e2taddress_key)
346                 }
347
348         }
349         return nil
350 }
351
352 func AssociateRanToE2THandlerImpl(data models.RanE2tMap) error {
353         xapp.Logger.Debug("Invoked associateRanToE2THandlerImpl")
354         err := validateE2TAddressRANListData(data)
355         if err != nil {
356                 xapp.Logger.Warn(" Association of RAN to E2T Instance data validation failed: " + err.Error())
357                 return err
358         }
359         xapp.Logger.Debug("Received associate RAN list to E2T instance mapping from E2 Manager")
360         m.Lock()
361         sdlEngine.WriteAssRANToE2TInstance(xapp.Config.GetString("rtfile"), data)
362         m.Unlock()
363         updateEp()
364         return sendRoutesToAll()
365
366 }
367
368 func DisassociateRanToE2THandlerImpl(data models.RanE2tMap) error {
369         xapp.Logger.Debug("Invoked disassociateRanToE2THandlerImpl")
370         err := validateE2TAddressRANListData(data)
371         if err != nil {
372                 xapp.Logger.Warn(" Disassociation of RAN List from E2T Instance data validation failed: " + err.Error())
373                 return err
374         }
375         xapp.Logger.Debug("Received disassociate RANs from E2T instance")
376         m.Lock()
377         sdlEngine.WriteDisAssRANFromE2TInstance(xapp.Config.GetString("rtfile"), data)
378         m.Unlock()
379         updateEp()
380         return sendRoutesToAll()
381
382 }
383
384 func DeleteE2tHandleHandlerImpl(data *models.E2tDeleteData) error {
385         xapp.Logger.Debug("Invoked deleteE2tHandleHandlerImpl")
386
387         err := validateDeleteE2tData(data)
388         if err != nil {
389                 xapp.Logger.Error(err.Error())
390                 return err
391         }
392         m.Lock()
393         sdlEngine.WriteDeleteE2TInstance(xapp.Config.GetString("rtfile"), data)
394         m.Unlock()
395         updateEp()
396         return sendRoutesToAll()
397
398 }
399
400 func DumpDebugData() (models.Debuginfo, error) {
401         var response models.Debuginfo
402         sdlEngine, _ := sdl.GetSdl("file")
403         rpeEngine, _ := rpe.GetRpe("rmrpush")
404         data, err := sdlEngine.ReadAll(xapp.Config.GetString("rtfile"))
405         if data == nil {
406                 if err != nil {
407                         xapp.Logger.Error("Cannot get data from sdl interface due to: " + err.Error())
408                         return response, err
409                 } else {
410                         xapp.Logger.Debug("Cannot get data from sdl interface")
411                         return response, errors.New("Cannot get data from sdl interface")
412                 }
413         }
414         response.RouteTable = *rpeEngine.GeneratePolicies(rtmgr.Eps, data)
415
416         prettyJSON, err := json.MarshalIndent(data, "", "")
417         response.RouteConfigs = string(prettyJSON)
418
419         return response, err
420 }
421
422 func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
423         xapp.Logger.Info("Invoked httprestful.httpGetXApps: " + xmurl)
424         r, err := myClient.Get(xmurl)
425         if err != nil {
426                 return nil, err
427         }
428         defer r.Body.Close()
429
430         if r.StatusCode == 200 {
431                 xapp.Logger.Debug("http client raw response: %v", r)
432                 var xapps []rtmgr.XApp
433                 err = json.NewDecoder(r.Body).Decode(&xapps)
434                 if err != nil {
435                         xapp.Logger.Warn("Json decode failed: " + err.Error())
436                 }
437                 xapp.Logger.Info("HTTP GET: OK")
438                 xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", xapps)
439                 return &xapps, err
440         }
441         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
442         return nil, nil
443 }
444
445 func httpGetE2TList(e2murl string) (*[]rtmgr.E2tIdentity, error) {
446         xapp.Logger.Info("Invoked httprestful.httpGetE2TList: " + e2murl)
447         r, err := myClient.Get(e2murl)
448         if err != nil {
449                 return nil, err
450         }
451         defer r.Body.Close()
452
453         if r.StatusCode == 200 {
454                 xapp.Logger.Debug("http client raw response: %v", r)
455                 var E2Tlist []rtmgr.E2tIdentity
456                 err = json.NewDecoder(r.Body).Decode(&E2Tlist)
457                 if err != nil {
458                         xapp.Logger.Warn("Json decode failed: " + err.Error())
459                 }
460                 xapp.Logger.Info("HTTP GET: OK")
461                 xapp.Logger.Debug("httprestful.httpGetE2TList returns: %v", E2Tlist)
462                 return &E2Tlist, err
463         }
464         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
465         return nil, nil
466 }
467
468 func PopulateE2TMap(e2tDataList *[]rtmgr.E2tIdentity, e2ts map[string]rtmgr.E2TInstance, meids *[]string) {
469         xapp.Logger.Info("Invoked httprestful.PopulateE2TMap ")
470
471         for _, e2tData := range *e2tDataList {
472                 var str string
473
474                 e2tinst := rtmgr.E2TInstance{
475                         Ranlist: make([]string, len(e2tData.Rannames)),
476                 }
477
478                 e2tinst.Fqdn = e2tData.E2taddress
479                 e2tinst.Name = "E2TERMINST"
480                 copy(e2tinst.Ranlist, e2tData.Rannames)
481
482                 if len(e2tData.Rannames) > 0 {
483                         var meidar string
484                         for _, meid := range e2tData.Rannames {
485                                 meidar += meid + " "
486                         }
487                         str = "mme_ar|" + e2tData.E2taddress + "|" + strings.TrimSuffix(meidar, " ")
488                         *meids = append(*meids, str)
489                 }
490
491                 e2ts[e2tinst.Fqdn] = e2tinst
492         }
493         xapp.Logger.Info("MEID's retrieved are %v", *meids)
494 }
495
496 func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile string, e2murl string, sdlEngine sdl.Engine) error {
497         xapp.Logger.Info("Invoked retrieveStartupData ")
498         var readErr error
499         var err error
500         var maxRetries = 10
501         var xappData *[]rtmgr.XApp
502         xappData = new([]rtmgr.XApp)
503         xapp.Logger.Info("Trying to fetch XApps data from XAPP manager")
504         for i := 1; i <= maxRetries; i++ {
505                 time.Sleep(2 * time.Second)
506
507                 readErr = nil
508                 xappData, err = httpGetXApps(xmurl)
509                 if xappData != nil && err == nil {
510                         break
511                 } else if err == nil {
512                         readErr = errors.New("unexpected HTTP status code")
513                 } else {
514                         xapp.Logger.Warn("Cannot get xapp data due to: " + err.Error())
515                         readErr = err
516                 }
517         }
518
519         if readErr != nil {
520                 return readErr
521         }
522
523         var meids []string
524         e2ts := make(map[string]rtmgr.E2TInstance)
525         xapp.Logger.Info("Trying to fetch E2T data from E2manager")
526         for i := 1; i <= maxRetries; i++ {
527
528                 readErr = nil
529                 e2tDataList, err := httpGetE2TList(e2murl)
530                 if e2tDataList != nil && err == nil {
531                         PopulateE2TMap(e2tDataList, e2ts, &meids)
532                         break
533                 } else if err == nil {
534                         readErr = errors.New("unexpected HTTP status code")
535                 } else {
536                         xapp.Logger.Warn("Cannot get E2T data from E2M due to: " + err.Error())
537                         readErr = err
538                 }
539                 time.Sleep(2 * time.Second)
540         }
541
542         if readErr != nil {
543                 return readErr
544         }
545
546         pcData, confErr := rtmgr.GetPlatformComponents(configfile)
547         if confErr != nil {
548                 xapp.Logger.Error(confErr.Error())
549                 return confErr
550         }
551         xapp.Logger.Info("Recieved intial xapp data, E2T data and platform data, writing into SDL.")
552         // Combine the xapps data and platform data before writing to the SDL
553         ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData, E2Ts: e2ts, MeidMap: meids}
554         writeErr := sdlEngine.WriteAll(fileName, ricData)
555         if writeErr != nil {
556                 xapp.Logger.Error(writeErr.Error())
557         }
558
559         xapp.Logger.Info("Trying to fetch Subscriptions data from Subscription manager")
560         for i := 1; i <= maxRetries; i++ {
561                 readErr = nil
562                 sub_list, err := xapp.Subscription.QuerySubscriptions()
563
564                 if sub_list != nil && err == nil {
565                         PopulateSubscription(sub_list)
566                         break
567                 } else {
568                         readErr = err
569                         xapp.Logger.Warn("Cannot get xapp data due to: " + readErr.Error())
570                 }
571                 time.Sleep(2 * time.Second)
572         }
573
574         if readErr != nil {
575                 return readErr
576         }
577
578         // post subscription req to appmgr
579         readErr = PostSubReq(xmurl, nbiif)
580         if readErr != nil {
581                 return readErr
582         }
583
584         //rlist := make(map[string]string)
585         xapp.Logger.Info("Reading SDL for any routes")
586         rlist, sdlerr := xapp.SdlStorage.Read(rtmgr.RTMGR_SDL_NS, "routes")
587         readErr = sdlerr
588         if readErr == nil {
589                 xapp.Logger.Info("Value is %s", rlist["routes"])
590                 if rlist["routes"] != nil {
591                         formstring := fmt.Sprintf("%s", rlist["routes"])
592                         xapp.Logger.Info("Value of formed string = %s", formstring)
593                         newstring := strings.Split(formstring, " ")
594                         for i, _ := range newstring {
595                                 xapp.Logger.Info("Value of formed string in loop = %s", newstring)
596                                 rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, newstring[i])
597                         }
598                 }
599
600                 return nil
601         }
602
603         return readErr
604 }
605
606 func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string, e2murl string,
607         sdlEngine sdl.Engine, rpeEngine rpe.Engine, m *sync.Mutex) error {
608         err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, e2murl, sdlEngine)
609         if err != nil {
610                 xapp.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
611                 return err
612         }
613
614         return nil
615 }
616
617 func (r *HttpRestful) Terminate() error {
618         return nil
619 }
620
621 func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
622         xapp.Logger.Debug("Adding the subscription into the subscriptions list")
623         var b = false
624         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
625         for _, elem := range *subs {
626                 if elem == sub {
627                         xapp.Logger.Warn("rtmgr.addSubscription: Subscription already present: %v", elem)
628                         b = true
629                 }
630         }
631         if b == false {
632                 *subs = append(*subs, sub)
633         }
634         return b
635 }
636
637 func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
638         xapp.Logger.Debug("Deleteing the subscription from the subscriptions list")
639         var present = false
640         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
641         for i, elem := range *subs {
642                 if elem == sub {
643                         present = true
644                         // Since the order of the list is not important, we are swapping the last element
645                         // with the matching element and replacing the list with list(n-1) elements.
646                         (*subs)[len(*subs)-1], (*subs)[i] = (*subs)[i], (*subs)[len(*subs)-1]
647                         *subs = (*subs)[:len(*subs)-1]
648                         break
649                 }
650         }
651         if present == false {
652                 xapp.Logger.Warn("rtmgr.delSubscription: Subscription = %v, not present in the existing subscriptions", xappSubData)
653         }
654         return present
655 }
656
657 func updateSubscription(data *rtmgr.XappList) {
658
659         var subdata models.XappSubscriptionData
660         var id int32
661         var matchingsubid, deletecount uint8
662         id = int32(data.SubscriptionID)
663         subdata.SubscriptionID = &id
664         for _, subs := range rtmgr.Subs {
665                 if int32(data.SubscriptionID) == subs.SubID {
666                         matchingsubid++
667                 }
668         }
669
670         for deletecount < matchingsubid {
671                 for _, subs := range rtmgr.Subs {
672                         if int32(data.SubscriptionID) == subs.SubID {
673                                 subdata.SubscriptionID = &subs.SubID
674                                 subdata.Address = &subs.Fqdn
675                                 subdata.Port = &subs.Port
676                                 xapp.Logger.Debug("Deleting Subscription List has %v", subdata)
677                                 delSubscription(&rtmgr.Subs, &subdata)
678                                 break
679                         }
680                 }
681                 deletecount++
682         }
683
684         for _, items := range data.FqdnList {
685                 subdata.Address = items.Address
686                 subdata.Port = items.Port
687                 xapp.Logger.Debug("Adding Subscription List has %v", subdata)
688                 addSubscription(&rtmgr.Subs, &subdata)
689         }
690
691 }
692
693 func PopulateSubscription(sub_list xfmodel.SubscriptionList) {
694         for _, sub_row := range sub_list {
695                 var subdata models.XappSubscriptionData
696                 id := int32(sub_row.SubscriptionID)
697                 subdata.SubscriptionID = &id
698                 for _, ep := range sub_row.ClientEndpoint {
699                         stringSlice := strings.Split(ep, ":")
700                         subdata.Address = &stringSlice[0]
701                         intportval, _ := strconv.Atoi(stringSlice[1])
702                         value := uint16(intportval)
703                         subdata.Port = &value
704                         xapp.Logger.Debug("Adding Subscription List has Address :%v, port :%v, SubscriptionID :%v ", subdata.Address, subdata.Address, subdata.SubscriptionID)
705                         addSubscription(&rtmgr.Subs, &subdata)
706                 }
707         }
708 }
709
710 func Adddelrmrroute(routelist models.Routelist, rtflag bool) error {
711         xapp.Logger.Info("Updating rmr route with Route list: %v,flag: %v", routelist, rtflag)
712         for _, rlist := range routelist {
713                 var subid int32
714                 var data string
715                 if rlist.SubscriptionID == 0 {
716                         subid = -1
717                 } else {
718                         subid = rlist.SubscriptionID
719                 }
720                 if rlist.SenderEndPoint == "" && rlist.SubscriptionID != 0 {
721                         data = fmt.Sprintf("mse|%d|%d|%s\n", *rlist.MessageType, rlist.SubscriptionID, *rlist.TargetEndPoint)
722                 } else if rlist.SenderEndPoint == "" && rlist.SubscriptionID == 0 {
723                         data = fmt.Sprintf("mse|%d|-1|%s\n", *rlist.MessageType, *rlist.TargetEndPoint)
724                 } else {
725                         data = fmt.Sprintf("mse|%d,%s|%d|%s\n", *rlist.MessageType, rlist.SenderEndPoint, subid, *rlist.TargetEndPoint)
726                 }
727                 err := checkrepeatedroute(data)
728
729                 if rtflag == true {
730                         if err == true {
731                                 xapp.Logger.Info("Given route %s is a duplicate", data)
732                         }
733                         rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, data)
734                         routearray := strings.Join(rtmgr.DynamicRouteList, " ")
735                         xapp.SdlStorage.Store(rtmgr.RTMGR_SDL_NS, "routes", routearray)
736                 } else {
737                         if err == true {
738                                 xapp.Logger.Info("route %s deleted successfully", data)
739                                 routearray := strings.Join(rtmgr.DynamicRouteList, " ")
740                                 xapp.SdlStorage.Store(rtmgr.RTMGR_SDL_NS, "routes", routearray)
741                         } else {
742                                 xapp.Logger.Info("No such route: %s", data)
743                                 return errors.New("No such route: " + data)
744                         }
745
746                 }
747         }
748         updateEp()
749         return sendRoutesToAll()
750 }
751
752 func checkrepeatedroute(data string) bool {
753         for i := 0; i < len(rtmgr.DynamicRouteList); i++ {
754                 if rtmgr.DynamicRouteList[i] == data {
755                         rtmgr.DynamicRouteList[i] = rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1]
756                         rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1] = ""
757                         rtmgr.DynamicRouteList = rtmgr.DynamicRouteList[:len(rtmgr.DynamicRouteList)-1]
758                         return true
759                 }
760         }
761         return false
762 }