Upgraded to RMR 4.7.4 and some improvements
[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 launchRest(nbiif *string) {
416         swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
417         if err != nil {
418                 //log.Fatalln(err)
419                 xapp.Logger.Error(err.Error())
420                 os.Exit(1)
421         }
422         nbiUrl, err := url.Parse(*nbiif)
423         if err != nil {
424                 xapp.Logger.Error(err.Error())
425                 os.Exit(1)
426         }
427         api := operations.NewRoutingManagerAPI(swaggerSpec)
428         server := restapi.NewServer(api)
429         defer server.Shutdown()
430
431         server.Port, err = strconv.Atoi(nbiUrl.Port())
432         if err != nil {
433                 xapp.Logger.Error("Invalid NBI RestAPI port")
434                 os.Exit(1)
435         }
436         server.Host = "0.0.0.0"
437         // set handlers
438         api.HandleProvideXappHandleHandler = handle.ProvideXappHandleHandlerFunc(
439                 func(params handle.ProvideXappHandleParams) middleware.Responder {
440                         xapp.Logger.Info("Data received on Http interface")
441                         err := provideXappHandleHandlerImpl(params.XappCallbackData)
442                         if err != nil {
443                                 xapp.Logger.Error("RoutingManager->AppManager request Failed: " + err.Error())
444                                 return handle.NewProvideXappHandleBadRequest()
445                         } else {
446                                 xapp.Logger.Info("RoutingManager->AppManager request Success")
447                                 return handle.NewGetHandlesOK()
448                         }
449                 })
450         api.HandleProvideXappSubscriptionHandleHandler = handle.ProvideXappSubscriptionHandleHandlerFunc(
451                 func(params handle.ProvideXappSubscriptionHandleParams) middleware.Responder {
452                         err := provideXappSubscriptionHandleImpl(params.XappSubscriptionData)
453                         if err != nil {
454                                 xapp.Logger.Error("RoutingManager->SubManager Add Request Failed: " + err.Error())
455                                 return handle.NewProvideXappSubscriptionHandleBadRequest()
456                         } else {
457                                 xapp.Logger.Info("RoutingManager->SubManager Add Request Success, subid = %v, requestor = %v", *params.XappSubscriptionData.SubscriptionID, *params.XappSubscriptionData.Address)
458                                 return handle.NewGetHandlesOK()
459                         }
460                 })
461         api.HandleDeleteXappSubscriptionHandleHandler = handle.DeleteXappSubscriptionHandleHandlerFunc(
462                 func(params handle.DeleteXappSubscriptionHandleParams) middleware.Responder {
463                         err := deleteXappSubscriptionHandleImpl(params.XappSubscriptionData)
464                         if err != nil {
465                                 xapp.Logger.Error("RoutingManager->SubManager Delete Request Failed: " + err.Error())
466                                 return handle.NewDeleteXappSubscriptionHandleNoContent()
467                         } else {
468                                 xapp.Logger.Info("RoutingManager->SubManager Delete Request Success, subid = %v, requestor = %v", *params.XappSubscriptionData.SubscriptionID, *params.XappSubscriptionData.Address)
469                                 return handle.NewGetHandlesOK()
470                         }
471                 })
472         api.HandleUpdateXappSubscriptionHandleHandler = handle.UpdateXappSubscriptionHandleHandlerFunc(
473                 func(params handle.UpdateXappSubscriptionHandleParams) middleware.Responder {
474                         err := updateXappSubscriptionHandleImpl(&params.XappList, params.SubscriptionID)
475                         if err != nil {
476                                 return handle.NewUpdateXappSubscriptionHandleBadRequest()
477                         } else {
478                                 return handle.NewUpdateXappSubscriptionHandleCreated()
479                         }
480                 })
481         api.HandleCreateNewE2tHandleHandler = handle.CreateNewE2tHandleHandlerFunc(
482                 func(params handle.CreateNewE2tHandleParams) middleware.Responder {
483                         err := createNewE2tHandleHandlerImpl(params.E2tData)
484                         if err != nil {
485                                 xapp.Logger.Error("RoutingManager->E2Manager AddE2T Request Failed: " + err.Error())
486                                 return handle.NewCreateNewE2tHandleBadRequest()
487                         } else {
488                                 xapp.Logger.Info("RoutingManager->E2Manager AddE2T Request Success, E2T = %v", *params.E2tData.E2TAddress)
489                                 return handle.NewCreateNewE2tHandleCreated()
490                         }
491                 })
492
493         api.HandleAssociateRanToE2tHandleHandler = handle.AssociateRanToE2tHandleHandlerFunc(
494                 func(params handle.AssociateRanToE2tHandleParams) middleware.Responder {
495                         err := associateRanToE2THandlerImpl(params.RanE2tList)
496                         if err != nil {
497                                 xapp.Logger.Error("RoutingManager->E2Manager associateRanToE2T Request Failed: " + err.Error())
498                                 return handle.NewAssociateRanToE2tHandleBadRequest()
499                         } else {
500                                 xapp.Logger.Info("RoutingManager->E2Manager associateRanToE2T Request Success, E2T = %v", params.RanE2tList)
501                                 return handle.NewAssociateRanToE2tHandleCreated()
502                         }
503                 })
504
505         api.HandleDissociateRanHandler = handle.DissociateRanHandlerFunc(
506                 func(params handle.DissociateRanParams) middleware.Responder {
507                         err := disassociateRanToE2THandlerImpl(params.DissociateList)
508                         if err != nil {
509                                 xapp.Logger.Error("RoutingManager->E2Manager DisassociateRanToE2T Request Failed: " + err.Error())
510                                 return handle.NewDissociateRanBadRequest()
511                         } else {
512                                 xapp.Logger.Info("RoutingManager->E2Manager DisassociateRanToE2T Request Success, E2T = %v", params.DissociateList)
513                                 return handle.NewDissociateRanCreated()
514                         }
515                 })
516
517         api.HandleDeleteE2tHandleHandler = handle.DeleteE2tHandleHandlerFunc(
518                 func(params handle.DeleteE2tHandleParams) middleware.Responder {
519                         err := deleteE2tHandleHandlerImpl(params.E2tData)
520                         if err != nil {
521                                 xapp.Logger.Error("RoutingManager->E2Manager DeleteE2T Request Failed: " + err.Error())
522                                 return handle.NewDeleteE2tHandleBadRequest()
523                         } else {
524                                 xapp.Logger.Info("RoutingManager->E2Manager DeleteE2T Request Success, E2T = %v", *params.E2tData.E2TAddress)
525                                 return handle.NewDeleteE2tHandleCreated()
526                         }
527                 })
528         api.DebugGetDebuginfoHandler = debug.GetDebuginfoHandlerFunc(
529                 func(params debug.GetDebuginfoParams) middleware.Responder {
530                         response, err := dumpDebugData()
531                         if err != nil {
532                                 return debug.NewGetDebuginfoCreated()
533                         } else {
534                                 return debug.NewGetDebuginfoOK().WithPayload(&response)
535                         }
536                 })
537         api.HandleAddRmrRouteHandler = handle.AddRmrRouteHandlerFunc(
538                 func(params handle.AddRmrRouteParams) middleware.Responder {
539                         err := adddelrmrroute(params.RoutesList, true)
540                         if err != nil {
541                                 return handle.NewAddRmrRouteBadRequest()
542                         } else {
543                                 return handle.NewAddRmrRouteCreated()
544                         }
545
546                 })
547         api.HandleDelRmrRouteHandler = handle.DelRmrRouteHandlerFunc(
548                 func(params handle.DelRmrRouteParams) middleware.Responder {
549                         err := adddelrmrroute(params.RoutesList, false)
550                         if err != nil {
551                                 return handle.NewDelRmrRouteBadRequest()
552                         } else {
553                                 return handle.NewDelRmrRouteCreated()
554                         }
555                 })
556
557         // start to serve API
558         xapp.Logger.Info("Starting the HTTP Rest service")
559         if err := server.Serve(); err != nil {
560                 xapp.Logger.Error(err.Error())
561         }
562 }
563
564 func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
565         xapp.Logger.Info("Invoked httprestful.httpGetXApps: " + xmurl)
566         r, err := myClient.Get(xmurl)
567         if err != nil {
568                 return nil, err
569         }
570         defer r.Body.Close()
571
572         if r.StatusCode == 200 {
573                 xapp.Logger.Debug("http client raw response: %v", r)
574                 var xapps []rtmgr.XApp
575                 err = json.NewDecoder(r.Body).Decode(&xapps)
576                 if err != nil {
577                         xapp.Logger.Warn("Json decode failed: " + err.Error())
578                 }
579                 xapp.Logger.Info("HTTP GET: OK")
580                 xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", xapps)
581                 return &xapps, err
582         }
583         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
584         return nil, nil
585 }
586
587 func httpGetE2TList(e2murl string) (*[]rtmgr.E2tIdentity, error) {
588         xapp.Logger.Info("Invoked httprestful.httpGetE2TList: " + e2murl)
589         r, err := myClient.Get(e2murl)
590         if err != nil {
591                 return nil, err
592         }
593         defer r.Body.Close()
594
595         if r.StatusCode == 200 {
596                 xapp.Logger.Debug("http client raw response: %v", r)
597                 var E2Tlist []rtmgr.E2tIdentity
598                 err = json.NewDecoder(r.Body).Decode(&E2Tlist)
599                 if err != nil {
600                         xapp.Logger.Warn("Json decode failed: " + err.Error())
601                 }
602                 xapp.Logger.Info("HTTP GET: OK")
603                 xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", E2Tlist)
604                 return &E2Tlist, err
605         }
606         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
607         return nil, nil
608 }
609
610 func PopulateE2TMap(e2tDataList *[]rtmgr.E2tIdentity, e2ts map[string]rtmgr.E2TInstance, meids []string) {
611         xapp.Logger.Info("Invoked httprestful.PopulateE2TMap ")
612
613         for _, e2tData := range *e2tDataList {
614                 var str string
615
616                 e2tinst := rtmgr.E2TInstance{
617                         Ranlist: make([]string, len(e2tData.Rannames)),
618                 }
619
620                 e2tinst.Fqdn = e2tData.E2taddress
621                 e2tinst.Name = "E2TERMINST"
622                 copy(e2tinst.Ranlist, e2tData.Rannames)
623
624                 if len(e2tData.Rannames) > 0 {
625                         var meidar string
626                         for _, meid := range e2tData.Rannames {
627                                 meidar += meid + " "
628                         }
629                         str += "mme_ar|" + e2tData.E2taddress + "|" + strings.TrimSuffix(meidar, " ")
630                 }
631
632                 e2ts[e2tinst.Fqdn] = e2tinst
633                 meids = append(meids, str)
634         }
635 }
636
637 func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile string, e2murl string, sdlEngine sdl.Engine) error {
638         xapp.Logger.Info("Invoked retrieveStartupData ")
639         var readErr error
640         var err error
641         var maxRetries = 10
642         var xappData *[]rtmgr.XApp
643         xappData = new([]rtmgr.XApp)
644         xapp.Logger.Info("Trying to fetch XApps data from XAPP manager")
645         for i := 1; i <= maxRetries; i++ {
646                 time.Sleep(2 * time.Second)
647
648                 readErr = nil
649                 xappData, err = httpGetXApps(xmurl)
650                 if xappData != nil && err == nil {
651                         break
652                 } else if err == nil {
653                         readErr = errors.New("unexpected HTTP status code")
654                 } else {
655                         xapp.Logger.Warn("cannot get xapp data due to: " + err.Error())
656                         readErr = err
657                 }
658         }
659
660         if readErr != nil {
661                 return readErr
662         }
663
664         var meids []string
665         e2ts := make(map[string]rtmgr.E2TInstance)
666         xapp.Logger.Info("Trying to fetch E2T data from E2manager")
667         for i := 1; i <= maxRetries; i++ {
668
669                 readErr = nil
670                 e2tDataList, err := httpGetE2TList(e2murl)
671                 if e2tDataList != nil && err == nil {
672                         PopulateE2TMap(e2tDataList, e2ts, meids[:])
673                         break
674                 } else if err == nil {
675                         readErr = errors.New("unexpected HTTP status code")
676                 } else {
677                         xapp.Logger.Warn("cannot get E2T data from E2M due to: " + err.Error())
678                         readErr = err
679                 }
680                 time.Sleep(2 * time.Second)
681         }
682
683         if readErr != nil {
684                 return readErr
685         }
686
687         pcData, confErr := rtmgr.GetPlatformComponents(configfile)
688         if confErr != nil {
689                 xapp.Logger.Error(confErr.Error())
690                 return confErr
691         }
692         xapp.Logger.Info("Recieved intial xapp data, E2T data and platform data, writing into SDL.")
693         // Combine the xapps data and platform data before writing to the SDL
694         ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData, E2Ts: e2ts, MeidMap: meids}
695         writeErr := sdlEngine.WriteAll(fileName, ricData)
696         if writeErr != nil {
697                 xapp.Logger.Error(writeErr.Error())
698         }
699
700         xapp.Logger.Info("Trying to fetch Subscriptions data from Subscription manager")
701         for i := 1; i <= maxRetries; i++ {
702                 readErr = nil
703                 sub_list, err := xapp.Subscription.QuerySubscriptions()
704
705                 if sub_list != nil && err == nil {
706                         PopulateSubscription(sub_list)
707                         break
708                 } else {
709                         readErr = err
710                         xapp.Logger.Warn("cannot get xapp data due to: " + readErr.Error())
711                 }
712                 time.Sleep(2 * time.Second)
713         }
714
715         if readErr != nil {
716                 return readErr
717         }
718
719         // post subscription req to appmgr
720         readErr = PostSubReq(xmurl, nbiif)
721         if readErr != nil {
722                 return readErr
723         }
724
725         //rlist := make(map[string]string)
726         xapp.Logger.Info("Reading SDL for any routes")
727         rlist, sdlerr := xapp.Sdl.Read("routes")
728         readErr = sdlerr
729         if readErr == nil {
730                 xapp.Logger.Info("Value is %s", rlist["routes"])
731                 if rlist["routes"] != nil {
732                         formstring := fmt.Sprintf("%s", rlist["routes"])
733                         xapp.Logger.Info("Value of formed string = %s", formstring)
734                         newstring := strings.Split(formstring, " ")
735                         for i, _ := range newstring {
736                                 xapp.Logger.Info("in Loop Value of formed string = %s", newstring)
737                                 rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, newstring[i])
738                         }
739                 }
740
741                 return nil
742         }
743
744         return readErr
745 }
746
747 func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string, e2murl string,
748         sdlEngine sdl.Engine, rpeEngine rpe.Engine, m *sync.Mutex) error {
749         err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, e2murl, sdlEngine)
750         if err != nil {
751                 xapp.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
752                 return err
753         }
754         go func() {
755                 r.LaunchRest(&nbiif)
756         }()
757
758         return nil
759 }
760
761 func (r *HttpRestful) Terminate() error {
762         return nil
763 }
764
765 func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
766         xapp.Logger.Debug("Adding the subscription into the subscriptions list")
767         var b = false
768         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
769         for _, elem := range *subs {
770                 if elem == sub {
771                         xapp.Logger.Warn("rtmgr.addSubscription: Subscription already present: %v", elem)
772                         b = true
773                 }
774         }
775         if b == false {
776                 *subs = append(*subs, sub)
777         }
778         return b
779 }
780
781 func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
782         xapp.Logger.Debug("Deleteing the subscription from the subscriptions list")
783         var present = false
784         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
785         for i, elem := range *subs {
786                 if elem == sub {
787                         present = true
788                         // Since the order of the list is not important, we are swapping the last element
789                         // with the matching element and replacing the list with list(n-1) elements.
790                         (*subs)[len(*subs)-1], (*subs)[i] = (*subs)[i], (*subs)[len(*subs)-1]
791                         *subs = (*subs)[:len(*subs)-1]
792                         break
793                 }
794         }
795         if present == false {
796                 xapp.Logger.Warn("rtmgr.delSubscription: Subscription = %v, not present in the existing subscriptions", xappSubData)
797         }
798         return present
799 }
800
801 func updateSubscription(data *rtmgr.XappList) {
802
803         var subdata models.XappSubscriptionData
804         var id int32
805         var matchingsubid, deletecount uint8
806         id = int32(data.SubscriptionID)
807         subdata.SubscriptionID = &id
808         for _, subs := range rtmgr.Subs {
809                 if int32(data.SubscriptionID) == subs.SubID {
810                         matchingsubid++
811                 }
812         }
813
814         for deletecount < matchingsubid {
815                 for _, subs := range rtmgr.Subs {
816                         if int32(data.SubscriptionID) == subs.SubID {
817                                 subdata.SubscriptionID = &subs.SubID
818                                 subdata.Address = &subs.Fqdn
819                                 subdata.Port = &subs.Port
820                                 xapp.Logger.Debug("Deletion Subscription List has %v", subdata)
821                                 delSubscription(&rtmgr.Subs, &subdata)
822                                 break
823                         }
824                 }
825                 deletecount++
826         }
827
828         for _, items := range data.FqdnList {
829                 subdata.Address = items.Address
830                 subdata.Port = items.Port
831                 xapp.Logger.Debug("Adding Subscription List has %v", subdata)
832                 addSubscription(&rtmgr.Subs, &subdata)
833         }
834
835 }
836
837 func PopulateSubscription(sub_list xfmodel.SubscriptionList) {
838         for _, sub_row := range sub_list {
839                 var subdata models.XappSubscriptionData
840                 id := int32(sub_row.SubscriptionID)
841                 subdata.SubscriptionID = &id
842                 for _, ep := range sub_row.Endpoint {
843
844                         stringSlice := strings.Split(ep, ":")
845                         subdata.Address = &stringSlice[0]
846                         intportval, _ := strconv.Atoi(stringSlice[1])
847                         value := uint16(intportval)
848                         subdata.Port = &value
849                         xapp.Logger.Debug("Adding Subscription List has Address :%v, port :%v, SubscriptionID :%v ", subdata.Address, subdata.Address, subdata.SubscriptionID)
850                         addSubscription(&rtmgr.Subs, &subdata)
851                 }
852         }
853 }
854
855 func adddelrmrroute(routelist models.Routelist, rtflag bool) error {
856         xapp.Logger.Info("Updating rmrroute with Route list: %v,flag: %v", routelist, rtflag)
857         for _, rlist := range routelist {
858                 var subid int32
859                 var data string
860                 if rlist.SubscriptionID == 0 {
861                         subid = -1
862                 } else {
863                         subid = rlist.SubscriptionID
864                 }
865                 if rlist.SenderEndPoint == "" && rlist.SubscriptionID != 0 {
866                         data = fmt.Sprintf("mse|%d|%d|%s\n", *rlist.MessageType, rlist.SubscriptionID, *rlist.TargetEndPoint)
867                 } else if rlist.SenderEndPoint == "" && rlist.SubscriptionID == 0 {
868                         data = fmt.Sprintf("mse|%d|-1|%s\n", *rlist.MessageType, *rlist.TargetEndPoint)
869                 } else {
870                         data = fmt.Sprintf("mse|%d,%s|%d|%s\n", *rlist.MessageType, rlist.SenderEndPoint, subid, *rlist.TargetEndPoint)
871                 }
872                 err := checkrepeatedroute(data)
873
874                 if rtflag == true {
875                         if err == true {
876                                 xapp.Logger.Info("Given route %s is a duplicate", data)
877                         }
878                         rtmgr.DynamicRouteList = append(rtmgr.DynamicRouteList, data)
879                         routearray := strings.Join(rtmgr.DynamicRouteList, " ")
880                         xapp.Sdl.Store("routes", routearray)
881                 } else {
882                         if err == true {
883                                 xapp.Logger.Info("Successfully deleted route: %s", data)
884                                 routearray := strings.Join(rtmgr.DynamicRouteList, " ")
885                                 xapp.Sdl.Store("routes", routearray)
886                         } else {
887                                 xapp.Logger.Info("No such route: %s", data)
888                                 return errors.New("No such route: " + data)
889                         }
890
891                 }
892         }
893         updateEp()
894         return sendRoutesToAll()
895 }
896
897 func checkrepeatedroute(data string) bool {
898         for i := 0; i < len(rtmgr.DynamicRouteList); i++ {
899                 if rtmgr.DynamicRouteList[i] == data {
900                         rtmgr.DynamicRouteList[i] = rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1]
901                         rtmgr.DynamicRouteList[len(rtmgr.DynamicRouteList)-1] = ""
902                         rtmgr.DynamicRouteList = rtmgr.DynamicRouteList[:len(rtmgr.DynamicRouteList)-1]
903                         return true
904                 }
905         }
906         return false
907 }