Routing manager needs to support for xApps that terminate other protocols than E2
[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         }
131         err := validateXappCallbackData(data)
132         if err != nil {
133                 xapp.Logger.Warn("XApp callback data validation failed: " + err.Error())
134                 return err
135         } else {
136                 appdata, err := recvXappCallbackData(data)
137                 if err != nil {
138                         xapp.Logger.Error("cannot get data from rest api dute to: " + err.Error())
139                 } else if appdata != nil {
140                         xapp.Logger.Debug("Fetching all xApps deployed in xApp Manager through GET operation.")
141                         alldata, err1 := httpGetXApps(xapp.Config.GetString("xmurl"))
142                         if alldata != nil && err1 == nil {
143                                 m.Lock()
144                                 sdlEngine.WriteXApps(xapp.Config.GetString("rtfile"), alldata)
145                                 m.Unlock()
146                                 return sendRoutesToAll()
147                         }
148                 }
149
150                 return nil
151         }
152 }
153
154 func validateXappSubscriptionData(data *models.XappSubscriptionData) error {
155         var err = fmt.Errorf("XApp instance not found: %v:%v", *data.Address, *data.Port)
156         for _, ep := range rtmgr.Eps {
157                 if ep.Ip == *data.Address && ep.Port == *data.Port {
158                         err = nil
159                         break
160                 }
161         }
162         return err
163 }
164
165 func validateE2tData(data *models.E2tData) error {
166
167         e2taddress_key := *data.E2TAddress
168         if e2taddress_key == "" {
169                 return fmt.Errorf("E2TAddress is empty!!!")
170         }
171         stringSlice := strings.Split(e2taddress_key, ":")
172         if len(stringSlice) == 1 {
173                 return fmt.Errorf("E2T E2TAddress is not a proper format like ip:port, %v", e2taddress_key)
174         }
175
176         _, err := net.LookupIP(stringSlice[0])
177         if err != nil {
178                 return fmt.Errorf("E2T E2TAddress DNS look up failed, E2TAddress: %v", stringSlice[0])
179         }
180
181         if checkValidaE2TAddress(e2taddress_key) {
182                 return fmt.Errorf("E2TAddress already exist!!!, E2TAddress: %v", e2taddress_key)
183         }
184
185         return nil
186 }
187
188 func validateDeleteE2tData(data *models.E2tDeleteData) error {
189
190         if *data.E2TAddress == "" {
191                 return fmt.Errorf("E2TAddress is empty!!!")
192         }
193
194         for _, element := range data.RanAssocList {
195                 e2taddress_key := *element.E2TAddress
196                 stringSlice := strings.Split(e2taddress_key, ":")
197
198                 if len(stringSlice) == 1 {
199                         return fmt.Errorf("E2T Delete - RanAssocList E2TAddress is not a proper format like ip:port, %v", e2taddress_key)
200                 }
201
202                 if !checkValidaE2TAddress(e2taddress_key) {
203                         return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v", e2taddress_key)
204                 }
205
206         }
207         return nil
208 }
209
210 func checkValidaE2TAddress(e2taddress string) bool {
211
212         _, exist := rtmgr.Eps[e2taddress]
213         return exist
214
215 }
216
217 func provideXappSubscriptionHandleImpl(data *models.XappSubscriptionData) error {
218         xapp.Logger.Debug("Invoked provideXappSubscriptionHandleImpl")
219         err := validateXappSubscriptionData(data)
220         if err != nil {
221                 xapp.Logger.Error(err.Error())
222                 return err
223         }
224         xapp.Logger.Debug("received XApp subscription data")
225         addSubscription(&rtmgr.Subs, data)
226         xapp.Logger.Debug("Endpoints: %v", rtmgr.Eps)
227         return sendRoutesToAll()
228 }
229
230 func subscriptionExists(data *models.XappSubscriptionData) bool {
231         present := false
232         sub := rtmgr.Subscription{SubID: *data.SubscriptionID, Fqdn: *data.Address, Port: *data.Port}
233         for _, elem := range rtmgr.Subs {
234                 if elem == sub {
235                         present = true
236                         break
237                 }
238         }
239         return present
240 }
241
242 func deleteXappSubscriptionHandleImpl(data *models.XappSubscriptionData) error {
243         xapp.Logger.Debug("Invoked deleteXappSubscriptionHandleImpl")
244         err := validateXappSubscriptionData(data)
245         if err != nil {
246                 xapp.Logger.Error(err.Error())
247                 return err
248         }
249
250         if !subscriptionExists(data) {
251                 xapp.Logger.Warn("subscription not found: %d", *data.SubscriptionID)
252                 err := fmt.Errorf("subscription not found: %d", *data.SubscriptionID)
253                 return err
254         }
255
256         xapp.Logger.Debug("received XApp subscription delete data")
257         delSubscription(&rtmgr.Subs, data)
258         return sendRoutesToAll()
259
260 }
261
262 func updateXappSubscriptionHandleImpl(data *models.XappList, subid uint16) error {
263         xapp.Logger.Debug("Invoked updateXappSubscriptionHandleImpl")
264
265         var fqdnlist []rtmgr.FqDn
266         for _, item := range *data {
267                 fqdnlist = append(fqdnlist, rtmgr.FqDn(*item))
268         }
269         xapplist := rtmgr.XappList{SubscriptionID: subid, FqdnList: fqdnlist}
270         var subdata models.XappSubscriptionData
271         var id int32
272         id = int32(subid)
273         subdata.SubscriptionID = &id
274         for _, items := range fqdnlist {
275                 subdata.Address = items.Address
276                 subdata.Port = items.Port
277                 err := validateXappSubscriptionData(&subdata)
278                 if err != nil {
279                         xapp.Logger.Error(err.Error())
280                         return err
281                 }
282         }
283         xapp.Logger.Debug("received XApp subscription Merge data")
284         updateSubscription(&xapplist)
285         return sendRoutesToAll()
286 }
287
288 func createNewE2tHandleHandlerImpl(data *models.E2tData) error {
289         xapp.Logger.Debug("Invoked createNewE2tHandleHandlerImpl")
290         err := validateE2tData(data)
291         if err != nil {
292                 xapp.Logger.Error(err.Error())
293                 return err
294         }
295         //e2taddchan <- data
296         e2data, meiddata, _ := recvNewE2Tdata(data)
297         xapp.Logger.Debug("received create New E2T data")
298         m.Lock()
299         sdlEngine.WriteNewE2TInstance(xapp.Config.GetString("rtfile"), e2data, meiddata)
300         m.Unlock()
301         return sendRoutesToAll()
302
303 }
304
305 func validateE2TAddressRANListData(assRanE2tData models.RanE2tMap) error {
306
307         xapp.Logger.Debug("Invoked.validateE2TAddressRANListData : %v", assRanE2tData)
308
309         for _, element := range assRanE2tData {
310                 if *element.E2TAddress == "" {
311                         return fmt.Errorf("E2T Instance - E2TAddress is empty!!!")
312                 }
313
314                 e2taddress_key := *element.E2TAddress
315                 if !checkValidaE2TAddress(e2taddress_key) {
316                         return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v", e2taddress_key)
317                 }
318
319         }
320         return nil
321 }
322
323 func associateRanToE2THandlerImpl(data models.RanE2tMap) error {
324         xapp.Logger.Debug("Invoked associateRanToE2THandlerImpl")
325         err := validateE2TAddressRANListData(data)
326         if err != nil {
327                 xapp.Logger.Warn(" Association of RAN to E2T Instance data validation failed: " + err.Error())
328                 return err
329         }
330         xapp.Logger.Debug("received associate RAN list to E2T instance mapping from E2 Manager")
331         m.Lock()
332         sdlEngine.WriteAssRANToE2TInstance(xapp.Config.GetString("rtfile"), data)
333         m.Unlock()
334         return sendRoutesToAll()
335
336 }
337
338 func disassociateRanToE2THandlerImpl(data models.RanE2tMap) error {
339         xapp.Logger.Debug("Invoked disassociateRanToE2THandlerImpl")
340         err := validateE2TAddressRANListData(data)
341         if err != nil {
342                 xapp.Logger.Warn(" Disassociation of RAN List from E2T Instance data validation failed: " + err.Error())
343                 return err
344         }
345         xapp.Logger.Debug("received disassociate RANs from E2T instance")
346         m.Lock()
347         sdlEngine.WriteDisAssRANFromE2TInstance(xapp.Config.GetString("rtfile"), data)
348         m.Unlock()
349         return sendRoutesToAll()
350
351 }
352
353 func deleteE2tHandleHandlerImpl(data *models.E2tDeleteData) error {
354         xapp.Logger.Debug("Invoked deleteE2tHandleHandlerImpl")
355
356         err := validateDeleteE2tData(data)
357         if err != nil {
358                 xapp.Logger.Error(err.Error())
359                 return err
360         }
361         m.Lock()
362         sdlEngine.WriteDeleteE2TInstance(xapp.Config.GetString("rtfile"), data)
363         m.Unlock()
364         return sendRoutesToAll()
365
366 }
367
368 func dumpDebugData() (models.Debuginfo, error) {
369         var response models.Debuginfo
370         sdlEngine, _ := sdl.GetSdl("file")
371         rpeEngine, _ := rpe.GetRpe("rmrpush")
372         data, err := sdlEngine.ReadAll(xapp.Config.GetString("rtfile"))
373         if err != nil || data == nil {
374                 xapp.Logger.Error("Cannot get data from sdl interface due to: " + err.Error())
375                 return response, err
376         }
377         response.RouteTable = *rpeEngine.GeneratePolicies(rtmgr.Eps, data)
378
379         prettyJSON, err := json.MarshalIndent(data, "", "")
380         response.RouteConfigs = string(prettyJSON)
381
382         return response, err
383 }
384
385 func launchRest(nbiif *string){
386         swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
387         if err != nil {
388                 //log.Fatalln(err)
389                 xapp.Logger.Error(err.Error())
390                 os.Exit(1)
391         }
392         nbiUrl, err := url.Parse(*nbiif)
393         if err != nil {
394                 xapp.Logger.Error(err.Error())
395                 os.Exit(1)
396         }
397         api := operations.NewRoutingManagerAPI(swaggerSpec)
398         server := restapi.NewServer(api)
399         defer server.Shutdown()
400
401         server.Port, err = strconv.Atoi(nbiUrl.Port())
402         if err != nil {
403                 xapp.Logger.Error("Invalid NBI RestAPI port")
404                 os.Exit(1)
405         }
406         server.Host = "0.0.0.0"
407         // set handlers
408         api.HandleProvideXappHandleHandler = handle.ProvideXappHandleHandlerFunc(
409                 func(params handle.ProvideXappHandleParams) middleware.Responder {
410                         xapp.Logger.Info("Data received on Http interface")
411                         err := provideXappHandleHandlerImpl(params.XappCallbackData)
412                         if err != nil {
413                                 xapp.Logger.Error("Invalid XApp callback data: " + err.Error())
414                                 return handle.NewProvideXappHandleBadRequest()
415                         } else {
416                                 return handle.NewGetHandlesOK()
417                         }
418                 })
419         api.HandleProvideXappSubscriptionHandleHandler = handle.ProvideXappSubscriptionHandleHandlerFunc(
420                 func(params handle.ProvideXappSubscriptionHandleParams) middleware.Responder {
421                         err := provideXappSubscriptionHandleImpl(params.XappSubscriptionData)
422                         if err != nil {
423                                 return handle.NewProvideXappSubscriptionHandleBadRequest()
424                         } else {
425                                 return handle.NewGetHandlesOK()
426                         }
427                 })
428         api.HandleDeleteXappSubscriptionHandleHandler = handle.DeleteXappSubscriptionHandleHandlerFunc(
429                 func(params handle.DeleteXappSubscriptionHandleParams) middleware.Responder {
430                         err := deleteXappSubscriptionHandleImpl(params.XappSubscriptionData)
431                         if err != nil {
432                                 return handle.NewDeleteXappSubscriptionHandleNoContent()
433                         } else {
434                                 return handle.NewGetHandlesOK()
435                         }
436                 })
437         api.HandleUpdateXappSubscriptionHandleHandler = handle.UpdateXappSubscriptionHandleHandlerFunc(
438                 func(params handle.UpdateXappSubscriptionHandleParams) middleware.Responder {
439                         err := updateXappSubscriptionHandleImpl(&params.XappList, params.SubscriptionID)
440                         if err != nil {
441                                 return handle.NewUpdateXappSubscriptionHandleBadRequest()
442                         } else {
443                                 return handle.NewUpdateXappSubscriptionHandleCreated()
444                         }
445                 })
446         api.HandleCreateNewE2tHandleHandler = handle.CreateNewE2tHandleHandlerFunc(
447                 func(params handle.CreateNewE2tHandleParams) middleware.Responder {
448                         err := createNewE2tHandleHandlerImpl(params.E2tData)
449                         if err != nil {
450                                 return handle.NewCreateNewE2tHandleBadRequest()
451                         } else {
452                                 return handle.NewCreateNewE2tHandleCreated()
453                         }
454                 })
455
456         api.HandleAssociateRanToE2tHandleHandler = handle.AssociateRanToE2tHandleHandlerFunc(
457                 func(params handle.AssociateRanToE2tHandleParams) middleware.Responder {
458                         err := associateRanToE2THandlerImpl(params.RanE2tList)
459                         if err != nil {
460                                 return handle.NewAssociateRanToE2tHandleBadRequest()
461                         } else {
462                                 return handle.NewAssociateRanToE2tHandleCreated()
463                         }
464                 })
465
466         api.HandleDissociateRanHandler = handle.DissociateRanHandlerFunc(
467                 func(params handle.DissociateRanParams) middleware.Responder {
468                         err := disassociateRanToE2THandlerImpl(params.DissociateList)
469                         if err != nil {
470                                 return handle.NewDissociateRanBadRequest()
471                         } else {
472                                 return handle.NewDissociateRanCreated()
473                         }
474                 })
475
476         api.HandleDeleteE2tHandleHandler = handle.DeleteE2tHandleHandlerFunc(
477                 func(params handle.DeleteE2tHandleParams) middleware.Responder {
478                         err := deleteE2tHandleHandlerImpl(params.E2tData)
479                         if err != nil {
480                                 return handle.NewDeleteE2tHandleBadRequest()
481                         } else {
482                                 return handle.NewDeleteE2tHandleCreated()
483                         }
484                 })
485         api.DebugGetDebuginfoHandler = debug.GetDebuginfoHandlerFunc(
486                 func(params debug.GetDebuginfoParams) middleware.Responder {
487                         response, err := dumpDebugData()
488                         if err != nil {
489                                 return debug.NewGetDebuginfoCreated()
490                         } else {
491                                 return debug.NewGetDebuginfoOK().WithPayload(&response)
492                         }
493                 })
494         api.HandleAddRmrRouteHandler = handle.AddRmrRouteHandlerFunc(
495                 func(params handle.AddRmrRouteParams) middleware.Responder {
496                         err := adddelrmrroute(params.RoutesList,true)
497                         if err != nil {
498                                 return handle.NewAddRmrRouteBadRequest()
499                         } else {
500                                 return handle.NewAddRmrRouteCreated()
501                         }
502
503                 })
504         api.HandleDelRmrRouteHandler = handle.DelRmrRouteHandlerFunc(
505                 func(params handle.DelRmrRouteParams) middleware.Responder {
506                         err := adddelrmrroute(params.RoutesList,false)
507                         if err != nil {
508                                 return handle.NewDelRmrRouteBadRequest()
509                         } else {
510                                 return handle.NewDelRmrRouteCreated()
511                         }
512                 })
513
514         // start to serve API
515         xapp.Logger.Info("Starting the HTTP Rest service")
516         if err := server.Serve(); err != nil {
517                 xapp.Logger.Error(err.Error())
518         }
519 }
520
521 func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
522         xapp.Logger.Info("Invoked httprestful.httpGetXApps: " + xmurl)
523         r, err := myClient.Get(xmurl)
524         if err != nil {
525                 return nil, err
526         }
527         defer r.Body.Close()
528
529         if r.StatusCode == 200 {
530                 xapp.Logger.Debug("http client raw response: %v", r)
531                 var xapps []rtmgr.XApp
532                 err = json.NewDecoder(r.Body).Decode(&xapps)
533                 if err != nil {
534                         xapp.Logger.Warn("Json decode failed: " + err.Error())
535                 }
536                 xapp.Logger.Info("HTTP GET: OK")
537                 xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", xapps)
538                 return &xapps, err
539         }
540         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
541         return nil, nil
542 }
543
544 func httpGetE2TList(e2murl string) (*[]rtmgr.E2tIdentity, error) {
545         xapp.Logger.Info("Invoked httprestful.httpGetE2TList: " + e2murl)
546         r, err := myClient.Get(e2murl)
547         if err != nil {
548                 return nil, err
549         }
550         defer r.Body.Close()
551
552         if r.StatusCode == 200 {
553                 xapp.Logger.Debug("http client raw response: %v", r)
554                 var E2Tlist []rtmgr.E2tIdentity
555                 err = json.NewDecoder(r.Body).Decode(&E2Tlist)
556                 if err != nil {
557                         xapp.Logger.Warn("Json decode failed: " + err.Error())
558                 }
559                 xapp.Logger.Info("HTTP GET: OK")
560                 xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", E2Tlist)
561                 return &E2Tlist, err
562         }
563         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
564         return nil, nil
565 }
566
567 func PopulateE2TMap(e2tDataList *[]rtmgr.E2tIdentity, e2ts map[string]rtmgr.E2TInstance, meids []string) {
568         xapp.Logger.Info("Invoked httprestful.PopulateE2TMap ")
569
570         for _, e2tData := range *e2tDataList {
571                 var str string
572
573                 e2tinst := rtmgr.E2TInstance{
574                         Ranlist: make([]string, len(e2tData.Rannames)),
575                 }
576
577                 e2tinst.Fqdn = e2tData.E2taddress
578                 e2tinst.Name = "E2TERMINST"
579                 copy(e2tinst.Ranlist, e2tData.Rannames)
580
581                 if len(e2tData.Rannames) > 0 {
582                         var meidar string
583                         for _, meid := range e2tData.Rannames {
584                                 meidar += meid + " "
585                         }
586                         str += "mme_ar|" + e2tData.E2taddress + "|" + strings.TrimSuffix(meidar, " ")
587                 }
588
589                 e2ts[e2tinst.Fqdn] = e2tinst
590                 meids = append(meids, str)
591         }
592 }
593
594 func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile string, e2murl string, sdlEngine sdl.Engine) error {
595         xapp.Logger.Info("Invoked retrieveStartupData ")
596         var readErr error
597         var err error
598         var maxRetries = 10
599         var xappData *[]rtmgr.XApp
600         xappData = new([]rtmgr.XApp)
601         xapp.Logger.Info("Trying to fetch XApps data from XAPP manager")
602         for i := 1; i <= maxRetries; i++ {
603                 time.Sleep(2 * time.Second)
604
605                 readErr = nil
606                 xappData, err = httpGetXApps(xmurl)
607                 if xappData != nil && err == nil {
608                         break
609                 } else if err == nil {
610                         readErr = errors.New("unexpected HTTP status code")
611                 } else {
612                         xapp.Logger.Warn("cannot get xapp data due to: " + err.Error())
613                         readErr = err
614                 }
615         }
616
617         if readErr != nil {
618                 return readErr
619         }
620
621         var meids []string
622         e2ts := make(map[string]rtmgr.E2TInstance)
623         xapp.Logger.Info("Trying to fetch E2T data from E2manager")
624         for i := 1; i <= maxRetries; i++ {
625
626                 readErr = nil
627                 e2tDataList, err := httpGetE2TList(e2murl)
628                 if e2tDataList != nil && err == nil {
629                         PopulateE2TMap(e2tDataList, e2ts, meids[:])
630                         break
631                 } else if err == nil {
632                         readErr = errors.New("unexpected HTTP status code")
633                 } else {
634                         xapp.Logger.Warn("cannot get E2T data from E2M due to: " + err.Error())
635                         readErr = err
636                 }
637                 time.Sleep(2 * time.Second)
638         }
639
640         if readErr != nil {
641                 return readErr
642         }
643
644         pcData, confErr := rtmgr.GetPlatformComponents(configfile)
645         if confErr != nil {
646                 xapp.Logger.Error(confErr.Error())
647                 return confErr
648         }
649         xapp.Logger.Info("Recieved intial xapp data, E2T data and platform data, writing into SDL.")
650         // Combine the xapps data and platform data before writing to the SDL
651         ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData, E2Ts: e2ts, MeidMap: meids}
652         writeErr := sdlEngine.WriteAll(fileName, ricData)
653         if writeErr != nil {
654                 xapp.Logger.Error(writeErr.Error())
655         }
656
657         xapp.Logger.Info("Trying to fetch Subscriptions data from Subscription manager")
658         for i := 1; i <= maxRetries; i++ {
659                         readErr = nil
660                         sub_list, err := xapp.Subscription.QuerySubscriptions()
661
662                         if sub_list != nil && err == nil {
663                                 PopulateSubscription(sub_list)
664                                 break
665                         } else {
666                                 readErr = err
667                                 xapp.Logger.Warn("cannot get xapp data due to: " + readErr.Error())
668                 }
669                         time.Sleep(2 * time.Second)
670                 }
671
672         if readErr != nil {
673                 return readErr
674         }
675
676         // post subscription req to appmgr
677         readErr = PostSubReq(xmurl, nbiif)
678         if readErr != nil {
679                 return readErr
680         }
681
682         //rlist := make(map[string]string)
683         xapp.Logger.Info("Reading SDL for any routes")
684         rlist,sdlerr := xapp.Sdl.Read("routes")
685         readErr = sdlerr
686         if readErr == nil {
687                 xapp.Logger.Info("Value is %s",rlist["routes"])
688                 if rlist["routes"] != nil {
689                         formstring := fmt.Sprintf("%s",rlist["routes"])
690                         xapp.Logger.Info("Value of formed string = %s",formstring)
691                         newstring := strings.Split(formstring," ")
692                         for i,_ := range newstring {
693                                 xapp.Logger.Info("in Loop Value of formed string = %s",newstring)
694                                 rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList,newstring[i])
695                         }
696                 }
697
698                 return nil
699         }
700
701         return readErr
702 }
703
704 func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string, e2murl string,
705         sdlEngine sdl.Engine, rpeEngine rpe.Engine, m *sync.Mutex) error {
706         err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, e2murl, sdlEngine)
707         if err != nil {
708                 xapp.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
709                 return err
710         }
711         go func() {
712                 r.LaunchRest(&nbiif)
713         }()
714
715         return nil
716 }
717
718 func (r *HttpRestful) Terminate() error {
719         return nil
720 }
721
722 func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
723         xapp.Logger.Debug("Adding the subscription into the subscriptions list")
724         var b = false
725         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
726         for _, elem := range *subs {
727                 if elem == sub {
728                         xapp.Logger.Warn("rtmgr.addSubscription: Subscription already present: %v", elem)
729                         b = true
730                 }
731         }
732         if b == false {
733                 *subs = append(*subs, sub)
734         }
735         return b
736 }
737
738 func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
739         xapp.Logger.Debug("Deleteing the subscription from the subscriptions list")
740         var present = false
741         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
742         for i, elem := range *subs {
743                 if elem == sub {
744                         present = true
745                         // Since the order of the list is not important, we are swapping the last element
746                         // with the matching element and replacing the list with list(n-1) elements.
747                         (*subs)[len(*subs)-1], (*subs)[i] = (*subs)[i], (*subs)[len(*subs)-1]
748                         *subs = (*subs)[:len(*subs)-1]
749                         break
750                 }
751         }
752         if present == false {
753                 xapp.Logger.Warn("rtmgr.delSubscription: Subscription = %v, not present in the existing subscriptions", xappSubData)
754         }
755         return present
756 }
757
758 func updateSubscription(data *rtmgr.XappList) {
759
760         var subdata models.XappSubscriptionData
761         var id int32
762         var matchingsubid, deletecount uint8
763         id = int32(data.SubscriptionID)
764         subdata.SubscriptionID = &id
765         for _, subs := range rtmgr.Subs {
766                 if int32(data.SubscriptionID) == subs.SubID {
767                         matchingsubid++
768                 }
769         }
770
771         for deletecount < matchingsubid {
772                 for _, subs := range rtmgr.Subs {
773                         if int32(data.SubscriptionID) == subs.SubID {
774                                 subdata.SubscriptionID = &subs.SubID
775                                 subdata.Address = &subs.Fqdn
776                                 subdata.Port = &subs.Port
777                                 xapp.Logger.Debug("Deletion Subscription List has %v", subdata)
778                                 delSubscription(&rtmgr.Subs, &subdata)
779                                 break
780                         }
781                 }
782                 deletecount++
783         }
784
785         for _, items := range data.FqdnList {
786                 subdata.Address = items.Address
787                 subdata.Port = items.Port
788                 xapp.Logger.Debug("Adding Subscription List has %v", subdata)
789                 addSubscription(&rtmgr.Subs, &subdata)
790         }
791
792 }
793
794 func PopulateSubscription(sub_list xfmodel.SubscriptionList) {
795         for _, sub_row := range sub_list {
796                 var subdata models.XappSubscriptionData
797                 id := int32(sub_row.SubscriptionID)
798                 subdata.SubscriptionID = &id
799                 for _, ep := range sub_row.Endpoint {
800
801                         stringSlice := strings.Split(ep, ":")
802                         subdata.Address = &stringSlice[0]
803                         intportval, _ := strconv.Atoi(stringSlice[1])
804                         value := uint16(intportval)
805                         subdata.Port = &value
806                         xapp.Logger.Debug("Adding Subscription List has Address :%v, port :%v, SubscriptionID :%v ", subdata.Address, subdata.Address, subdata.SubscriptionID)
807                         addSubscription(&rtmgr.Subs, &subdata)
808                 }
809         }
810 }
811
812 func adddelrmrroute(routelist models.Routelist,rtflag bool) error {
813         xapp.Logger.Info("Updating rmrroute with Route list: %v,flag: %v", routelist,rtflag)
814         for _, rlist := range routelist {
815                 var  subid int32
816                 var data string
817                 if rlist.SubscriptionID == 0 {
818                         subid = -1
819                 } else {
820                         subid = rlist.SubscriptionID
821                 }
822                 if rlist.SenderEndPoint == "" && rlist.SubscriptionID != 0 {
823                         data = fmt.Sprintf("mse|%d|%d|%s\n",*rlist.MessageType,rlist.SubscriptionID,*rlist.TargetEndPoint)
824                 } else if rlist.SenderEndPoint == "" && rlist.SubscriptionID == 0 {
825                         data = fmt.Sprintf("mse|%d|-1|%s\n",*rlist.MessageType,*rlist.TargetEndPoint)
826                 } else {
827                         data = fmt.Sprintf("mse|%d,%s|%d|%s\n",*rlist.MessageType,rlist.SenderEndPoint,subid,*rlist.TargetEndPoint)
828                 }
829                 err := checkrepeatedroute(data)
830
831                 if rtflag == true {
832                         if err == true {
833                                 xapp.Logger.Info("Given route %s is a duplicate",data)
834                         }
835                         rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList,data)
836                         routearray := strings.Join(rtmgr.DynamicRouteList," ")
837                         xapp.Sdl.Store("routes",routearray)
838                 } else {
839                         if err == true {
840                                 xapp.Logger.Info("Successfully deleted route: %s",data)
841                                 routearray := strings.Join(rtmgr.DynamicRouteList," ")
842                                 xapp.Sdl.Store("routes",routearray)
843                         }else {
844                                 xapp.Logger.Info("No such route: %s",data)
845                                 return errors.New("No such route: " + data)
846                         }
847
848                 }
849         }
850         return sendRoutesToAll()
851 }
852
853 func checkrepeatedroute (data string) bool {
854         for i:=0;i<len(rtmgr.DynamicRouteList);i++ {
855                 if rtmgr.DynamicRouteList[i] == data {
856                         rtmgr.DynamicRouteList[i] = rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1]
857                         rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1] = ""
858                         rtmgr.DynamicRouteList = rtmgr.DynamicRouteList[:len(rtmgr.DynamicRouteList)-1]
859                         return true
860                 }
861         }
862         return false
863 }