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