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