Unit test description improvements
[ric-plt/submgr.git] / pkg / control / control.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
20 package control
21
22 import (
23         "fmt"
24         "net/http"
25         "os"
26         "strconv"
27         "strings"
28         "sync"
29         "time"
30
31         "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
32         rtmgrclient "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/rtmgr_client"
33         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
34         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/common"
35         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
36         httptransport "github.com/go-openapi/runtime/client"
37         "github.com/go-openapi/strfmt"
38         "github.com/gorilla/mux"
39         "github.com/segmentio/ksuid"
40         "github.com/spf13/viper"
41 )
42
43 //-----------------------------------------------------------------------------
44 //
45 //-----------------------------------------------------------------------------
46
47 func idstring(err error, entries ...fmt.Stringer) string {
48         var retval string = ""
49         var filler string = ""
50         for _, entry := range entries {
51                 if entry != nil {
52                         retval += filler + entry.String()
53                         filler = " "
54                 } else {
55                         retval += filler + "(NIL)"
56                 }
57         }
58         if err != nil {
59                 retval += filler + "err(" + err.Error() + ")"
60                 filler = " "
61         }
62         return retval
63 }
64
65 //-----------------------------------------------------------------------------
66 //
67 //-----------------------------------------------------------------------------
68
69 var e2tSubReqTimeout time.Duration
70 var e2tSubDelReqTime time.Duration
71 var e2tRecvMsgTimeout time.Duration
72 var waitRouteCleanup_ms time.Duration
73 var e2tMaxSubReqTryCount uint64    // Initial try + retry
74 var e2tMaxSubDelReqTryCount uint64 // Initial try + retry
75 var checkE2State string
76 var readSubsFromDb string
77 var dbRetryForever string
78 var dbTryCount int
79
80 type Control struct {
81         *xapp.RMRClient
82         e2ap              *E2ap
83         registry          *Registry
84         tracker           *Tracker
85         restDuplicateCtrl *DuplicateCtrl
86         e2IfState         *E2IfState
87         e2IfStateDb       XappRnibInterface
88         e2SubsDb          Sdlnterface
89         restSubsDb        Sdlnterface
90         CntRecvMsg        uint64
91         ResetTestFlag     bool
92         Counters          map[string]xapp.Counter
93         LoggerLevel       int
94         UTTesting         bool
95 }
96
97 type RMRMeid struct {
98         PlmnID  string
99         EnbID   string
100         RanName string
101 }
102
103 type SubmgrRestartTestEvent struct{}
104 type SubmgrRestartUpEvent struct{}
105 type PackSubscriptionRequestErrortEvent struct {
106         ErrorInfo ErrorInfo
107 }
108
109 func (p *PackSubscriptionRequestErrortEvent) SetEvent(errorInfo *ErrorInfo) {
110         p.ErrorInfo = *errorInfo
111 }
112
113 type SDLWriteErrortEvent struct {
114         ErrorInfo ErrorInfo
115 }
116
117 func (s *SDLWriteErrortEvent) SetEvent(errorInfo *ErrorInfo) {
118         s.ErrorInfo = *errorInfo
119 }
120
121 func init() {
122         xapp.Logger.Debug("SUBMGR")
123         viper.AutomaticEnv()
124         viper.SetEnvPrefix("submgr")
125         viper.AllowEmptyEnv(true)
126 }
127
128 func NewControl() *Control {
129
130         transport := httptransport.New(viper.GetString("rtmgr.HostAddr")+":"+viper.GetString("rtmgr.port"), viper.GetString("rtmgr.baseUrl"), []string{"http"})
131         rtmgrClient := RtmgrClient{rtClient: rtmgrclient.New(transport, strfmt.Default)}
132
133         registry := new(Registry)
134         registry.Initialize()
135         registry.rtmgrClient = &rtmgrClient
136
137         tracker := new(Tracker)
138         tracker.Init()
139
140         restDuplicateCtrl := new(DuplicateCtrl)
141         restDuplicateCtrl.Init()
142
143         e2IfState := new(E2IfState)
144
145         c := &Control{e2ap: new(E2ap),
146                 registry:          registry,
147                 tracker:           tracker,
148                 restDuplicateCtrl: restDuplicateCtrl,
149                 e2IfState:         e2IfState,
150                 e2IfStateDb:       CreateXappRnibIfInstance(),
151                 e2SubsDb:          CreateSdl(),
152                 restSubsDb:        CreateRESTSdl(),
153                 Counters:          xapp.Metric.RegisterCounterGroup(GetMetricsOpts(), "SUBMGR"),
154                 LoggerLevel:       1,
155         }
156
157         e2IfState.Init(c)
158         c.ReadConfigParameters("")
159
160         // Register REST handler for testing support
161         xapp.Resource.InjectRoute("/ric/v1/test/{testId}", c.TestRestHandler, "POST")
162         xapp.Resource.InjectRoute("/ric/v1/restsubscriptions", c.GetAllRestSubscriptions, "GET")
163         xapp.Resource.InjectRoute("/ric/v1/symptomdata", c.SymptomDataHandler, "GET")
164
165         if readSubsFromDb == "true" {
166                 // Read subscriptions from db
167                 c.ReadE2Subscriptions()
168                 c.ReadRESTSubscriptions()
169         }
170
171         go xapp.Subscription.Listen(c.RESTSubscriptionHandler, c.RESTQueryHandler, c.RESTSubscriptionDeleteHandler)
172         return c
173 }
174
175 func (c *Control) SymptomDataHandler(w http.ResponseWriter, r *http.Request) {
176         subscriptions, _ := c.registry.QueryHandler()
177         xapp.Resource.SendSymptomDataJson(w, r, subscriptions, "platform/subscriptions.json")
178 }
179
180 //-------------------------------------------------------------------
181 //
182 //-------------------------------------------------------------------
183 func (c *Control) GetAllRestSubscriptions(w http.ResponseWriter, r *http.Request) {
184         xapp.Logger.Debug("GetAllRestSubscriptions() called")
185         response := c.registry.GetAllRestSubscriptions()
186         w.Write(response)
187 }
188
189 //-------------------------------------------------------------------
190 //
191 //-------------------------------------------------------------------
192 func (c *Control) ReadE2Subscriptions() error {
193         var err error
194         var subIds []uint32
195         var register map[uint32]*Subscription
196         for i := 0; dbRetryForever == "true" || i < dbTryCount; i++ {
197                 xapp.Logger.Debug("Reading E2 subscriptions from db")
198                 subIds, register, err = c.ReadAllSubscriptionsFromSdl()
199                 if err != nil {
200                         xapp.Logger.Error("%v", err)
201                         <-time.After(1 * time.Second)
202                 } else {
203                         c.registry.subIds = subIds
204                         c.registry.register = register
205                         go c.HandleUncompletedSubscriptions(register)
206                         return nil
207                 }
208         }
209         xapp.Logger.Debug("Continuing without retring")
210         return err
211 }
212
213 //-------------------------------------------------------------------
214 //
215 //-------------------------------------------------------------------
216 func (c *Control) ReadRESTSubscriptions() error {
217
218         xapp.Logger.Debug("ReadRESTSubscriptions()")
219         var err error
220         var restSubscriptions map[string]*RESTSubscription
221         for i := 0; dbRetryForever == "true" || i < dbTryCount; i++ {
222                 xapp.Logger.Debug("Reading REST subscriptions from db")
223                 restSubscriptions, err = c.ReadAllRESTSubscriptionsFromSdl()
224                 if err != nil {
225                         xapp.Logger.Error("%v", err)
226                         <-time.After(1 * time.Second)
227                 } else {
228                         // Fix REST subscriptions ongoing status after restart
229                         for restSubId, restSubscription := range restSubscriptions {
230                                 restSubscription.SubReqOngoing = false
231                                 restSubscription.SubDelReqOngoing = false
232                                 c.WriteRESTSubscriptionToSdl(restSubId, restSubscription)
233                         }
234                         c.registry.restSubscriptions = restSubscriptions
235                         return nil
236                 }
237         }
238         xapp.Logger.Debug("Continuing without retring")
239         return err
240 }
241
242 //-------------------------------------------------------------------
243 //
244 //-------------------------------------------------------------------
245 func (c *Control) ReadConfigParameters(f string) {
246
247         xapp.Logger.Debug("ReadConfigParameters")
248
249         c.LoggerLevel = int(xapp.Logger.GetLevel())
250         xapp.Logger.Info("LoggerLevel = %v", c.LoggerLevel)
251         c.e2ap.SetASN1DebugPrintStatus(c.LoggerLevel)
252
253         // viper.GetDuration returns nanoseconds
254         e2tSubReqTimeout = viper.GetDuration("controls.e2tSubReqTimeout_ms") * 1000000
255         if e2tSubReqTimeout == 0 {
256                 e2tSubReqTimeout = 2000 * 1000000
257                 xapp.Logger.Debug("WARNING: Using hard coded default value for e2tSubReqTimeout")
258         }
259         xapp.Logger.Debug("e2tSubReqTimeout= %v", e2tSubReqTimeout)
260
261         e2tSubDelReqTime = viper.GetDuration("controls.e2tSubDelReqTime_ms") * 1000000
262         if e2tSubDelReqTime == 0 {
263                 e2tSubDelReqTime = 2000 * 1000000
264                 xapp.Logger.Debug("WARNING: Using hard coded default value for e2tSubDelReqTime")
265         }
266         xapp.Logger.Debug("e2tSubDelReqTime= %v", e2tSubDelReqTime)
267
268         e2tRecvMsgTimeout = viper.GetDuration("controls.e2tRecvMsgTimeout_ms") * 1000000
269         if e2tRecvMsgTimeout == 0 {
270                 e2tRecvMsgTimeout = 2000 * 1000000
271                 xapp.Logger.Debug("WARNING: Using hard coded default value for e2tRecvMsgTimeout")
272         }
273         xapp.Logger.Debug("e2tRecvMsgTimeout= %v", e2tRecvMsgTimeout)
274
275         e2tMaxSubReqTryCount = viper.GetUint64("controls.e2tMaxSubReqTryCount")
276         if e2tMaxSubReqTryCount == 0 {
277                 e2tMaxSubReqTryCount = 1
278                 xapp.Logger.Debug("WARNING: Using hard coded default value for e2tMaxSubReqTryCount")
279         }
280         xapp.Logger.Debug("e2tMaxSubReqTryCount= %v", e2tMaxSubReqTryCount)
281
282         e2tMaxSubDelReqTryCount = viper.GetUint64("controls.e2tMaxSubDelReqTryCount")
283         if e2tMaxSubDelReqTryCount == 0 {
284                 e2tMaxSubDelReqTryCount = 1
285                 xapp.Logger.Debug("WARNING: Using hard coded default value for e2tMaxSubDelReqTryCount")
286         }
287         xapp.Logger.Debug("e2tMaxSubDelReqTryCount= %v", e2tMaxSubDelReqTryCount)
288
289         checkE2State = viper.GetString("controls.checkE2State")
290         if checkE2State == "" {
291                 checkE2State = "true"
292                 xapp.Logger.Debug("WARNING: Using hard coded default value for checkE2State")
293         }
294         xapp.Logger.Debug("checkE2State= %v", checkE2State)
295
296         readSubsFromDb = viper.GetString("controls.readSubsFromDb")
297         if readSubsFromDb == "" {
298                 readSubsFromDb = "true"
299                 xapp.Logger.Debug("WARNING: Using hard coded default value for readSubsFromDb")
300         }
301         xapp.Logger.Debug("readSubsFromDb= %v", readSubsFromDb)
302
303         dbTryCount = viper.GetInt("controls.dbTryCount")
304         if dbTryCount == 0 {
305                 dbTryCount = 200
306                 xapp.Logger.Debug("WARNING: Using hard coded default value for dbTryCount")
307         }
308         xapp.Logger.Debug("dbTryCount= %v", dbTryCount)
309
310         dbRetryForever = viper.GetString("controls.dbRetryForever")
311         if dbRetryForever == "" {
312                 dbRetryForever = "true"
313                 xapp.Logger.Debug("WARNING: Using hard coded default value for dbRetryForever")
314         }
315         xapp.Logger.Debug("dbRetryForever= %v", dbRetryForever)
316
317         // Internal cfg parameter, used to define a wait time for RMR route clean-up. None default
318         // value 100ms used currently only in unittests.
319         waitRouteCleanup_ms = viper.GetDuration("controls.waitRouteCleanup_ms") * 1000000
320         if waitRouteCleanup_ms == 0 {
321                 waitRouteCleanup_ms = 5000 * 1000000
322                 xapp.Logger.Debug("WARNING: Using hard coded default value for waitRouteCleanup_ms")
323         }
324         xapp.Logger.Debug("waitRouteCleanup= %v", waitRouteCleanup_ms)
325 }
326
327 //-------------------------------------------------------------------
328 //
329 //-------------------------------------------------------------------
330 func (c *Control) HandleUncompletedSubscriptions(register map[uint32]*Subscription) {
331
332         xapp.Logger.Debug("HandleUncompletedSubscriptions. len(register) = %v", len(register))
333         for subId, subs := range register {
334                 if subs.SubRespRcvd == false {
335                         // If policy subscription has already been made successfully unsuccessful update should not be deleted.
336                         if subs.PolicyUpdate == false {
337                                 subs.NoRespToXapp = true
338                                 xapp.Logger.Debug("SendSubscriptionDeleteReq. subId = %v", subId)
339                                 c.SendSubscriptionDeleteReq(subs)
340                         }
341                 }
342         }
343 }
344
345 func (c *Control) ReadyCB(data interface{}) {
346         if c.RMRClient == nil {
347                 c.RMRClient = xapp.Rmr
348         }
349 }
350
351 func (c *Control) Run() {
352         xapp.SetReadyCB(c.ReadyCB, nil)
353         xapp.AddConfigChangeListener(c.ReadConfigParameters)
354         xapp.Run(c)
355 }
356
357 //-------------------------------------------------------------------
358 //
359 //-------------------------------------------------------------------
360 func (c *Control) GetOrCreateRestSubscription(p *models.SubscriptionParams, md5sum string, xAppRmrEndpoint string) (*RESTSubscription, string, error) {
361
362         var restSubId string
363         var restSubscription *RESTSubscription
364         var err error
365
366         prevRestSubsId, exists := c.restDuplicateCtrl.GetLastKnownRestSubsIdBasedOnMd5sum(md5sum)
367         if p.SubscriptionID == "" {
368                 // Subscription does not contain REST subscription Id
369                 if exists {
370                         restSubscription, err = c.registry.GetRESTSubscription(prevRestSubsId, false)
371                         if restSubscription != nil {
372                                 // Subscription not found
373                                 restSubId = prevRestSubsId
374                                 if err == nil {
375                                         xapp.Logger.Debug("Existing restSubId %s found by MD5sum %s for a request without subscription ID - using previous subscription", prevRestSubsId, md5sum)
376                                 } else {
377                                         xapp.Logger.Debug("Existing restSubId %s found by MD5sum %s for a request without subscription ID - Note: %s", prevRestSubsId, md5sum, err.Error())
378                                 }
379                         } else {
380                                 xapp.Logger.Debug("None existing restSubId %s referred by MD5sum %s for a request without subscription ID - deleting cached entry", prevRestSubsId, md5sum)
381                                 c.restDuplicateCtrl.DeleteLastKnownRestSubsIdBasedOnMd5sum(md5sum)
382                         }
383                 }
384
385                 if restSubscription == nil {
386                         restSubId = ksuid.New().String()
387                         restSubscription = c.registry.CreateRESTSubscription(&restSubId, &xAppRmrEndpoint, p.Meid)
388                 }
389         } else {
390                 // Subscription contains REST subscription Id
391                 restSubId = p.SubscriptionID
392
393                 xapp.Logger.Debug("RestSubscription ID %s provided via REST request", restSubId)
394                 restSubscription, err = c.registry.GetRESTSubscription(restSubId, false)
395                 if err != nil {
396                         // Subscription with id in REST request does not exist
397                         xapp.Logger.Error("%s", err.Error())
398                         c.UpdateCounter(cRestSubFailToXapp)
399                         return nil, "", err
400                 }
401
402                 if !exists {
403                         xapp.Logger.Debug("Existing restSubscription found for ID %s, new request based on md5sum", restSubId)
404                 } else {
405                         xapp.Logger.Debug("Existing restSubscription found for ID %s(%s), re-transmission based on md5sum match with previous request", prevRestSubsId, restSubId)
406                 }
407         }
408
409         return restSubscription, restSubId, nil
410 }
411
412 //-------------------------------------------------------------------
413 //
414 //-------------------------------------------------------------------
415 func (c *Control) RESTSubscriptionHandler(params interface{}) (*models.SubscriptionResponse, int) {
416
417         c.CntRecvMsg++
418         c.UpdateCounter(cRestSubReqFromXapp)
419
420         subResp := models.SubscriptionResponse{}
421         p := params.(*models.SubscriptionParams)
422
423         if c.LoggerLevel > 2 {
424                 c.PrintRESTSubscriptionRequest(p)
425         }
426
427         if c.e2IfState.IsE2ConnectionUp(p.Meid) == false {
428                 xapp.Logger.Error("No E2 connection for ranName %v", *p.Meid)
429                 c.UpdateCounter(cRestReqRejDueE2Down)
430                 return nil, common.SubscribeServiceUnavailableCode
431         }
432
433         if p.ClientEndpoint == nil {
434                 err := fmt.Errorf("ClientEndpoint == nil")
435                 xapp.Logger.Error("%v", err)
436                 c.UpdateCounter(cRestSubFailToXapp)
437                 return nil, common.SubscribeBadRequestCode
438         }
439
440         _, xAppRmrEndpoint, err := ConstructEndpointAddresses(*p.ClientEndpoint)
441         if err != nil {
442                 xapp.Logger.Error("%s", err.Error())
443                 c.UpdateCounter(cRestSubFailToXapp)
444                 return nil, common.SubscribeBadRequestCode
445         }
446
447         md5sum, err := CalculateRequestMd5sum(params)
448         if err != nil {
449                 xapp.Logger.Error("Failed to generate md5sum from incoming request - %s", err.Error())
450         }
451
452         restSubscription, restSubId, err := c.GetOrCreateRestSubscription(p, md5sum, xAppRmrEndpoint)
453         if err != nil {
454                 xapp.Logger.Error("Subscription with id in REST request does not exist")
455                 return nil, common.SubscribeNotFoundCode
456         }
457
458         subResp.SubscriptionID = &restSubId
459         subReqList := e2ap.SubscriptionRequestList{}
460         err = c.e2ap.FillSubscriptionReqMsgs(params, &subReqList, restSubscription)
461         if err != nil {
462                 xapp.Logger.Error("%s", err.Error())
463                 c.restDuplicateCtrl.DeleteLastKnownRestSubsIdBasedOnMd5sum(md5sum)
464                 c.registry.DeleteRESTSubscription(&restSubId)
465                 c.UpdateCounter(cRestSubFailToXapp)
466                 return nil, common.SubscribeBadRequestCode
467         }
468
469         duplicate := c.restDuplicateCtrl.IsDuplicateToOngoingTransaction(restSubId, md5sum)
470         if duplicate {
471                 err := fmt.Errorf("Retransmission blocker direct ACK for request of restSubsId %s restSubId MD5sum %s as retransmission", restSubId, md5sum)
472                 xapp.Logger.Debug("%s", err)
473                 c.registry.DeleteRESTSubscription(&restSubId)
474                 c.UpdateCounter(cRestSubRespToXapp)
475                 return &subResp, common.SubscribeCreatedCode
476         }
477
478         c.WriteRESTSubscriptionToDb(restSubId, restSubscription)
479         e2SubscriptionDirectives, err := c.GetE2SubscriptionDirectives(p)
480         if err != nil {
481                 xapp.Logger.Error("%s", err)
482                 c.registry.DeleteRESTSubscription(&restSubId)
483                 return nil, common.SubscribeBadRequestCode
484         }
485         go c.processSubscriptionRequests(restSubscription, &subReqList, p.ClientEndpoint, p.Meid, &restSubId, xAppRmrEndpoint, md5sum, e2SubscriptionDirectives)
486
487         c.UpdateCounter(cRestSubRespToXapp)
488         return &subResp, common.SubscribeCreatedCode
489 }
490
491 //-------------------------------------------------------------------
492 //
493 //-------------------------------------------------------------------
494 func (c *Control) GetE2SubscriptionDirectives(p *models.SubscriptionParams) (*E2SubscriptionDirectives, error) {
495
496         e2SubscriptionDirectives := &E2SubscriptionDirectives{}
497         if p == nil || p.E2SubscriptionDirectives == nil {
498                 e2SubscriptionDirectives.E2TimeoutTimerValue = e2tSubReqTimeout
499                 e2SubscriptionDirectives.E2MaxTryCount = int64(e2tMaxSubReqTryCount)
500                 e2SubscriptionDirectives.CreateRMRRoute = true
501                 xapp.Logger.Debug("p == nil || p.E2SubscriptionDirectives == nil. Using default values for E2TimeoutTimerValue = %v and E2RetryCount = %v RMRRoutingNeeded = true", e2tSubReqTimeout, e2tMaxSubReqTryCount)
502         } else {
503                 if p.E2SubscriptionDirectives.E2TimeoutTimerValue >= 1 && p.E2SubscriptionDirectives.E2TimeoutTimerValue <= 10 {
504                         e2SubscriptionDirectives.E2TimeoutTimerValue = time.Duration(p.E2SubscriptionDirectives.E2TimeoutTimerValue) * 1000000000 // Duration type cast returns nano seconds
505                 } else {
506                         return nil, fmt.Errorf("p.E2SubscriptionDirectives.E2TimeoutTimerValue out of range (1-10 seconds): %v", p.E2SubscriptionDirectives.E2TimeoutTimerValue)
507                 }
508                 if p.E2SubscriptionDirectives.E2RetryCount == nil {
509                         xapp.Logger.Error("p.E2SubscriptionDirectives.E2RetryCount == nil. Using default value")
510                         e2SubscriptionDirectives.E2MaxTryCount = int64(e2tMaxSubReqTryCount)
511                 } else {
512                         if *p.E2SubscriptionDirectives.E2RetryCount >= 0 && *p.E2SubscriptionDirectives.E2RetryCount <= 10 {
513                                 e2SubscriptionDirectives.E2MaxTryCount = *p.E2SubscriptionDirectives.E2RetryCount + 1 // E2MaxTryCount = First sending plus two retries
514                         } else {
515                                 return nil, fmt.Errorf("p.E2SubscriptionDirectives.E2RetryCount out of range (0-10): %v", *p.E2SubscriptionDirectives.E2RetryCount)
516                         }
517                 }
518                 e2SubscriptionDirectives.CreateRMRRoute = p.E2SubscriptionDirectives.RMRRoutingNeeded
519         }
520         xapp.Logger.Debug("e2SubscriptionDirectives.E2TimeoutTimerValue: %v", e2SubscriptionDirectives.E2TimeoutTimerValue)
521         xapp.Logger.Debug("e2SubscriptionDirectives.E2MaxTryCount: %v", e2SubscriptionDirectives.E2MaxTryCount)
522         xapp.Logger.Debug("e2SubscriptionDirectives.CreateRMRRoute: %v", e2SubscriptionDirectives.CreateRMRRoute)
523         return e2SubscriptionDirectives, nil
524 }
525
526 //-------------------------------------------------------------------
527 //
528 //-------------------------------------------------------------------
529
530 func (c *Control) processSubscriptionRequests(restSubscription *RESTSubscription, subReqList *e2ap.SubscriptionRequestList,
531         clientEndpoint *models.SubscriptionParamsClientEndpoint, meid *string, restSubId *string, xAppRmrEndpoint string, md5sum string, e2SubscriptionDirectives *E2SubscriptionDirectives) {
532
533         c.SubscriptionProcessingStartDelay()
534         xapp.Logger.Debug("E2 SubscriptionRequest count = %v ", len(subReqList.E2APSubscriptionRequests))
535
536         var xAppEventInstanceID int64
537         var e2EventInstanceID int64
538         errorInfo := &ErrorInfo{}
539
540         defer c.restDuplicateCtrl.SetMd5sumFromLastOkRequest(*restSubId, md5sum)
541
542         for index := 0; index < len(subReqList.E2APSubscriptionRequests); index++ {
543                 subReqMsg := subReqList.E2APSubscriptionRequests[index]
544                 xAppEventInstanceID = (int64)(subReqMsg.RequestId.Id)
545
546                 trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(xAppRmrEndpoint), *restSubId, subReqMsg.RequestId, &xapp.RMRMeid{RanName: *meid})
547                 if trans == nil {
548                         // Send notification to xApp that prosessing of a Subscription Request has failed.
549                         err := fmt.Errorf("Tracking failure")
550                         errorInfo.ErrorCause = err.Error()
551                         c.sendUnsuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, err, clientEndpoint, trans, errorInfo)
552                         continue
553                 }
554
555                 xapp.Logger.Debug("Handle SubscriptionRequest index=%v, %s", index, idstring(nil, trans))
556
557                 subRespMsg, errorInfo, err := c.handleSubscriptionRequest(trans, &subReqMsg, meid, *restSubId, e2SubscriptionDirectives)
558
559                 xapp.Logger.Debug("Handled SubscriptionRequest index=%v, %s", index, idstring(nil, trans))
560                 trans.Release()
561
562                 if err != nil {
563                         if err.Error() == "TEST: restart event received" {
564                                 // This is just for UT cases. Stop here subscription processing
565                                 return
566                         }
567                         c.sendUnsuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, err, clientEndpoint, trans, errorInfo)
568                 } else {
569                         e2EventInstanceID = (int64)(subRespMsg.RequestId.InstanceId)
570                         restSubscription.AddMd5Sum(md5sum)
571                         xapp.Logger.Debug("SubscriptionRequest index=%v processed successfullyfor %s. endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
572                                 index, *restSubId, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
573                         c.sendSuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, e2EventInstanceID, clientEndpoint, trans)
574                 }
575         }
576 }
577
578 //-------------------------------------------------------------------
579 //
580 //------------------------------------------------------------------
581 func (c *Control) SubscriptionProcessingStartDelay() {
582         if c.UTTesting == true {
583                 // This is temporary fix for the UT problem that notification arrives before subscription response
584                 // Correct fix would be to allow notification come before response and process it correctly
585                 xapp.Logger.Debug("Setting 50 ms delay before starting processing Subscriptions")
586                 <-time.After(time.Millisecond * 50)
587                 xapp.Logger.Debug("Continuing after delay")
588         }
589 }
590
591 //-------------------------------------------------------------------
592 //
593 //------------------------------------------------------------------
594 func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, meid *string,
595         restSubId string, e2SubscriptionDirectives *E2SubscriptionDirectives) (*e2ap.E2APSubscriptionResponse, *ErrorInfo, error) {
596
597         errorInfo := ErrorInfo{}
598
599         err := c.tracker.Track(trans)
600         if err != nil {
601                 xapp.Logger.Error("XAPP-SubReq Tracking error: %s", idstring(err, trans))
602                 errorInfo.ErrorCause = err.Error()
603                 err = fmt.Errorf("Tracking failure")
604                 return nil, &errorInfo, err
605         }
606
607         subs, errorInfo, err := c.registry.AssignToSubscription(trans, subReqMsg, c.ResetTestFlag, c, e2SubscriptionDirectives.CreateRMRRoute)
608         if err != nil {
609                 xapp.Logger.Error("XAPP-SubReq Assign error: %s", idstring(err, trans))
610                 return nil, &errorInfo, err
611         }
612
613         //
614         // Wake subs request
615         //
616         subs.OngoingReqCount++
617         go c.handleSubscriptionCreate(subs, trans, e2SubscriptionDirectives, 0)
618         event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
619         subs.OngoingReqCount--
620
621         err = nil
622         if event != nil {
623                 switch themsg := event.(type) {
624                 case *e2ap.E2APSubscriptionResponse:
625                         trans.Release()
626                         if c.e2IfState.IsE2ConnectionUp(meid) == true {
627                                 return themsg, &errorInfo, nil
628                         } else {
629                                 c.registry.RemoveFromSubscription(subs, trans, waitRouteCleanup_ms, c)
630                                 c.RemoveSubscriptionFromDb(subs)
631                                 err = fmt.Errorf("E2 interface down")
632                                 errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
633                         }
634                 case *e2ap.E2APSubscriptionFailure:
635                         err = fmt.Errorf("E2 SubscriptionFailure received")
636                         errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
637                 case *PackSubscriptionRequestErrortEvent:
638                         err = fmt.Errorf("E2 SubscriptionRequest pack failure")
639                         errorInfo = themsg.ErrorInfo
640                 case *SDLWriteErrortEvent:
641                         err = fmt.Errorf("SDL write failure")
642                         errorInfo = themsg.ErrorInfo
643                 case *SubmgrRestartTestEvent:
644                         err = fmt.Errorf("TEST: restart event received")
645                         xapp.Logger.Debug("%s", err)
646                         return nil, &errorInfo, err
647                 default:
648                         err = fmt.Errorf("Unexpected E2 subscription response received")
649                         errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
650                         break
651                 }
652         } else {
653                 // Timer expiry
654                 err = fmt.Errorf("E2 subscription response timeout")
655                 errorInfo.SetInfo(err.Error(), "", models.SubscriptionInstanceTimeoutTypeE2Timeout)
656                 if subs.PolicyUpdate == true {
657                         return nil, &errorInfo, err
658                 }
659         }
660
661         xapp.Logger.Error("XAPP-SubReq E2 subscription failed %s", idstring(err, trans, subs))
662         c.registry.RemoveFromSubscription(subs, trans, waitRouteCleanup_ms, c)
663         return nil, &errorInfo, err
664 }
665
666 //-------------------------------------------------------------------
667 //
668 //-------------------------------------------------------------------
669 func (c *Control) sendUnsuccesfullResponseNotification(restSubId *string, restSubscription *RESTSubscription, xAppEventInstanceID int64, err error,
670         clientEndpoint *models.SubscriptionParamsClientEndpoint, trans *TransactionXapp, errorInfo *ErrorInfo) {
671
672         // Send notification to xApp that prosessing of a Subscription Request has failed.
673         e2EventInstanceID := (int64)(0)
674         if errorInfo.ErrorSource == "" {
675                 // Submgr is default source of error
676                 errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceSUBMGR
677         }
678         resp := &models.SubscriptionResponse{
679                 SubscriptionID: restSubId,
680                 SubscriptionInstances: []*models.SubscriptionInstance{
681                         &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
682                                 ErrorCause:          errorInfo.ErrorCause,
683                                 ErrorSource:         errorInfo.ErrorSource,
684                                 TimeoutType:         errorInfo.TimeoutType,
685                                 XappEventInstanceID: &xAppEventInstanceID},
686                 },
687         }
688         // Mark REST subscription request processed.
689         restSubscription.SetProcessed(err)
690         c.UpdateRESTSubscriptionInDB(*restSubId, restSubscription, false)
691         if trans != nil {
692                 xapp.Logger.Debug("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
693                         errorInfo.ErrorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
694         } else {
695                 xapp.Logger.Debug("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v",
696                         errorInfo.ErrorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID)
697         }
698
699         c.UpdateCounter(cRestSubFailNotifToXapp)
700         xapp.Subscription.Notify(resp, *clientEndpoint)
701
702         // E2 is down. Delete completely processed request safely now
703         if c.e2IfState.IsE2ConnectionUp(&restSubscription.Meid) == false && restSubscription.SubReqOngoing == false {
704                 c.registry.DeleteRESTSubscription(restSubId)
705                 c.RemoveRESTSubscriptionFromDb(*restSubId)
706         }
707 }
708
709 //-------------------------------------------------------------------
710 //
711 //-------------------------------------------------------------------
712 func (c *Control) sendSuccesfullResponseNotification(restSubId *string, restSubscription *RESTSubscription, xAppEventInstanceID int64, e2EventInstanceID int64,
713         clientEndpoint *models.SubscriptionParamsClientEndpoint, trans *TransactionXapp) {
714
715         // Store successfully processed InstanceId for deletion
716         restSubscription.AddE2InstanceId((uint32)(e2EventInstanceID))
717         restSubscription.AddXappIdToE2Id(xAppEventInstanceID, e2EventInstanceID)
718
719         // Send notification to xApp that a Subscription Request has been processed.
720         resp := &models.SubscriptionResponse{
721                 SubscriptionID: restSubId,
722                 SubscriptionInstances: []*models.SubscriptionInstance{
723                         &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
724                                 ErrorCause:          "",
725                                 XappEventInstanceID: &xAppEventInstanceID},
726                 },
727         }
728         // Mark REST subscription request processesd.
729         restSubscription.SetProcessed(nil)
730         c.UpdateRESTSubscriptionInDB(*restSubId, restSubscription, false)
731         xapp.Logger.Debug("Sending successful REST notification to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
732                 clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
733
734         c.UpdateCounter(cRestSubNotifToXapp)
735         xapp.Subscription.Notify(resp, *clientEndpoint)
736
737         // E2 is down. Delete completely processed request safely now
738         if c.e2IfState.IsE2ConnectionUp(&restSubscription.Meid) == false && restSubscription.SubReqOngoing == false {
739                 c.registry.DeleteRESTSubscription(restSubId)
740                 c.RemoveRESTSubscriptionFromDb(*restSubId)
741         }
742 }
743
744 //-------------------------------------------------------------------
745 //
746 //-------------------------------------------------------------------
747 func (c *Control) RESTSubscriptionDeleteHandler(restSubId string) int {
748
749         c.CntRecvMsg++
750         c.UpdateCounter(cRestSubDelReqFromXapp)
751
752         xapp.Logger.Debug("SubscriptionDeleteRequest from XAPP")
753
754         restSubscription, err := c.registry.GetRESTSubscription(restSubId, true)
755         if err != nil {
756                 xapp.Logger.Error("%s", err.Error())
757                 if restSubscription == nil {
758                         // Subscription was not found
759                         c.UpdateCounter(cRestSubDelRespToXapp)
760                         return common.UnsubscribeNoContentCode
761                 } else {
762                         if restSubscription.SubReqOngoing == true {
763                                 err := fmt.Errorf("Handling of the REST Subscription Request still ongoing %s", restSubId)
764                                 xapp.Logger.Error("%s", err.Error())
765                                 c.UpdateCounter(cRestSubDelFailToXapp)
766                                 return common.UnsubscribeBadRequestCode
767                         } else if restSubscription.SubDelReqOngoing == true {
768                                 // Previous request for same restSubId still ongoing
769                                 c.UpdateCounter(cRestSubDelRespToXapp)
770                                 return common.UnsubscribeNoContentCode
771                         }
772                 }
773         }
774
775         xAppRmrEndPoint := restSubscription.xAppRmrEndPoint
776         go func() {
777                 xapp.Logger.Debug("Deleteting handler: processing instances = %v", restSubscription.InstanceIds)
778                 for _, instanceId := range restSubscription.InstanceIds {
779                         xAppEventInstanceID, err := c.SubscriptionDeleteHandler(&restSubId, &xAppRmrEndPoint, &restSubscription.Meid, instanceId, 0)
780
781                         if err != nil {
782                                 xapp.Logger.Error("%s", err.Error())
783                         }
784                         xapp.Logger.Debug("Deleteting instanceId = %v", instanceId)
785                         restSubscription.DeleteXappIdToE2Id(xAppEventInstanceID)
786                         restSubscription.DeleteE2InstanceId(instanceId)
787                 }
788                 c.restDuplicateCtrl.DeleteLastKnownRestSubsIdBasedOnMd5sum(restSubscription.lastReqMd5sum)
789                 c.registry.DeleteRESTSubscription(&restSubId)
790                 c.RemoveRESTSubscriptionFromDb(restSubId)
791         }()
792
793         c.UpdateCounter(cRestSubDelRespToXapp)
794         return common.UnsubscribeNoContentCode
795 }
796
797 //-------------------------------------------------------------------
798 //
799 //-------------------------------------------------------------------
800 func (c *Control) SubscriptionDeleteHandler(restSubId *string, endPoint *string, meid *string, instanceId uint32, waitRouteCleanupTime time.Duration) (int64, error) {
801
802         var xAppEventInstanceID int64
803         subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{instanceId})
804         if err != nil {
805                 xapp.Logger.Debug("Subscription Delete Handler subscription for restSubId=%v, E2EventInstanceID=%v not found %s",
806                         restSubId, instanceId, idstring(err, nil))
807                 return xAppEventInstanceID, nil
808         }
809
810         xAppEventInstanceID = int64(subs.ReqId.Id)
811         trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(*endPoint), *restSubId, e2ap.RequestId{subs.ReqId.Id, 0}, &xapp.RMRMeid{RanName: *meid})
812         if trans == nil {
813                 err := fmt.Errorf("XAPP-SubDelReq transaction not created. restSubId %s, endPoint %s, meid %s, instanceId %v", *restSubId, *endPoint, *meid, instanceId)
814                 xapp.Logger.Error("%s", err.Error())
815         }
816         defer trans.Release()
817
818         err = c.tracker.Track(trans)
819         if err != nil {
820                 err := fmt.Errorf("XAPP-SubDelReq %s:", idstring(err, trans))
821                 xapp.Logger.Error("%s", err.Error())
822                 return xAppEventInstanceID, &time.ParseError{}
823         }
824         //
825         // Wake subs delete
826         //
827         subs.OngoingDelCount++
828         go c.handleSubscriptionDelete(subs, trans, waitRouteCleanupTime)
829         trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
830         subs.OngoingDelCount--
831
832         xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs))
833
834         c.registry.RemoveFromSubscription(subs, trans, waitRouteCleanup_ms, c)
835
836         return xAppEventInstanceID, nil
837 }
838
839 //-------------------------------------------------------------------
840 //
841 //-------------------------------------------------------------------
842 func (c *Control) RESTQueryHandler() (models.SubscriptionList, error) {
843         xapp.Logger.Debug("RESTQueryHandler() called")
844
845         c.CntRecvMsg++
846
847         return c.registry.QueryHandler()
848 }
849
850 func (c *Control) TestRestHandler(w http.ResponseWriter, r *http.Request) {
851         xapp.Logger.Debug("RESTTestRestHandler() called")
852
853         pathParams := mux.Vars(r)
854         s := pathParams["testId"]
855
856         // This can be used to delete single subscription from db
857         if contains := strings.Contains(s, "deletesubid="); contains == true {
858                 var splits = strings.Split(s, "=")
859                 if subId, err := strconv.ParseInt(splits[1], 10, 64); err == nil {
860                         xapp.Logger.Debug("RemoveSubscriptionFromSdl() called. subId = %v", subId)
861                         c.RemoveSubscriptionFromSdl(uint32(subId))
862                         return
863                 }
864         }
865
866         // This can be used to remove all subscriptions db from
867         if s == "emptydb" {
868                 xapp.Logger.Debug("RemoveAllSubscriptionsFromSdl() called")
869                 c.RemoveAllSubscriptionsFromSdl()
870                 c.RemoveAllRESTSubscriptionsFromSdl()
871                 return
872         }
873
874         // This is meant to cause submgr's restart in testing
875         if s == "restart" {
876                 xapp.Logger.Debug("os.Exit(1) called")
877                 os.Exit(1)
878         }
879
880         xapp.Logger.Debug("Unsupported rest command received %s", s)
881 }
882
883 //-------------------------------------------------------------------
884 //
885 //-------------------------------------------------------------------
886
887 func (c *Control) rmrSendToE2T(desc string, subs *Subscription, trans *TransactionSubs) (err error) {
888         params := &xapp.RMRParams{}
889         params.Mtype = trans.GetMtype()
890         params.SubId = int(subs.GetReqId().InstanceId)
891         params.Xid = ""
892         params.Meid = subs.GetMeid()
893         params.Src = ""
894         params.PayloadLen = len(trans.Payload.Buf)
895         params.Payload = trans.Payload.Buf
896         params.Mbuf = nil
897         xapp.Logger.Debug("MSG to E2T: %s %s %s", desc, trans.String(), params.String())
898         err = c.SendWithRetry(params, false, 5)
899         if err != nil {
900                 xapp.Logger.Error("rmrSendToE2T: Send failed: %+v", err)
901         }
902         return err
903 }
904
905 func (c *Control) rmrSendToXapp(desc string, subs *Subscription, trans *TransactionXapp) (err error) {
906
907         params := &xapp.RMRParams{}
908         params.Mtype = trans.GetMtype()
909         params.SubId = int(subs.GetReqId().InstanceId)
910         params.Xid = trans.GetXid()
911         params.Meid = trans.GetMeid()
912         params.Src = ""
913         params.PayloadLen = len(trans.Payload.Buf)
914         params.Payload = trans.Payload.Buf
915         params.Mbuf = nil
916         xapp.Logger.Debug("MSG to XAPP: %s %s %s", desc, trans.String(), params.String())
917         err = c.SendWithRetry(params, false, 5)
918         if err != nil {
919                 xapp.Logger.Error("rmrSendToXapp: Send failed: %+v", err)
920         }
921         return err
922 }
923
924 func (c *Control) Consume(msg *xapp.RMRParams) (err error) {
925         if c.RMRClient == nil {
926                 err = fmt.Errorf("Rmr object nil can handle %s", msg.String())
927                 xapp.Logger.Error("%s", err.Error())
928                 return
929         }
930         c.CntRecvMsg++
931
932         defer c.RMRClient.Free(msg.Mbuf)
933
934         // xapp-frame might use direct access to c buffer and
935         // when msg.Mbuf is freed, someone might take it into use
936         // and payload data might be invalid inside message handle function
937         //
938         // subscriptions won't load system a lot so there is no
939         // real performance hit by cloning buffer into new go byte slice
940         cPay := append(msg.Payload[:0:0], msg.Payload...)
941         msg.Payload = cPay
942         msg.PayloadLen = len(cPay)
943
944         switch msg.Mtype {
945         case xapp.RIC_SUB_REQ:
946                 go c.handleXAPPSubscriptionRequest(msg)
947         case xapp.RIC_SUB_RESP:
948                 go c.handleE2TSubscriptionResponse(msg)
949         case xapp.RIC_SUB_FAILURE:
950                 go c.handleE2TSubscriptionFailure(msg)
951         case xapp.RIC_SUB_DEL_REQ:
952                 go c.handleXAPPSubscriptionDeleteRequest(msg)
953         case xapp.RIC_SUB_DEL_RESP:
954                 go c.handleE2TSubscriptionDeleteResponse(msg)
955         case xapp.RIC_SUB_DEL_FAILURE:
956                 go c.handleE2TSubscriptionDeleteFailure(msg)
957         default:
958                 xapp.Logger.Debug("Unknown Message Type '%d', discarding", msg.Mtype)
959         }
960         return
961 }
962
963 //-------------------------------------------------------------------
964 // handle from XAPP Subscription Request
965 //------------------------------------------------------------------
966 func (c *Control) handleXAPPSubscriptionRequest(params *xapp.RMRParams) {
967         xapp.Logger.Debug("MSG from XAPP: %s", params.String())
968         c.UpdateCounter(cSubReqFromXapp)
969
970         if c.e2IfState.IsE2ConnectionUp(&params.Meid.RanName) == false {
971                 xapp.Logger.Error("No E2 connection for ranName %v", params.Meid.RanName)
972                 return
973         }
974
975         subReqMsg, err := c.e2ap.UnpackSubscriptionRequest(params.Payload)
976         if err != nil {
977                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, params))
978                 return
979         }
980
981         trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subReqMsg.RequestId, params.Meid)
982         if trans == nil {
983                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(fmt.Errorf("transaction not created"), params))
984                 return
985         }
986         defer trans.Release()
987
988         if err = c.tracker.Track(trans); err != nil {
989                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
990                 return
991         }
992
993         subs, _, err := c.registry.AssignToSubscription(trans, subReqMsg, c.ResetTestFlag, c, true)
994         if err != nil {
995                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
996                 return
997         }
998
999         c.wakeSubscriptionRequest(subs, trans)
1000 }
1001
1002 //-------------------------------------------------------------------
1003 // Wake Subscription Request to E2node
1004 //------------------------------------------------------------------
1005 func (c *Control) wakeSubscriptionRequest(subs *Subscription, trans *TransactionXapp) {
1006
1007         e2SubscriptionDirectives, _ := c.GetE2SubscriptionDirectives(nil)
1008         subs.OngoingReqCount++
1009         go c.handleSubscriptionCreate(subs, trans, e2SubscriptionDirectives, waitRouteCleanup_ms)
1010         event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
1011         subs.OngoingReqCount--
1012         var err error
1013         if event != nil {
1014                 switch themsg := event.(type) {
1015                 case *e2ap.E2APSubscriptionResponse:
1016                         themsg.RequestId.Id = trans.RequestId.Id
1017                         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionResponse(themsg)
1018                         if err == nil {
1019                                 trans.Release()
1020                                 c.UpdateCounter(cSubRespToXapp)
1021                                 c.rmrSendToXapp("", subs, trans)
1022                                 return
1023                         }
1024                 case *e2ap.E2APSubscriptionFailure:
1025                         themsg.RequestId.Id = trans.RequestId.Id
1026                         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionFailure(themsg)
1027                         if err == nil {
1028                                 c.UpdateCounter(cSubFailToXapp)
1029                                 c.rmrSendToXapp("", subs, trans)
1030                         }
1031                 default:
1032                         break
1033                 }
1034         }
1035         xapp.Logger.Debug("XAPP-SubReq: failed %s", idstring(err, trans, subs))
1036 }
1037
1038 //-------------------------------------------------------------------
1039 // handle from XAPP Subscription Delete Request
1040 //------------------------------------------------------------------
1041 func (c *Control) handleXAPPSubscriptionDeleteRequest(params *xapp.RMRParams) {
1042         xapp.Logger.Debug("MSG from XAPP: %s", params.String())
1043         c.UpdateCounter(cSubDelReqFromXapp)
1044
1045         if c.e2IfState.IsE2ConnectionUp(&params.Meid.RanName) == false {
1046                 xapp.Logger.Error("No E2 connection for ranName %v", params.Meid.RanName)
1047                 return
1048         }
1049
1050         subDelReqMsg, err := c.e2ap.UnpackSubscriptionDeleteRequest(params.Payload)
1051         if err != nil {
1052                 xapp.Logger.Error("XAPP-SubDelReq %s", idstring(err, params))
1053                 return
1054         }
1055
1056         trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subDelReqMsg.RequestId, params.Meid)
1057         if trans == nil {
1058                 xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(fmt.Errorf("transaction not created"), params))
1059                 return
1060         }
1061         defer trans.Release()
1062
1063         err = c.tracker.Track(trans)
1064         if err != nil {
1065                 xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
1066                 return
1067         }
1068
1069         subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{trans.GetSubId()})
1070         if err != nil {
1071                 xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(err, trans))
1072                 return
1073         }
1074
1075         //
1076         // Wake subs delete
1077         //
1078         subs.OngoingDelCount++
1079         go c.handleSubscriptionDelete(subs, trans, waitRouteCleanup_ms)
1080         trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
1081         subs.OngoingDelCount--
1082
1083         xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs))
1084
1085         if subs.NoRespToXapp == true {
1086                 // Do no send delete responses to xapps due to submgr restart is deleting uncompleted subscriptions
1087                 xapp.Logger.Debug("XAPP-SubDelReq: subs.NoRespToXapp == true")
1088                 return
1089         }
1090
1091         // Whatever is received success, fail or timeout, send successful delete response
1092         subDelRespMsg := &e2ap.E2APSubscriptionDeleteResponse{}
1093         subDelRespMsg.RequestId.Id = trans.RequestId.Id
1094         subDelRespMsg.RequestId.InstanceId = subs.GetReqId().RequestId.InstanceId
1095         subDelRespMsg.FunctionId = subs.SubReqMsg.FunctionId
1096         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteResponse(subDelRespMsg)
1097         if err == nil {
1098                 c.UpdateCounter(cSubDelRespToXapp)
1099                 c.rmrSendToXapp("", subs, trans)
1100         }
1101 }
1102
1103 //-------------------------------------------------------------------
1104 // SUBS CREATE Handling
1105 //-------------------------------------------------------------------
1106 func (c *Control) handleSubscriptionCreate(subs *Subscription, parentTrans *TransactionXapp, e2SubscriptionDirectives *E2SubscriptionDirectives, waitRouteCleanupTime time.Duration) {
1107
1108         var event interface{} = nil
1109         var removeSubscriptionFromDb bool = false
1110         trans := c.tracker.NewSubsTransaction(subs)
1111         subs.WaitTransactionTurn(trans)
1112         defer subs.ReleaseTransactionTurn(trans)
1113         defer trans.Release()
1114
1115         xapp.Logger.Debug("SUBS-SubReq: Handling %s ", idstring(nil, trans, subs, parentTrans))
1116
1117         subRfMsg, valid := subs.GetCachedResponse()
1118         if subRfMsg == nil && valid == true {
1119                 event = c.sendE2TSubscriptionRequest(subs, trans, parentTrans, e2SubscriptionDirectives)
1120                 switch event.(type) {
1121                 case *e2ap.E2APSubscriptionResponse:
1122                         subRfMsg, valid = subs.SetCachedResponse(event, true)
1123                         subs.SubRespRcvd = true
1124                 case *e2ap.E2APSubscriptionFailure:
1125                         subRfMsg, valid = subs.SetCachedResponse(event, false)
1126                         xapp.Logger.Debug("SUBS-SubReq: internal delete due failure event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
1127                 case *SubmgrRestartTestEvent:
1128                         // This is used to simulate that no response has been received and after restart, subscriptions are restored from db
1129                         xapp.Logger.Debug("Test restart flag is active. Dropping this transaction to test restart case")
1130                         subRfMsg, valid = subs.SetCachedResponse(event, false)
1131                         parentTrans.SendEvent(subRfMsg, 0)
1132                         return
1133                 case *PackSubscriptionRequestErrortEvent, *SDLWriteErrortEvent:
1134                         subRfMsg, valid = subs.SetCachedResponse(event, false)
1135                 default:
1136                         // Timer expiry
1137                         if subs.PolicyUpdate == false {
1138                                 xapp.Logger.Debug("SUBS-SubReq: internal delete due default event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
1139                                 subRfMsg, valid = subs.SetCachedResponse(nil, false)
1140                                 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
1141                         } else {
1142                                 subRfMsg, valid = subs.SetCachedResponse(nil, true)
1143                         }
1144                 }
1145                 xapp.Logger.Debug("SUBS-SubReq: Handling (e2t response %s) %s", typeofSubsMessage(subRfMsg), idstring(nil, trans, subs, parentTrans))
1146         } else {
1147                 xapp.Logger.Debug("SUBS-SubReq: Handling (cached response %s) %s", typeofSubsMessage(subRfMsg), idstring(nil, trans, subs, parentTrans))
1148         }
1149         if valid == false {
1150                 removeSubscriptionFromDb = true
1151         }
1152
1153         err := c.UpdateSubscriptionInDB(subs, removeSubscriptionFromDb)
1154         if err != nil {
1155                 valid = false
1156                 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
1157         }
1158
1159         // Now RemoveFromSubscription in here to avoid race conditions (mostly concerns delete)
1160         if valid == false {
1161                 c.registry.RemoveFromSubscription(subs, parentTrans, waitRouteCleanupTime, c)
1162         }
1163
1164         parentTrans.SendEvent(subRfMsg, 0)
1165 }
1166
1167 //-------------------------------------------------------------------
1168 // SUBS DELETE Handling
1169 //-------------------------------------------------------------------
1170
1171 func (c *Control) handleSubscriptionDelete(subs *Subscription, parentTrans *TransactionXapp, waitRouteCleanupTime time.Duration) {
1172
1173         trans := c.tracker.NewSubsTransaction(subs)
1174         subs.WaitTransactionTurn(trans)
1175         defer subs.ReleaseTransactionTurn(trans)
1176         defer trans.Release()
1177
1178         xapp.Logger.Debug("SUBS-SubDelReq: Handling %s", idstring(nil, trans, subs, parentTrans))
1179
1180         subs.mutex.Lock()
1181
1182         if subs.valid && subs.EpList.HasEndpoint(parentTrans.GetEndpoint()) && subs.EpList.Size() == 1 {
1183                 subs.valid = false
1184                 subs.mutex.Unlock()
1185                 c.sendE2TSubscriptionDeleteRequest(subs, trans, parentTrans)
1186         } else {
1187                 subs.mutex.Unlock()
1188         }
1189
1190         // Now RemoveFromSubscription in here to avoid race conditions (mostly concerns delete)
1191         c.registry.RemoveFromSubscription(subs, parentTrans, waitRouteCleanupTime, c)
1192         parentTrans.SendEvent(nil, 0)
1193 }
1194
1195 //-------------------------------------------------------------------
1196 // send to E2T Subscription Request
1197 //-------------------------------------------------------------------
1198 func (c *Control) sendE2TSubscriptionRequest(subs *Subscription, trans *TransactionSubs, parentTrans *TransactionXapp, e2SubscriptionDirectives *E2SubscriptionDirectives) interface{} {
1199         var err error
1200         var event interface{} = nil
1201         var timedOut bool = false
1202         const ricRequestorId = 123
1203
1204         subReqMsg := subs.SubReqMsg
1205         subReqMsg.RequestId = subs.GetReqId().RequestId
1206         subReqMsg.RequestId.Id = ricRequestorId
1207         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionRequest(subReqMsg)
1208         if err != nil {
1209                 xapp.Logger.Error("SUBS-SubReq ASN1 pack error: %s", idstring(err, trans, subs, parentTrans))
1210                 return &PackSubscriptionRequestErrortEvent{
1211                         ErrorInfo{
1212                                 ErrorSource: models.SubscriptionInstanceErrorSourceASN1,
1213                                 ErrorCause:  err.Error(),
1214                         },
1215                 }
1216         }
1217
1218         // Write uncompleted subscrition in db. If no response for subscrition it need to be re-processed (deleted) after restart
1219         err = c.WriteSubscriptionToDb(subs)
1220         if err != nil {
1221                 return &SDLWriteErrortEvent{
1222                         ErrorInfo{
1223                                 ErrorSource: models.SubscriptionInstanceErrorSourceDBAAS,
1224                                 ErrorCause:  err.Error(),
1225                         },
1226                 }
1227         }
1228
1229         for retries := int64(0); retries < e2SubscriptionDirectives.E2MaxTryCount; retries++ {
1230                 desc := fmt.Sprintf("(retry %d)", retries)
1231                 if retries == 0 {
1232                         c.UpdateCounter(cSubReqToE2)
1233                 } else {
1234                         c.UpdateCounter(cSubReReqToE2)
1235                 }
1236                 c.rmrSendToE2T(desc, subs, trans)
1237                 if subs.DoNotWaitSubResp == false {
1238                         event, timedOut = trans.WaitEvent(e2SubscriptionDirectives.E2TimeoutTimerValue)
1239                         if timedOut {
1240                                 c.UpdateCounter(cSubReqTimerExpiry)
1241                                 continue
1242                         }
1243                 } else {
1244                         // Simulating case where subscrition request has been sent but response has not been received before restart
1245                         event = &SubmgrRestartTestEvent{}
1246                         xapp.Logger.Debug("Restart event, DoNotWaitSubResp == true")
1247                 }
1248                 break
1249         }
1250         xapp.Logger.Debug("SUBS-SubReq: Response handling event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
1251         return event
1252 }
1253
1254 //-------------------------------------------------------------------
1255 // send to E2T Subscription Delete Request
1256 //-------------------------------------------------------------------
1257
1258 func (c *Control) sendE2TSubscriptionDeleteRequest(subs *Subscription, trans *TransactionSubs, parentTrans *TransactionXapp) interface{} {
1259         var err error
1260         var event interface{}
1261         var timedOut bool
1262         const ricRequestorId = 123
1263
1264         subDelReqMsg := &e2ap.E2APSubscriptionDeleteRequest{}
1265         subDelReqMsg.RequestId = subs.GetReqId().RequestId
1266         subDelReqMsg.RequestId.Id = ricRequestorId
1267         subDelReqMsg.FunctionId = subs.SubReqMsg.FunctionId
1268         trans.Mtype, trans.Payload, err = c.e2ap.PackSubscriptionDeleteRequest(subDelReqMsg)
1269         if err != nil {
1270                 xapp.Logger.Error("SUBS-SubDelReq: %s", idstring(err, trans, subs, parentTrans))
1271                 return event
1272         }
1273
1274         for retries := uint64(0); retries < e2tMaxSubDelReqTryCount; retries++ {
1275                 desc := fmt.Sprintf("(retry %d)", retries)
1276                 if retries == 0 {
1277                         c.UpdateCounter(cSubDelReqToE2)
1278                 } else {
1279                         c.UpdateCounter(cSubDelReReqToE2)
1280                 }
1281                 c.rmrSendToE2T(desc, subs, trans)
1282                 event, timedOut = trans.WaitEvent(e2tSubDelReqTime)
1283                 if timedOut {
1284                         c.UpdateCounter(cSubDelReqTimerExpiry)
1285                         continue
1286                 }
1287                 break
1288         }
1289         xapp.Logger.Debug("SUBS-SubDelReq: Response handling event(%s) %s", typeofSubsMessage(event), idstring(nil, trans, subs, parentTrans))
1290         return event
1291 }
1292
1293 //-------------------------------------------------------------------
1294 // handle from E2T Subscription Response
1295 //-------------------------------------------------------------------
1296 func (c *Control) handleE2TSubscriptionResponse(params *xapp.RMRParams) {
1297         xapp.Logger.Debug("MSG from E2T: %s", params.String())
1298         c.UpdateCounter(cSubRespFromE2)
1299
1300         subRespMsg, err := c.e2ap.UnpackSubscriptionResponse(params.Payload)
1301         if err != nil {
1302                 xapp.Logger.Error("MSG-SubResp %s", idstring(err, params))
1303                 return
1304         }
1305         subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subRespMsg.RequestId.InstanceId})
1306         if err != nil {
1307                 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, params))
1308                 return
1309         }
1310         trans := subs.GetTransaction()
1311         if trans == nil {
1312                 err = fmt.Errorf("Ongoing transaction not found")
1313                 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, params, subs))
1314                 return
1315         }
1316         xapp.Logger.Debug("SUBS-SubResp: Sending event, trans= %v", trans)
1317         sendOk, timedOut := trans.SendEvent(subRespMsg, e2tRecvMsgTimeout)
1318         if sendOk == false {
1319                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
1320                 xapp.Logger.Error("MSG-SubResp: %s", idstring(err, trans, subs))
1321         }
1322         return
1323 }
1324
1325 //-------------------------------------------------------------------
1326 // handle from E2T Subscription Failure
1327 //-------------------------------------------------------------------
1328 func (c *Control) handleE2TSubscriptionFailure(params *xapp.RMRParams) {
1329         xapp.Logger.Debug("MSG from E2T: %s", params.String())
1330         c.UpdateCounter(cSubFailFromE2)
1331         subFailMsg, err := c.e2ap.UnpackSubscriptionFailure(params.Payload)
1332         if err != nil {
1333                 xapp.Logger.Error("MSG-SubFail %s", idstring(err, params))
1334                 return
1335         }
1336         subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subFailMsg.RequestId.InstanceId})
1337         if err != nil {
1338                 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, params))
1339                 return
1340         }
1341         trans := subs.GetTransaction()
1342         if trans == nil {
1343                 err = fmt.Errorf("Ongoing transaction not found")
1344                 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, params, subs))
1345                 return
1346         }
1347         sendOk, timedOut := trans.SendEvent(subFailMsg, e2tRecvMsgTimeout)
1348         if sendOk == false {
1349                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
1350                 xapp.Logger.Error("MSG-SubFail: %s", idstring(err, trans, subs))
1351         }
1352         return
1353 }
1354
1355 //-------------------------------------------------------------------
1356 // handle from E2T Subscription Delete Response
1357 //-------------------------------------------------------------------
1358 func (c *Control) handleE2TSubscriptionDeleteResponse(params *xapp.RMRParams) (err error) {
1359         xapp.Logger.Debug("MSG from E2T: %s", params.String())
1360         c.UpdateCounter(cSubDelRespFromE2)
1361         subDelRespMsg, err := c.e2ap.UnpackSubscriptionDeleteResponse(params.Payload)
1362         if err != nil {
1363                 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params))
1364                 return
1365         }
1366         subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subDelRespMsg.RequestId.InstanceId})
1367         if err != nil {
1368                 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params))
1369                 return
1370         }
1371         trans := subs.GetTransaction()
1372         if trans == nil {
1373                 err = fmt.Errorf("Ongoing transaction not found")
1374                 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, params, subs))
1375                 return
1376         }
1377         sendOk, timedOut := trans.SendEvent(subDelRespMsg, e2tRecvMsgTimeout)
1378         if sendOk == false {
1379                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
1380                 xapp.Logger.Error("MSG-SubDelResp: %s", idstring(err, trans, subs))
1381         }
1382         return
1383 }
1384
1385 //-------------------------------------------------------------------
1386 // handle from E2T Subscription Delete Failure
1387 //-------------------------------------------------------------------
1388 func (c *Control) handleE2TSubscriptionDeleteFailure(params *xapp.RMRParams) {
1389         xapp.Logger.Debug("MSG from E2T: %s", params.String())
1390         c.UpdateCounter(cSubDelFailFromE2)
1391         subDelFailMsg, err := c.e2ap.UnpackSubscriptionDeleteFailure(params.Payload)
1392         if err != nil {
1393                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params))
1394                 return
1395         }
1396         subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subDelFailMsg.RequestId.InstanceId})
1397         if err != nil {
1398                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params))
1399                 return
1400         }
1401         trans := subs.GetTransaction()
1402         if trans == nil {
1403                 err = fmt.Errorf("Ongoing transaction not found")
1404                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params, subs))
1405                 return
1406         }
1407         sendOk, timedOut := trans.SendEvent(subDelFailMsg, e2tRecvMsgTimeout)
1408         if sendOk == false {
1409                 err = fmt.Errorf("Passing event to transaction failed: sendOk(%t) timedOut(%t)", sendOk, timedOut)
1410                 xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, trans, subs))
1411         }
1412         return
1413 }
1414
1415 //-------------------------------------------------------------------
1416 //
1417 //-------------------------------------------------------------------
1418 func typeofSubsMessage(v interface{}) string {
1419         if v == nil {
1420                 return "NIL"
1421         }
1422         switch v.(type) {
1423         //case *e2ap.E2APSubscriptionRequest:
1424         //      return "SubReq"
1425         case *e2ap.E2APSubscriptionResponse:
1426                 return "SubResp"
1427         case *e2ap.E2APSubscriptionFailure:
1428                 return "SubFail"
1429         //case *e2ap.E2APSubscriptionDeleteRequest:
1430         //      return "SubDelReq"
1431         case *e2ap.E2APSubscriptionDeleteResponse:
1432                 return "SubDelResp"
1433         case *e2ap.E2APSubscriptionDeleteFailure:
1434                 return "SubDelFail"
1435         default:
1436                 return "Unknown"
1437         }
1438 }
1439
1440 //-------------------------------------------------------------------
1441 //
1442 //-------------------------------------------------------------------
1443 func (c *Control) WriteSubscriptionToDb(subs *Subscription) error {
1444         xapp.Logger.Debug("WriteSubscriptionToDb() subId = %v", subs.ReqId.InstanceId)
1445         err := c.WriteSubscriptionToSdl(subs.ReqId.InstanceId, subs)
1446         if err != nil {
1447                 xapp.Logger.Error("%v", err)
1448                 return err
1449         }
1450         return nil
1451 }
1452
1453 //-------------------------------------------------------------------
1454 //
1455 //-------------------------------------------------------------------
1456 func (c *Control) UpdateSubscriptionInDB(subs *Subscription, removeSubscriptionFromDb bool) error {
1457
1458         if removeSubscriptionFromDb == true {
1459                 // Subscription was written in db already when subscription request was sent to BTS, except for merged request
1460                 c.RemoveSubscriptionFromDb(subs)
1461         } else {
1462                 // Update is needed for successful response and merge case here
1463                 if subs.RetryFromXapp == false {
1464                         err := c.WriteSubscriptionToDb(subs)
1465                         return err
1466                 }
1467         }
1468         subs.RetryFromXapp = false
1469         return nil
1470 }
1471
1472 //-------------------------------------------------------------------
1473 //
1474 //-------------------------------------------------------------------
1475 func (c *Control) RemoveSubscriptionFromDb(subs *Subscription) {
1476         xapp.Logger.Debug("RemoveSubscriptionFromDb() subId = %v", subs.ReqId.InstanceId)
1477         err := c.RemoveSubscriptionFromSdl(subs.ReqId.InstanceId)
1478         if err != nil {
1479                 xapp.Logger.Error("%v", err)
1480         }
1481 }
1482
1483 //-------------------------------------------------------------------
1484 //
1485 //-------------------------------------------------------------------
1486 func (c *Control) WriteRESTSubscriptionToDb(restSubId string, restSubs *RESTSubscription) {
1487         xapp.Logger.Debug("WriteRESTSubscriptionToDb() restSubId = %s", restSubId)
1488         err := c.WriteRESTSubscriptionToSdl(restSubId, restSubs)
1489         if err != nil {
1490                 xapp.Logger.Error("%v", err)
1491         }
1492 }
1493
1494 //-------------------------------------------------------------------
1495 //
1496 //-------------------------------------------------------------------
1497 func (c *Control) UpdateRESTSubscriptionInDB(restSubId string, restSubs *RESTSubscription, removeRestSubscriptionFromDb bool) {
1498
1499         if removeRestSubscriptionFromDb == true {
1500                 // Subscription was written in db already when subscription request was sent to BTS, except for merged request
1501                 c.RemoveRESTSubscriptionFromDb(restSubId)
1502         } else {
1503                 c.WriteRESTSubscriptionToDb(restSubId, restSubs)
1504         }
1505 }
1506
1507 //-------------------------------------------------------------------
1508 //
1509 //-------------------------------------------------------------------
1510 func (c *Control) RemoveRESTSubscriptionFromDb(restSubId string) {
1511         xapp.Logger.Debug("RemoveRESTSubscriptionFromDb() restSubId = %s", restSubId)
1512         err := c.RemoveRESTSubscriptionFromSdl(restSubId)
1513         if err != nil {
1514                 xapp.Logger.Error("%v", err)
1515         }
1516 }
1517
1518 func (c *Control) SendSubscriptionDeleteReq(subs *Subscription) {
1519
1520         if c.UTTesting == true {
1521                 // Reqistry mutex is not locked after real restart but it can be when restart is simulated in unit tests
1522                 c.registry.mutex = new(sync.Mutex)
1523         }
1524
1525         const ricRequestorId = 123
1526         xapp.Logger.Debug("Sending subscription delete due to restart. subId = %v", subs.ReqId.InstanceId)
1527
1528         // Send delete for every endpoint in the subscription
1529         if subs.PolicyUpdate == false {
1530                 subDelReqMsg := &e2ap.E2APSubscriptionDeleteRequest{}
1531                 subDelReqMsg.RequestId = subs.GetReqId().RequestId
1532                 subDelReqMsg.RequestId.Id = ricRequestorId
1533                 subDelReqMsg.FunctionId = subs.SubReqMsg.FunctionId
1534                 mType, payload, err := c.e2ap.PackSubscriptionDeleteRequest(subDelReqMsg)
1535                 if err != nil {
1536                         xapp.Logger.Error("SendSubscriptionDeleteReq() %s", idstring(err))
1537                         return
1538                 }
1539                 for _, endPoint := range subs.EpList.Endpoints {
1540                         params := &xapp.RMRParams{}
1541                         params.Mtype = mType
1542                         params.SubId = int(subs.GetReqId().InstanceId)
1543                         params.Xid = ""
1544                         params.Meid = subs.Meid
1545                         params.Src = endPoint.String()
1546                         params.PayloadLen = len(payload.Buf)
1547                         params.Payload = payload.Buf
1548                         params.Mbuf = nil
1549                         subs.DeleteFromDb = true
1550                         c.handleXAPPSubscriptionDeleteRequest(params)
1551                 }
1552         }
1553 }
1554
1555 func (c *Control) PrintRESTSubscriptionRequest(p *models.SubscriptionParams) {
1556
1557         fmt.Println("CRESTSubscriptionRequest")
1558
1559         if p == nil {
1560                 return
1561         }
1562
1563         if p.SubscriptionID != "" {
1564                 fmt.Println("  SubscriptionID = ", p.SubscriptionID)
1565         } else {
1566                 fmt.Println("  SubscriptionID = ''")
1567         }
1568
1569         fmt.Printf("  ClientEndpoint.Host = %s\n", p.ClientEndpoint.Host)
1570
1571         if p.ClientEndpoint.HTTPPort != nil {
1572                 fmt.Printf("  ClientEndpoint.HTTPPort = %v\n", *p.ClientEndpoint.HTTPPort)
1573         } else {
1574                 fmt.Println("  ClientEndpoint.HTTPPort = nil")
1575         }
1576
1577         if p.ClientEndpoint.RMRPort != nil {
1578                 fmt.Printf("  ClientEndpoint.RMRPort = %v\n", *p.ClientEndpoint.RMRPort)
1579         } else {
1580                 fmt.Println("  ClientEndpoint.RMRPort = nil")
1581         }
1582
1583         if p.Meid != nil {
1584                 fmt.Printf("  Meid = %s\n", *p.Meid)
1585         } else {
1586                 fmt.Println("  Meid = nil")
1587         }
1588
1589         if p.E2SubscriptionDirectives == nil {
1590                 fmt.Println("  E2SubscriptionDirectives = nil")
1591         } else {
1592                 fmt.Println("  E2SubscriptionDirectives")
1593                 if p.E2SubscriptionDirectives.E2RetryCount == nil {
1594                         fmt.Println("    E2RetryCount == nil")
1595                 } else {
1596                         fmt.Printf("    E2RetryCount = %v\n", *p.E2SubscriptionDirectives.E2RetryCount)
1597                 }
1598                 fmt.Printf("    E2TimeoutTimerValue = %v\n", p.E2SubscriptionDirectives.E2TimeoutTimerValue)
1599                 fmt.Printf("    RMRRoutingNeeded = %v\n", p.E2SubscriptionDirectives.RMRRoutingNeeded)
1600         }
1601         for _, subscriptionDetail := range p.SubscriptionDetails {
1602                 if p.RANFunctionID != nil {
1603                         fmt.Printf("  RANFunctionID = %v\n", *p.RANFunctionID)
1604                 } else {
1605                         fmt.Println("  RANFunctionID = nil")
1606                 }
1607                 fmt.Printf("  SubscriptionDetail.XappEventInstanceID = %v\n", *subscriptionDetail.XappEventInstanceID)
1608                 fmt.Printf("  SubscriptionDetail.EventTriggers = %v\n", subscriptionDetail.EventTriggers)
1609
1610                 for _, actionToBeSetup := range subscriptionDetail.ActionToBeSetupList {
1611                         fmt.Printf("  SubscriptionDetail.ActionToBeSetup.ActionID = %v\n", *actionToBeSetup.ActionID)
1612                         fmt.Printf("  SubscriptionDetail.ActionToBeSetup.ActionType = %s\n", *actionToBeSetup.ActionType)
1613                         fmt.Printf("  SubscriptionDetail.ActionToBeSetup.ActionDefinition = %v\n", actionToBeSetup.ActionDefinition)
1614
1615                         if actionToBeSetup.SubsequentAction != nil {
1616                                 fmt.Printf("  SubscriptionDetail.ActionToBeSetup.SubsequentAction.SubsequentActionType = %s\n", *actionToBeSetup.SubsequentAction.SubsequentActionType)
1617                                 fmt.Printf("  SubscriptionDetail.ActionToBeSetup..SubsequentAction.TimeToWait = %s\n", *actionToBeSetup.SubsequentAction.TimeToWait)
1618                         } else {
1619                                 fmt.Println("  SubscriptionDetail.ActionToBeSetup.SubsequentAction = nil")
1620                         }
1621                 }
1622         }
1623 }