+//-------------------------------------------------------------------
+//
+//------------------------------------------------------------------
+func (c *Control) SubscriptionProcessingStartDelay() {
+ if c.UTTesting == true {
+ // This is temporary fix for the UT problem that notification arrives before subscription response
+ // Correct fix would be to allow notification come before response and process it correctly
+ xapp.Logger.Debug("Setting 50 ms delay before starting processing Subscriptions")
+ <-time.After(time.Millisecond * 50)
+ xapp.Logger.Debug("Continuing after delay")
+ }
+}
+
+//-------------------------------------------------------------------
+//
+//------------------------------------------------------------------
+func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e2ap.E2APSubscriptionRequest, meid *string,
+ restSubId string, e2SubscriptionDirectives *E2SubscriptionDirectives) (*e2ap.E2APSubscriptionResponse, *ErrorInfo, error) {
+
+ errorInfo := ErrorInfo{}
+
+ err := c.tracker.Track(trans)
+ if err != nil {
+ xapp.Logger.Error("XAPP-SubReq Tracking error: %s", idstring(err, trans))
+ errorInfo.ErrorCause = err.Error()
+ err = fmt.Errorf("Tracking failure")
+ return nil, &errorInfo, err
+ }
+
+ subs, errorInfo, err := c.registry.AssignToSubscription(trans, subReqMsg, c.ResetTestFlag, c, e2SubscriptionDirectives.CreateRMRRoute)
+ if err != nil {
+ xapp.Logger.Error("XAPP-SubReq Assign error: %s", idstring(err, trans))
+ return nil, &errorInfo, err
+ }
+
+ //
+ // Wake subs request
+ //
+ subs.OngoingReqCount++
+ go c.handleSubscriptionCreate(subs, trans, e2SubscriptionDirectives, 0)
+ event, _ := trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
+ subs.OngoingReqCount--
+
+ err = nil
+ if event != nil {
+ switch themsg := event.(type) {
+ case *e2ap.E2APSubscriptionResponse:
+ trans.Release()
+ if c.e2IfState.IsE2ConnectionUp(meid) == true {
+ errorInfo = c.e2ap.CheckActionNotAdmittedList(xapp.RIC_SUB_RESP, themsg.ActionNotAdmittedList, c)
+ return themsg, &errorInfo, nil
+ } else {
+ c.registry.RemoveFromSubscription(subs, trans, waitRouteCleanup_ms, c)
+ c.RemoveSubscriptionFromDb(subs)
+ err = fmt.Errorf("E2 interface down")
+ errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
+ }
+ case *e2ap.E2APSubscriptionFailure:
+ err = fmt.Errorf("RICSubscriptionFailure. E2NodeCause: (Cause:%v, Value %v)", themsg.Cause.Content, themsg.Cause.Value)
+ errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
+ case *PackSubscriptionRequestErrortEvent:
+ err = fmt.Errorf("E2 RICSubscriptionRequest pack failure")
+ errorInfo = themsg.ErrorInfo
+ case *SDLWriteErrortEvent:
+ err = fmt.Errorf("SDL write failure")
+ errorInfo = themsg.ErrorInfo
+ case *SubmgrRestartTestEvent:
+ err = fmt.Errorf("TEST: restart event received")
+ xapp.Logger.Debug("%s", err)
+ return nil, &errorInfo, err
+ default:
+ err = fmt.Errorf("Unexpected E2 subscription response received")
+ errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
+ break
+ }
+ } else {
+ // Timer expiry
+ err = fmt.Errorf("E2 RICSubscriptionResponse timeout")
+ errorInfo.SetInfo(err.Error(), "", models.SubscriptionInstanceTimeoutTypeE2Timeout)
+ if subs.PolicyUpdate == true {
+ return nil, &errorInfo, err
+ }
+ }
+
+ xapp.Logger.Error("XAPP-SubReq E2 subscription failed: %s", idstring(err, trans, subs))
+ // If policy type subscription fails we cannot remove it only internally. Once subscription has been created
+ // successfully, it must be deleted on both sides.
+ if subs.PolicyUpdate == false {
+ c.registry.RemoveFromSubscription(subs, trans, waitRouteCleanup_ms, c)
+ }
+
+ return nil, &errorInfo, err
+}
+
+//-------------------------------------------------------------------
+//
+//-------------------------------------------------------------------
+func (c *Control) sendUnsuccesfullResponseNotification(restSubId *string, restSubscription *RESTSubscription, xAppEventInstanceID int64, err error,
+ clientEndpoint *models.SubscriptionParamsClientEndpoint, trans *TransactionXapp, errorInfo *ErrorInfo) {
+
+ // Send notification to xApp that prosessing of a Subscription Request has failed.
+ e2EventInstanceID := (int64)(0)
+ if errorInfo.ErrorSource == "" {
+ // Submgr is default source of error
+ errorInfo.ErrorSource = models.SubscriptionInstanceErrorSourceSUBMGR
+ }
+ resp := &models.SubscriptionResponse{
+ SubscriptionID: restSubId,
+ SubscriptionInstances: []*models.SubscriptionInstance{
+ &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
+ ErrorCause: errorInfo.ErrorCause,
+ ErrorSource: errorInfo.ErrorSource,
+ TimeoutType: errorInfo.TimeoutType,
+ XappEventInstanceID: &xAppEventInstanceID},
+ },
+ }
+ // Mark REST subscription request processed.
+ restSubscription.SetProcessed(err)
+ c.UpdateRESTSubscriptionInDB(*restSubId, restSubscription, false)
+ if trans != nil {
+ xapp.Logger.Debug("Sending unsuccessful REST notification: ErrorCause:%s, ErrorSource:%s, TimeoutType:%s, to Endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
+ errorInfo.ErrorCause, errorInfo.ErrorSource, errorInfo.TimeoutType, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
+ } else {
+ xapp.Logger.Debug("Sending unsuccessful REST notification: ErrorCause:%s, ErrorSource:%s, TimeoutType:%s, to Endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v",
+ errorInfo.ErrorCause, errorInfo.ErrorSource, errorInfo.TimeoutType, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID)
+ }
+
+ c.UpdateCounter(cRestSubFailNotifToXapp)
+ err = xapp.Subscription.Notify(resp, *clientEndpoint)
+ if err != nil {
+ xapp.Logger.Error("xapp.Subscription.Notify failed %s", err.Error())