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