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