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