8222e72984da7d048617c5d9481362b3c312bc80
[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                         rtmgr.RMRConnStatus[ep] = false //Reset to false incase of E2t restart scenario
320                         return nil
321                 }
322         }
323
324         return errors.New("Error while adding new E2T " + *data.E2TAddress)
325
326 }
327
328 func validateE2TAddressRANListData(assRanE2tData models.RanE2tMap) error {
329
330         xapp.Logger.Debug("Invoked.validateE2TAddressRANListData : %v", assRanE2tData)
331
332         for _, element := range assRanE2tData {
333                 if *element.E2TAddress == "" {
334                         return fmt.Errorf("E2T Instance - E2TAddress is empty!!!")
335                 }
336
337                 e2taddress_key := *element.E2TAddress
338                 if !checkValidaE2TAddress(e2taddress_key) {
339                         return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v", e2taddress_key)
340                 }
341
342         }
343         return nil
344 }
345
346 func AssociateRanToE2THandlerImpl(data models.RanE2tMap) error {
347         xapp.Logger.Debug("Invoked associateRanToE2THandlerImpl")
348         err := validateE2TAddressRANListData(data)
349         if err != nil {
350                 xapp.Logger.Warn(" Association of RAN to E2T Instance data validation failed: " + err.Error())
351                 return err
352         }
353         xapp.Logger.Debug("Received associate RAN list to E2T instance mapping from E2 Manager")
354         m.Lock()
355         sdlEngine.WriteAssRANToE2TInstance(xapp.Config.GetString("rtfile"), data)
356         m.Unlock()
357         updateEp()
358         return sendRoutesToAll()
359
360 }
361
362 func DisassociateRanToE2THandlerImpl(data models.RanE2tMap) error {
363         xapp.Logger.Debug("Invoked disassociateRanToE2THandlerImpl")
364         err := validateE2TAddressRANListData(data)
365         if err != nil {
366                 xapp.Logger.Warn(" Disassociation of RAN List from E2T Instance data validation failed: " + err.Error())
367                 return err
368         }
369         xapp.Logger.Debug("Received disassociate RANs from E2T instance")
370         m.Lock()
371         sdlEngine.WriteDisAssRANFromE2TInstance(xapp.Config.GetString("rtfile"), data)
372         m.Unlock()
373         updateEp()
374         return sendRoutesToAll()
375
376 }
377
378 func DeleteE2tHandleHandlerImpl(data *models.E2tDeleteData) error {
379         xapp.Logger.Debug("Invoked deleteE2tHandleHandlerImpl")
380
381         err := validateDeleteE2tData(data)
382         if err != nil {
383                 xapp.Logger.Error(err.Error())
384                 return err
385         }
386         m.Lock()
387         sdlEngine.WriteDeleteE2TInstance(xapp.Config.GetString("rtfile"), data)
388         m.Unlock()
389         updateEp()
390         return sendRoutesToAll()
391
392 }
393
394 func DumpDebugData() (models.Debuginfo, error) {
395         var response models.Debuginfo
396         sdlEngine, _ := sdl.GetSdl("file")
397         rpeEngine, _ := rpe.GetRpe("rmrpush")
398         data, err := sdlEngine.ReadAll(xapp.Config.GetString("rtfile"))
399         if data == nil {
400                 if err != nil {
401                         xapp.Logger.Error("Cannot get data from sdl interface due to: " + err.Error())
402                         return response, err
403                 } else {
404                         xapp.Logger.Debug("Cannot get data from sdl interface")
405                         return response, errors.New("Cannot get data from sdl interface")
406                 }
407         }
408         response.RouteTable = *rpeEngine.GeneratePolicies(rtmgr.Eps, data)
409
410         prettyJSON, err := json.MarshalIndent(data, "", "")
411         response.RouteConfigs = string(prettyJSON)
412
413         return response, err
414 }
415
416 func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
417         xapp.Logger.Info("Invoked httprestful.httpGetXApps: " + xmurl)
418         r, err := myClient.Get(xmurl)
419         if err != nil {
420                 return nil, err
421         }
422         defer r.Body.Close()
423
424         if r.StatusCode == 200 {
425                 xapp.Logger.Debug("http client raw response: %v", r)
426                 var xapps []rtmgr.XApp
427                 err = json.NewDecoder(r.Body).Decode(&xapps)
428                 if err != nil {
429                         xapp.Logger.Warn("Json decode failed: " + err.Error())
430                 }
431                 xapp.Logger.Info("HTTP GET: OK")
432                 xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", xapps)
433                 return &xapps, err
434         }
435         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
436         return nil, nil
437 }
438
439 func httpGetE2TList(e2murl string) (*[]rtmgr.E2tIdentity, error) {
440         xapp.Logger.Info("Invoked httprestful.httpGetE2TList: " + e2murl)
441         r, err := myClient.Get(e2murl)
442         if err != nil {
443                 return nil, err
444         }
445         defer r.Body.Close()
446
447         if r.StatusCode == 200 {
448                 xapp.Logger.Debug("http client raw response: %v", r)
449                 var E2Tlist []rtmgr.E2tIdentity
450                 err = json.NewDecoder(r.Body).Decode(&E2Tlist)
451                 if err != nil {
452                         xapp.Logger.Warn("Json decode failed: " + err.Error())
453                 }
454                 xapp.Logger.Info("HTTP GET: OK")
455                 xapp.Logger.Debug("httprestful.httpGetE2TList returns: %v", E2Tlist)
456                 return &E2Tlist, err
457         }
458         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
459         return nil, nil
460 }
461
462 func PopulateE2TMap(e2tDataList *[]rtmgr.E2tIdentity, e2ts map[string]rtmgr.E2TInstance, meids *[]string) {
463         xapp.Logger.Info("Invoked httprestful.PopulateE2TMap ")
464
465         for _, e2tData := range *e2tDataList {
466                 var str string
467
468                 e2tinst := rtmgr.E2TInstance{
469                         Ranlist: make([]string, len(e2tData.Rannames)),
470                 }
471
472                 e2tinst.Fqdn = e2tData.E2taddress
473                 e2tinst.Name = "E2TERMINST"
474                 copy(e2tinst.Ranlist, e2tData.Rannames)
475
476                 if len(e2tData.Rannames) > 0 {
477                         var meidar string
478                         for _, meid := range e2tData.Rannames {
479                                 meidar += meid + " "
480                         }
481                         str = "mme_ar|" + e2tData.E2taddress + "|" + strings.TrimSuffix(meidar, " ")
482                         *meids = append(*meids, str)
483                 }
484
485                 e2ts[e2tinst.Fqdn] = e2tinst
486         }
487         xapp.Logger.Info("MEID's retrieved are %v", *meids)
488 }
489
490 func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile string, e2murl string, sdlEngine sdl.Engine) error {
491         xapp.Logger.Info("Invoked retrieveStartupData ")
492         var readErr error
493         var err error
494         var maxRetries = 10
495         var xappData *[]rtmgr.XApp
496         xappData = new([]rtmgr.XApp)
497         xapp.Logger.Info("Trying to fetch XApps data from XAPP manager")
498         for i := 1; i <= maxRetries; i++ {
499                 time.Sleep(2 * time.Second)
500
501                 readErr = nil
502                 xappData, err = httpGetXApps(xmurl)
503                 if xappData != nil && err == nil {
504                         break
505                 } else if err == nil {
506                         readErr = errors.New("unexpected HTTP status code")
507                 } else {
508                         xapp.Logger.Warn("Cannot get xapp data due to: " + err.Error())
509                         readErr = err
510                 }
511         }
512
513         if readErr != nil {
514                 return readErr
515         }
516
517         var meids []string
518         e2ts := make(map[string]rtmgr.E2TInstance)
519         xapp.Logger.Info("Trying to fetch E2T data from E2manager")
520         for i := 1; i <= maxRetries; i++ {
521
522                 readErr = nil
523                 e2tDataList, err := httpGetE2TList(e2murl)
524                 if e2tDataList != nil && err == nil {
525                         PopulateE2TMap(e2tDataList, e2ts, &meids)
526                         break
527                 } else if err == nil {
528                         readErr = errors.New("unexpected HTTP status code")
529                 } else {
530                         xapp.Logger.Warn("Cannot get E2T data from E2M due to: " + err.Error())
531                         readErr = err
532                 }
533                 time.Sleep(2 * time.Second)
534         }
535
536         if readErr != nil {
537                 return readErr
538         }
539
540         pcData, confErr := rtmgr.GetPlatformComponents(configfile)
541         if confErr != nil {
542                 xapp.Logger.Error(confErr.Error())
543                 return confErr
544         }
545         xapp.Logger.Info("Recieved intial xapp data, E2T data and platform data, writing into SDL.")
546         // Combine the xapps data and platform data before writing to the SDL
547         ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData, E2Ts: e2ts, MeidMap: meids}
548         writeErr := sdlEngine.WriteAll(fileName, ricData)
549         if writeErr != nil {
550                 xapp.Logger.Error(writeErr.Error())
551         }
552
553         xapp.Logger.Info("Trying to fetch Subscriptions data from Subscription manager")
554         for i := 1; i <= maxRetries; i++ {
555                 readErr = nil
556                 sub_list, err := xapp.Subscription.QuerySubscriptions()
557
558                 if sub_list != nil && err == nil {
559                         PopulateSubscription(sub_list)
560                         break
561                 } else {
562                         readErr = err
563                         xapp.Logger.Warn("Cannot get xapp data due to: " + readErr.Error())
564                 }
565                 time.Sleep(2 * time.Second)
566         }
567
568         if readErr != nil {
569                 return readErr
570         }
571
572         // post subscription req to appmgr
573         readErr = PostSubReq(xmurl, nbiif)
574         if readErr != nil {
575                 return readErr
576         }
577
578         //rlist := make(map[string]string)
579         xapp.Logger.Info("Reading SDL for any routes")
580         rlist, sdlerr := xapp.SdlStorage.Read(rtmgr.RTMGR_SDL_NS, "routes")
581         readErr = sdlerr
582         if readErr == nil {
583                 xapp.Logger.Info("Value is %s", rlist["routes"])
584                 if rlist["routes"] != nil {
585                         formstring := fmt.Sprintf("%s", rlist["routes"])
586                         xapp.Logger.Info("Value of formed string = %s", formstring)
587                         newstring := strings.Split(formstring, " ")
588                         for i, _ := range newstring {
589                                 xapp.Logger.Info("Value of formed string in loop = %s", newstring)
590                                 rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, newstring[i])
591                         }
592                 }
593
594                 return nil
595         }
596
597         return readErr
598 }
599
600 func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string, e2murl string,
601         sdlEngine sdl.Engine, rpeEngine rpe.Engine, m *sync.Mutex) error {
602         err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, e2murl, sdlEngine)
603         if err != nil {
604                 xapp.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
605                 return err
606         }
607
608         return nil
609 }
610
611 func (r *HttpRestful) Terminate() error {
612         return nil
613 }
614
615 func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
616         xapp.Logger.Debug("Adding the subscription into the subscriptions list")
617         var b = false
618         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
619         for _, elem := range *subs {
620                 if elem == sub {
621                         xapp.Logger.Warn("rtmgr.addSubscription: Subscription already present: %v", elem)
622                         b = true
623                 }
624         }
625         if b == false {
626                 *subs = append(*subs, sub)
627         }
628         return b
629 }
630
631 func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
632         xapp.Logger.Debug("Deleteing the subscription from the subscriptions list")
633         var present = false
634         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
635         for i, elem := range *subs {
636                 if elem == sub {
637                         present = true
638                         // Since the order of the list is not important, we are swapping the last element
639                         // with the matching element and replacing the list with list(n-1) elements.
640                         (*subs)[len(*subs)-1], (*subs)[i] = (*subs)[i], (*subs)[len(*subs)-1]
641                         *subs = (*subs)[:len(*subs)-1]
642                         break
643                 }
644         }
645         if present == false {
646                 xapp.Logger.Warn("rtmgr.delSubscription: Subscription = %v, not present in the existing subscriptions", xappSubData)
647         }
648         return present
649 }
650
651 func updateSubscription(data *rtmgr.XappList) {
652
653         var subdata models.XappSubscriptionData
654         var id int32
655         var matchingsubid, deletecount uint8
656         id = int32(data.SubscriptionID)
657         subdata.SubscriptionID = &id
658         for _, subs := range rtmgr.Subs {
659                 if int32(data.SubscriptionID) == subs.SubID {
660                         matchingsubid++
661                 }
662         }
663
664         for deletecount < matchingsubid {
665                 for _, subs := range rtmgr.Subs {
666                         if int32(data.SubscriptionID) == subs.SubID {
667                                 subdata.SubscriptionID = &subs.SubID
668                                 subdata.Address = &subs.Fqdn
669                                 subdata.Port = &subs.Port
670                                 xapp.Logger.Debug("Deleting Subscription List has %v", subdata)
671                                 delSubscription(&rtmgr.Subs, &subdata)
672                                 break
673                         }
674                 }
675                 deletecount++
676         }
677
678         for _, items := range data.FqdnList {
679                 subdata.Address = items.Address
680                 subdata.Port = items.Port
681                 xapp.Logger.Debug("Adding Subscription List has %v", subdata)
682                 addSubscription(&rtmgr.Subs, &subdata)
683         }
684
685 }
686
687 func PopulateSubscription(sub_list xfmodel.SubscriptionList) {
688         for _, sub_row := range sub_list {
689                 var subdata models.XappSubscriptionData
690                 id := int32(sub_row.SubscriptionID)
691                 subdata.SubscriptionID = &id
692                 for _, ep := range sub_row.ClientEndpoint {
693                         stringSlice := strings.Split(ep, ":")
694                         subdata.Address = &stringSlice[0]
695                         intportval, _ := strconv.Atoi(stringSlice[1])
696                         value := uint16(intportval)
697                         subdata.Port = &value
698                         xapp.Logger.Debug("Adding Subscription List has Address :%v, port :%v, SubscriptionID :%v ", subdata.Address, subdata.Address, subdata.SubscriptionID)
699                         addSubscription(&rtmgr.Subs, &subdata)
700                 }
701         }
702 }
703
704 func Adddelrmrroute(routelist models.Routelist, rtflag bool) error {
705         xapp.Logger.Info("Updating rmr route with Route list: %v,flag: %v", routelist, rtflag)
706         for _, rlist := range routelist {
707                 var subid int32
708                 var data string
709                 if rlist.SubscriptionID == 0 {
710                         subid = -1
711                 } else {
712                         subid = rlist.SubscriptionID
713                 }
714                 if rlist.SenderEndPoint == "" && rlist.SubscriptionID != 0 {
715                         data = fmt.Sprintf("mse|%d|%d|%s\n", *rlist.MessageType, rlist.SubscriptionID, *rlist.TargetEndPoint)
716                 } else if rlist.SenderEndPoint == "" && rlist.SubscriptionID == 0 {
717                         data = fmt.Sprintf("mse|%d|-1|%s\n", *rlist.MessageType, *rlist.TargetEndPoint)
718                 } else {
719                         data = fmt.Sprintf("mse|%d,%s|%d|%s\n", *rlist.MessageType, rlist.SenderEndPoint, subid, *rlist.TargetEndPoint)
720                 }
721                 err := checkrepeatedroute(data)
722
723                 if rtflag == true {
724                         if err == true {
725                                 xapp.Logger.Info("Given route %s is a duplicate", data)
726                         }
727                         rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, data)
728                         routearray := strings.Join(rtmgr.DynamicRouteList, " ")
729                         xapp.SdlStorage.Store(rtmgr.RTMGR_SDL_NS, "routes", routearray)
730                 } else {
731                         if err == true {
732                                 xapp.Logger.Info("route %s deleted successfully", data)
733                                 routearray := strings.Join(rtmgr.DynamicRouteList, " ")
734                                 xapp.SdlStorage.Store(rtmgr.RTMGR_SDL_NS, "routes", routearray)
735                         } else {
736                                 xapp.Logger.Info("No such route: %s", data)
737                                 return errors.New("No such route: " + data)
738                         }
739
740                 }
741         }
742         updateEp()
743         return sendRoutesToAll()
744 }
745
746 func checkrepeatedroute(data string) bool {
747         for i := 0; i < len(rtmgr.DynamicRouteList); i++ {
748                 if rtmgr.DynamicRouteList[i] == data {
749                         rtmgr.DynamicRouteList[i] = rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1]
750                         rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1] = ""
751                         rtmgr.DynamicRouteList = rtmgr.DynamicRouteList[:len(rtmgr.DynamicRouteList)-1]
752                         return true
753                 }
754         }
755         return false
756 }