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