Added debug API to request route and configuration details in routing manager
[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         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
39         "github.com/go-openapi/loads"
40         "github.com/go-openapi/runtime/middleware"
41         "net"
42         "net/url"
43         "os"
44         "routing-manager/pkg/models"
45         "routing-manager/pkg/restapi"
46         "routing-manager/pkg/restapi/operations"
47         "routing-manager/pkg/restapi/operations/debug"
48         "routing-manager/pkg/restapi/operations/handle"
49         "routing-manager/pkg/rpe"
50         "routing-manager/pkg/rtmgr"
51         "routing-manager/pkg/sdl"
52         "strconv"
53         "strings"
54         "sync"
55         "time"
56 )
57
58 //var myClient = &http.Client{Timeout: 1 * time.Second}
59
60 type HttpRestful struct {
61         Engine
62         LaunchRest                   LaunchRestHandler
63         RecvXappCallbackData         RecvXappCallbackDataHandler
64         RecvNewE2Tdata               RecvNewE2TdataHandler
65         ProvideXappHandleHandlerImpl ProvideXappHandleHandlerImpl
66         RetrieveStartupData          RetrieveStartupDataHandler
67 }
68
69 func NewHttpRestful() *HttpRestful {
70         instance := new(HttpRestful)
71         instance.LaunchRest = launchRest
72         instance.RecvXappCallbackData = recvXappCallbackData
73         instance.RecvNewE2Tdata = recvNewE2Tdata
74         instance.ProvideXappHandleHandlerImpl = provideXappHandleHandlerImpl
75         instance.RetrieveStartupData = retrieveStartupData
76         return instance
77 }
78
79 // ToDo: Use Range over channel. Read and return only the latest one.
80 func recvXappCallbackData(dataChannel <-chan *models.XappCallbackData) (*[]rtmgr.XApp, error) {
81         var xappData *models.XappCallbackData
82         // Drain the channel as we are only looking for the latest value until
83         // xapp manager sends all xapp data with every request.
84         length := len(dataChannel)
85         //xapp.Logger.Info(length)
86         for i := 0; i <= length; i++ {
87                 xapp.Logger.Info("data received")
88                 // If no data received from the REST, it blocks.
89                 xappData = <-dataChannel
90         }
91         if nil != xappData {
92                 var xapps []rtmgr.XApp
93                 err := json.Unmarshal([]byte(xappData.XApps), &xapps)
94                 return &xapps, err
95         } else {
96                 xapp.Logger.Info("No data")
97         }
98
99         xapp.Logger.Debug("Nothing received on the Http interface")
100         return nil, nil
101 }
102
103 func recvNewE2Tdata(dataChannel <-chan *models.E2tData) (*rtmgr.E2TInstance, string, error) {
104         var e2tData *models.E2tData
105         var str string
106         xapp.Logger.Info("data received")
107
108         e2tData = <-dataChannel
109
110         if nil != e2tData {
111
112                 e2tinst := rtmgr.E2TInstance{
113                         Ranlist: make([]string, len(e2tData.RanNamelist)),
114                 }
115
116                 e2tinst.Fqdn = *e2tData.E2TAddress
117                 e2tinst.Name = "E2TERMINST"
118                 copy(e2tinst.Ranlist, e2tData.RanNamelist)
119                 if len(e2tData.RanNamelist) > 0 {
120                         var meidar string
121                         for _, meid := range e2tData.RanNamelist {
122                                 meidar += meid + " "
123                         }
124                         str = "mme_ar|" + *e2tData.E2TAddress + "|" + strings.TrimSuffix(meidar, " ")
125                 }
126                 return &e2tinst, str, nil
127
128         } else {
129                 xapp.Logger.Info("No data")
130         }
131
132         xapp.Logger.Debug("Nothing received on the Http interface")
133         return nil, str, nil
134 }
135
136 func validateXappCallbackData(callbackData *models.XappCallbackData) error {
137         if len(callbackData.XApps) == 0 {
138                 return fmt.Errorf("invalid Data field: \"%s\"", callbackData.XApps)
139         }
140         var xapps []rtmgr.XApp
141         err := json.Unmarshal([]byte(callbackData.XApps), &xapps)
142         if err != nil {
143                 return fmt.Errorf("unmarshal failed: \"%s\"", err.Error())
144         }
145         return nil
146 }
147
148 func provideXappHandleHandlerImpl(datach chan<- *models.XappCallbackData, data *models.XappCallbackData) error {
149         if data != nil {
150                 xapp.Logger.Debug("Received callback data")
151         }
152         err := validateXappCallbackData(data)
153         if err != nil {
154                 xapp.Logger.Warn("XApp callback data validation failed: " + err.Error())
155                 return err
156         } else {
157                 datach <- data
158                 return nil
159         }
160 }
161
162 func validateXappSubscriptionData(data *models.XappSubscriptionData) error {
163         var err = fmt.Errorf("XApp instance not found: %v:%v", *data.Address, *data.Port)
164         for _, ep := range rtmgr.Eps {
165                 if ep.Ip == *data.Address && ep.Port == *data.Port {
166                         err = nil
167                         break
168                 }
169         }
170         return err
171 }
172
173 func validateE2tData(data *models.E2tData) error {
174
175         e2taddress_key := *data.E2TAddress
176         if e2taddress_key == "" {
177                 return fmt.Errorf("E2TAddress is empty!!!")
178         }
179         stringSlice := strings.Split(e2taddress_key, ":")
180         if len(stringSlice) == 1 {
181                 return fmt.Errorf("E2T E2TAddress is not a proper format like ip:port, %v", e2taddress_key)
182         }
183
184         _, err := net.LookupIP(stringSlice[0])
185         if err != nil {
186                 return fmt.Errorf("E2T E2TAddress DNS look up failed, E2TAddress: %v", stringSlice[0])
187         }
188
189         if checkValidaE2TAddress(e2taddress_key) {
190                 return fmt.Errorf("E2TAddress already exist!!!, E2TAddress: %v", e2taddress_key)
191         }
192
193         return nil
194 }
195
196 func validateDeleteE2tData(data *models.E2tDeleteData) error {
197
198         if *data.E2TAddress == "" {
199                 return fmt.Errorf("E2TAddress is empty!!!")
200         }
201
202         for _, element := range data.RanAssocList {
203                 e2taddress_key := *element.E2TAddress
204                 stringSlice := strings.Split(e2taddress_key, ":")
205
206                 if len(stringSlice) == 1 {
207                         return fmt.Errorf("E2T Delete - RanAssocList E2TAddress is not a proper format like ip:port, %v", e2taddress_key)
208                 }
209
210                 if !checkValidaE2TAddress(e2taddress_key) {
211                         return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v", e2taddress_key)
212                 }
213
214         }
215         return nil
216 }
217
218 func checkValidaE2TAddress(e2taddress string) bool {
219
220         _, exist := rtmgr.Eps[e2taddress]
221         return exist
222
223 }
224
225 func provideXappSubscriptionHandleImpl(subchan chan<- *models.XappSubscriptionData,
226         data *models.XappSubscriptionData) error {
227         xapp.Logger.Debug("Invoked provideXappSubscriptionHandleImpl")
228         err := validateXappSubscriptionData(data)
229         if err != nil {
230                 xapp.Logger.Error(err.Error())
231                 return err
232         }
233         subchan <- data
234         //var val = string(*data.Address + ":" + strconv.Itoa(int(*data.Port)))
235         xapp.Logger.Debug("Endpoints: %v", rtmgr.Eps)
236         return nil
237 }
238
239 func subscriptionExists(data *models.XappSubscriptionData) bool {
240         present := false
241         sub := rtmgr.Subscription{SubID: *data.SubscriptionID, Fqdn: *data.Address, Port: *data.Port}
242         for _, elem := range rtmgr.Subs {
243                 if elem == sub {
244                         present = true
245                         break
246                 }
247         }
248         return present
249 }
250
251 func deleteXappSubscriptionHandleImpl(subdelchan chan<- *models.XappSubscriptionData,
252         data *models.XappSubscriptionData) error {
253         xapp.Logger.Debug("Invoked deleteXappSubscriptionHandleImpl")
254         err := validateXappSubscriptionData(data)
255         if err != nil {
256                 xapp.Logger.Error(err.Error())
257                 return err
258         }
259
260         if !subscriptionExists(data) {
261                 xapp.Logger.Warn("subscription not found: %d", *data.SubscriptionID)
262                 err := fmt.Errorf("subscription not found: %d", *data.SubscriptionID)
263                 return err
264         }
265
266         subdelchan <- data
267         return nil
268 }
269
270 func updateXappSubscriptionHandleImpl(subupdatechan chan<- *rtmgr.XappList, data *models.XappList, subid uint16) error {
271         xapp.Logger.Debug("Invoked updateXappSubscriptionHandleImpl")
272
273         var fqdnlist []rtmgr.FqDn
274         for _, item := range *data {
275                 fqdnlist = append(fqdnlist, rtmgr.FqDn(*item))
276         }
277         xapplist := rtmgr.XappList{SubscriptionID: subid, FqdnList: fqdnlist}
278         var subdata models.XappSubscriptionData
279         var id int32
280         id = int32(subid)
281         subdata.SubscriptionID = &id
282         for _, items := range fqdnlist {
283                 subdata.Address = items.Address
284                 subdata.Port = items.Port
285                 err := validateXappSubscriptionData(&subdata)
286                 if err != nil {
287                         xapp.Logger.Error(err.Error())
288                         return err
289                 }
290         }
291         subupdatechan <- &xapplist
292         return nil
293 }
294
295 func createNewE2tHandleHandlerImpl(e2taddchan chan<- *models.E2tData,
296         data *models.E2tData) error {
297         xapp.Logger.Debug("Invoked createNewE2tHandleHandlerImpl")
298         err := validateE2tData(data)
299         if err != nil {
300                 xapp.Logger.Error(err.Error())
301                 return err
302         }
303         e2taddchan <- data
304         return nil
305 }
306
307 func validateE2TAddressRANListData(assRanE2tData models.RanE2tMap) error {
308
309         xapp.Logger.Debug("Invoked.validateE2TAddressRANListData : %v", assRanE2tData)
310
311         for _, element := range assRanE2tData {
312                 if *element.E2TAddress == "" {
313                         return fmt.Errorf("E2T Instance - E2TAddress is empty!!!")
314                 }
315
316                 e2taddress_key := *element.E2TAddress
317                 if !checkValidaE2TAddress(e2taddress_key) {
318                         return fmt.Errorf("E2TAddress doesn't exist!!!, E2TAddress: %v", e2taddress_key)
319                 }
320
321         }
322         return nil
323 }
324
325 func associateRanToE2THandlerImpl(assranchan chan<- models.RanE2tMap,
326         data models.RanE2tMap) error {
327         xapp.Logger.Debug("Invoked associateRanToE2THandlerImpl")
328         err := validateE2TAddressRANListData(data)
329         if err != nil {
330                 xapp.Logger.Warn(" Association of RAN to E2T Instance data validation failed: " + err.Error())
331                 return err
332         }
333         assranchan <- data
334         return nil
335 }
336
337 func disassociateRanToE2THandlerImpl(disassranchan chan<- models.RanE2tMap,
338         data models.RanE2tMap) error {
339         xapp.Logger.Debug("Invoked disassociateRanToE2THandlerImpl")
340         err := validateE2TAddressRANListData(data)
341         if err != nil {
342                 xapp.Logger.Warn(" Disassociation of RAN List from E2T Instance data validation failed: " + err.Error())
343                 return err
344         }
345         disassranchan <- data
346         return nil
347 }
348
349 func deleteE2tHandleHandlerImpl(e2tdelchan chan<- *models.E2tDeleteData,
350         data *models.E2tDeleteData) error {
351         xapp.Logger.Debug("Invoked deleteE2tHandleHandlerImpl")
352
353         err := validateDeleteE2tData(data)
354         if err != nil {
355                 xapp.Logger.Error(err.Error())
356                 return err
357         }
358
359         e2tdelchan <- data
360         return nil
361 }
362
363 func dumpDebugData() (models.Debuginfo, error) {
364         var response models.Debuginfo
365         sdlEngine, _ := sdl.GetSdl("file")
366         rpeEngine, _ := rpe.GetRpe("rmrpush")
367         data, err := sdlEngine.ReadAll(xapp.Config.GetString("rtfile"))
368         if err != nil || data == nil {
369                 xapp.Logger.Error("Cannot get data from sdl interface due to: " + err.Error())
370                 return response, err
371         }
372         response.RouteTable = *rpeEngine.GeneratePolicies(rtmgr.Eps, data)
373
374         prettyJSON, err := json.MarshalIndent(data, "", "")
375         response.RouteConfigs = string(prettyJSON)
376
377         return response, err
378 }
379
380 func launchRest(nbiif *string, datach chan<- *models.XappCallbackData, subchan chan<- *models.XappSubscriptionData, subupdatechan chan<- *rtmgr.XappList,
381         subdelchan chan<- *models.XappSubscriptionData, e2taddchan chan<- *models.E2tData, assranchan chan<- models.RanE2tMap, disassranchan chan<- models.RanE2tMap, e2tdelchan chan<- *models.E2tDeleteData) {
382         swaggerSpec, err := loads.Embedded(restapi.SwaggerJSON, restapi.FlatSwaggerJSON)
383         if err != nil {
384                 //log.Fatalln(err)
385                 xapp.Logger.Error(err.Error())
386                 os.Exit(1)
387         }
388         nbiUrl, err := url.Parse(*nbiif)
389         if err != nil {
390                 xapp.Logger.Error(err.Error())
391                 os.Exit(1)
392         }
393         api := operations.NewRoutingManagerAPI(swaggerSpec)
394         server := restapi.NewServer(api)
395         defer server.Shutdown()
396
397         server.Port, err = strconv.Atoi(nbiUrl.Port())
398         if err != nil {
399                 xapp.Logger.Error("Invalid NBI RestAPI port")
400                 os.Exit(1)
401         }
402         server.Host = "0.0.0.0"
403         // set handlers
404         api.HandleProvideXappHandleHandler = handle.ProvideXappHandleHandlerFunc(
405                 func(params handle.ProvideXappHandleParams) middleware.Responder {
406                         xapp.Logger.Info("Data received on Http interface")
407                         err := provideXappHandleHandlerImpl(datach, params.XappCallbackData)
408                         if err != nil {
409                                 xapp.Logger.Error("Invalid XApp callback data: " + err.Error())
410                                 return handle.NewProvideXappHandleBadRequest()
411                         } else {
412                                 return handle.NewGetHandlesOK()
413                         }
414                 })
415         api.HandleProvideXappSubscriptionHandleHandler = handle.ProvideXappSubscriptionHandleHandlerFunc(
416                 func(params handle.ProvideXappSubscriptionHandleParams) middleware.Responder {
417                         err := provideXappSubscriptionHandleImpl(subchan, params.XappSubscriptionData)
418                         if err != nil {
419                                 return handle.NewProvideXappSubscriptionHandleBadRequest()
420                         } else {
421                                 //Delay the reponse as add subscription channel needs to update sdl and then sbi sends updated routes to all endpoints
422                                 time.Sleep(1 * time.Second)
423                                 return handle.NewGetHandlesOK()
424                         }
425                 })
426         api.HandleDeleteXappSubscriptionHandleHandler = handle.DeleteXappSubscriptionHandleHandlerFunc(
427                 func(params handle.DeleteXappSubscriptionHandleParams) middleware.Responder {
428                         err := deleteXappSubscriptionHandleImpl(subdelchan, params.XappSubscriptionData)
429                         if err != nil {
430                                 return handle.NewDeleteXappSubscriptionHandleNoContent()
431                         } else {
432                                 //Delay the reponse as delete subscription channel needs to update sdl and then sbi sends updated routes to all endpoints
433                                 time.Sleep(1 * time.Second)
434                                 return handle.NewGetHandlesOK()
435                         }
436                 })
437         api.HandleUpdateXappSubscriptionHandleHandler = handle.UpdateXappSubscriptionHandleHandlerFunc(
438                 func(params handle.UpdateXappSubscriptionHandleParams) middleware.Responder {
439                         err := updateXappSubscriptionHandleImpl(subupdatechan, &params.XappList, params.SubscriptionID)
440                         if err != nil {
441                                 return handle.NewUpdateXappSubscriptionHandleBadRequest()
442                         } else {
443                                 //Delay the reponse as delete subscription channel needs to update sdl and then sbi sends updated routes to all endpoints
444                                 time.Sleep(1 * time.Second)
445                                 return handle.NewUpdateXappSubscriptionHandleCreated()
446                         }
447                 })
448         api.HandleCreateNewE2tHandleHandler = handle.CreateNewE2tHandleHandlerFunc(
449                 func(params handle.CreateNewE2tHandleParams) middleware.Responder {
450                         err := createNewE2tHandleHandlerImpl(e2taddchan, params.E2tData)
451                         if err != nil {
452                                 return handle.NewCreateNewE2tHandleBadRequest()
453                         } else {
454                                 time.Sleep(1 * time.Second)
455                                 return handle.NewCreateNewE2tHandleCreated()
456                         }
457                 })
458
459         api.HandleAssociateRanToE2tHandleHandler = handle.AssociateRanToE2tHandleHandlerFunc(
460                 func(params handle.AssociateRanToE2tHandleParams) middleware.Responder {
461                         err := associateRanToE2THandlerImpl(assranchan, params.RanE2tList)
462                         if err != nil {
463                                 return handle.NewAssociateRanToE2tHandleBadRequest()
464                         } else {
465                                 time.Sleep(1 * time.Second)
466                                 return handle.NewAssociateRanToE2tHandleCreated()
467                         }
468                 })
469
470         api.HandleDissociateRanHandler = handle.DissociateRanHandlerFunc(
471                 func(params handle.DissociateRanParams) middleware.Responder {
472                         err := disassociateRanToE2THandlerImpl(disassranchan, params.DissociateList)
473                         if err != nil {
474                                 return handle.NewDissociateRanBadRequest()
475                         } else {
476                                 time.Sleep(1 * time.Second)
477                                 return handle.NewDissociateRanCreated()
478                         }
479                 })
480
481         api.HandleDeleteE2tHandleHandler = handle.DeleteE2tHandleHandlerFunc(
482                 func(params handle.DeleteE2tHandleParams) middleware.Responder {
483                         err := deleteE2tHandleHandlerImpl(e2tdelchan, params.E2tData)
484                         if err != nil {
485                                 return handle.NewDeleteE2tHandleBadRequest()
486                         } else {
487                                 time.Sleep(1 * time.Second)
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         // start to serve API
501         xapp.Logger.Info("Starting the HTTP Rest service")
502         if err := server.Serve(); err != nil {
503                 xapp.Logger.Error(err.Error())
504         }
505 }
506
507 func httpGetXApps(xmurl string) (*[]rtmgr.XApp, error) {
508         xapp.Logger.Info("Invoked httprestful.httpGetXApps: " + xmurl)
509         r, err := myClient.Get(xmurl)
510         if err != nil {
511                 return nil, err
512         }
513         defer r.Body.Close()
514
515         if r.StatusCode == 200 {
516                 xapp.Logger.Debug("http client raw response: %v", r)
517                 var xapps []rtmgr.XApp
518                 err = json.NewDecoder(r.Body).Decode(&xapps)
519                 if err != nil {
520                         xapp.Logger.Warn("Json decode failed: " + err.Error())
521                 }
522                 xapp.Logger.Info("HTTP GET: OK")
523                 xapp.Logger.Debug("httprestful.httpGetXApps returns: %v", xapps)
524                 return &xapps, err
525         }
526         xapp.Logger.Warn("httprestful got an unexpected http status code: %v", r.StatusCode)
527         return nil, nil
528 }
529
530 func retrieveStartupData(xmurl string, nbiif string, fileName string, configfile string, sdlEngine sdl.Engine) error {
531         var readErr error
532         var maxRetries = 10
533         for i := 1; i <= maxRetries; i++ {
534                 time.Sleep(2 * time.Second)
535                 xappData, err := httpGetXApps(xmurl)
536                 if xappData != nil && err == nil {
537                         pcData, confErr := rtmgr.GetPlatformComponents(configfile)
538                         if confErr != nil {
539                                 xapp.Logger.Error(confErr.Error())
540                                 return confErr
541                         }
542                         xapp.Logger.Info("Recieved intial xapp data and platform data, writing into SDL.")
543                         // Combine the xapps data and platform data before writing to the SDL
544                         ricData := &rtmgr.RicComponents{XApps: *xappData, Pcs: *pcData, E2Ts: make(map[string]rtmgr.E2TInstance)}
545                         writeErr := sdlEngine.WriteAll(fileName, ricData)
546                         if writeErr != nil {
547                                 xapp.Logger.Error(writeErr.Error())
548                         }
549                         // post subscription req to appmgr
550                         readErr = PostSubReq(xmurl, nbiif)
551                         if readErr == nil {
552                                 return nil
553                         }
554                 } else if err == nil {
555                         readErr = errors.New("unexpected HTTP status code")
556                 } else {
557                         xapp.Logger.Warn("cannot get xapp data due to: " + err.Error())
558                         readErr = err
559                 }
560         }
561         return readErr
562 }
563
564 func (r *HttpRestful) Initialize(xmurl string, nbiif string, fileName string, configfile string,
565         sdlEngine sdl.Engine, rpeEngine rpe.Engine, triggerSBI chan<- bool, m *sync.Mutex) error {
566         err := r.RetrieveStartupData(xmurl, nbiif, fileName, configfile, sdlEngine)
567         if err != nil {
568                 xapp.Logger.Error("Exiting as nbi failed to get the initial startup data from the xapp manager: " + err.Error())
569                 return err
570         }
571
572         datach := make(chan *models.XappCallbackData, 10)
573         subschan := make(chan *models.XappSubscriptionData, 10)
574         subdelchan := make(chan *models.XappSubscriptionData, 10)
575         subupdatechan := make(chan *rtmgr.XappList, 10)
576         e2taddchan := make(chan *models.E2tData, 10)
577         associateranchan := make(chan models.RanE2tMap, 10)
578         disassociateranchan := make(chan models.RanE2tMap, 10)
579         e2tdelchan := make(chan *models.E2tDeleteData, 10)
580         xapp.Logger.Info("Launching Rest Http service")
581         go func() {
582                 r.LaunchRest(&nbiif, datach, subschan, subupdatechan, subdelchan, e2taddchan, associateranchan, disassociateranchan, e2tdelchan)
583         }()
584
585         go func() {
586                 for {
587                         data, err := r.RecvXappCallbackData(datach)
588                         if err != nil {
589                                 xapp.Logger.Error("cannot get data from rest api dute to: " + err.Error())
590                         } else if data != nil {
591                                 xapp.Logger.Debug("Fetching all xApps deployed in xApp Manager through GET operation.")
592                                 alldata, err1 := httpGetXApps(xmurl)
593                                 if alldata != nil && err1 == nil {
594                                         m.Lock()
595                                         sdlEngine.WriteXApps(fileName, alldata)
596                                         m.Unlock()
597                                         triggerSBI <- true
598                                 }
599                         }
600                 }
601         }()
602
603         go func() {
604                 for {
605                         data := <-subschan
606                         xapp.Logger.Debug("received XApp subscription data")
607                         addSubscription(&rtmgr.Subs, data)
608                         triggerSBI <- true
609                 }
610         }()
611
612         go func() {
613                 for {
614                         data := <-subdelchan
615                         xapp.Logger.Debug("received XApp subscription delete data")
616                         delSubscription(&rtmgr.Subs, data)
617                         triggerSBI <- true
618                 }
619         }()
620
621         go func() {
622                 for {
623                         data := <-subupdatechan
624                         xapp.Logger.Debug("received XApp subscription Merge data")
625                         updateSubscription(data)
626                         triggerSBI <- true
627                 }
628         }()
629
630         go func() {
631                 for {
632
633                         data, meiddata, _ := r.RecvNewE2Tdata(e2taddchan)
634                         if data != nil {
635                                 xapp.Logger.Debug("received create New E2T data")
636                                 m.Lock()
637                                 sdlEngine.WriteNewE2TInstance(fileName, data, meiddata)
638                                 m.Unlock()
639                                 triggerSBI <- true
640                         }
641                 }
642         }()
643
644         go func() {
645                 for {
646                         data := <-associateranchan
647                         xapp.Logger.Debug("received associate RAN list to E2T instance mapping from E2 Manager")
648                         m.Lock()
649                         sdlEngine.WriteAssRANToE2TInstance(fileName, data)
650                         m.Unlock()
651                         triggerSBI <- true
652                 }
653         }()
654
655         go func() {
656                 for {
657
658                         data := <-disassociateranchan
659                         xapp.Logger.Debug("received disassociate RANs from E2T instance")
660                         m.Lock()
661                         sdlEngine.WriteDisAssRANFromE2TInstance(fileName, data)
662                         m.Unlock()
663                         triggerSBI <- true
664                 }
665         }()
666
667         go func() {
668                 for {
669
670                         data := <-e2tdelchan
671                         xapp.Logger.Debug("received Delete E2T data")
672                         if data != nil {
673                                 m.Lock()
674                                 sdlEngine.WriteDeleteE2TInstance(fileName, data)
675                                 m.Unlock()
676                                 triggerSBI <- true
677                         }
678                 }
679         }()
680
681         return nil
682 }
683
684 func (r *HttpRestful) Terminate() error {
685         return nil
686 }
687
688 func addSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
689         xapp.Logger.Debug("Adding the subscription into the subscriptions list")
690         var b = false
691         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
692         for _, elem := range *subs {
693                 if elem == sub {
694                         xapp.Logger.Warn("rtmgr.addSubscription: Subscription already present: %v", elem)
695                         b = true
696                 }
697         }
698         if b == false {
699                 *subs = append(*subs, sub)
700         }
701         return b
702 }
703
704 func delSubscription(subs *rtmgr.SubscriptionList, xappSubData *models.XappSubscriptionData) bool {
705         xapp.Logger.Debug("Deleteing the subscription from the subscriptions list")
706         var present = false
707         sub := rtmgr.Subscription{SubID: *xappSubData.SubscriptionID, Fqdn: *xappSubData.Address, Port: *xappSubData.Port}
708         for i, elem := range *subs {
709                 if elem == sub {
710                         present = true
711                         // Since the order of the list is not important, we are swapping the last element
712                         // with the matching element and replacing the list with list(n-1) elements.
713                         (*subs)[len(*subs)-1], (*subs)[i] = (*subs)[i], (*subs)[len(*subs)-1]
714                         *subs = (*subs)[:len(*subs)-1]
715                         break
716                 }
717         }
718         if present == false {
719                 xapp.Logger.Warn("rtmgr.delSubscription: Subscription = %v, not present in the existing subscriptions", xappSubData)
720         }
721         return present
722 }
723
724 func updateSubscription(data *rtmgr.XappList) {
725
726         var subdata models.XappSubscriptionData
727         var id int32
728         var matchingsubid, deletecount uint8
729         id = int32(data.SubscriptionID)
730         subdata.SubscriptionID = &id
731         for _, subs := range rtmgr.Subs {
732                 if int32(data.SubscriptionID) == subs.SubID {
733                         matchingsubid++
734                 }
735         }
736
737         for deletecount < matchingsubid {
738                 for _, subs := range rtmgr.Subs {
739                         if int32(data.SubscriptionID) == subs.SubID {
740                                 subdata.SubscriptionID = &subs.SubID
741                                 subdata.Address = &subs.Fqdn
742                                 subdata.Port = &subs.Port
743                                 xapp.Logger.Debug("Deletion Subscription List has %v", subdata)
744                                 delSubscription(&rtmgr.Subs, &subdata)
745                                 break
746                         }
747                 }
748                 deletecount++
749         }
750
751         for _, items := range data.FqdnList {
752                 subdata.Address = items.Address
753                 subdata.Port = items.Port
754                 xapp.Logger.Debug("Adding Subscription List has %v", subdata)
755                 addSubscription(&rtmgr.Subs, &subdata)
756         }
757
758 }