Added handing for ActionNotAdmittedList 10/7610/1
authorAnssi Mannila <anssi.mannila@nokia.com>
Mon, 24 Jan 2022 11:26:42 +0000 (13:26 +0200)
committerAnssi Mannila <anssi.mannila@nokia.com>
Mon, 24 Jan 2022 11:28:22 +0000 (13:28 +0200)
- REST interfase lacks ActionNotAdmittedList IE
- Added workaroud for that
- Document updated also

Change-Id: I9701fae7319d668412ebcb667c61837612b448a3
Signed-off-by: Anssi Mannila <anssi.mannila@nokia.com>
docs/user-guide.rst
pkg/control/control.go
pkg/control/e2ap.go
pkg/control/metrics.go
pkg/control/metrics_test.go
pkg/control/ut_messaging_test.go
pkg/teststube2ap/stubE2.go

index 08b72b9..a32e6f5 100755 (executable)
@@ -381,6 +381,7 @@ Metrics
                - SubReqToE2: The total number of SubscriptionRequest messages sent to E2Term
                - SubReReqToE2: The total number of SubscriptionRequest messages resent to E2Term
                - SubRespFromE2: The total number of SubscriptionResponse messages from E2Term
+               - PartialSubRespFromE2: The total number of partial SubscriptionResponse messages from E2Term
                - SubFailFromE2: The total number of SubscriptionFailure messages from E2Term
                - SubReqTimerExpiry: The total number of SubscriptionRequest timer expires
                - RouteCreateFail: The total number of subscription route create failure
@@ -629,3 +630,17 @@ Recommendations for xApps
      all E2 subscriptions sent in REST subscription request. Maximum time to complete all E2 subscriptions in Subscription Manager can be calculated like this:
      t >= 3 * 2s * count_of_subscriptions in the REST request. Length of supervising timers in Subscription Manager for the requests it sends to E2 Node is by
      default 2 seconds. There can be only one ongoing E2 subscription request towards per E2 Node other requests are queued in Subscription Manager.
+
+Special notes
+-------------
+ According to E2 specification E2Node may accept subscription partially. This in not properly supported in REST interface between xApp and Subscription Manager.
+ The interface specification yaml lacks ActionNotAdmittedList IE for RICSubscriptionResponse and RICSubscriptionFailure messages. That information in now embedded as
+ workaround in the descriptive error string as a valid JSON string. Missing ActionNotAdmittedList will be added in the REST interface in some coming update.
+
+ Example descriptive error string for RICSubscriptionResponse:
+
+   Error cause RICSubscriptionResponse partially accepted: ActionNotAdmittedList: [{\"ActionId\":1,\"Cause\":{\"Content\":1,\"Value\":8}}]
+
+ Example descriptive error string for RICSubscriptionFailure:
+
+   Error cause RICSubscriptionFailure: ActionNotAdmittedList: [{\"ActionId\":1,\"Cause\":{\"Content\":5,\"Value\":1}}]
\ No newline at end of file
index 42c639b..d4079c1 100755 (executable)
@@ -578,7 +578,7 @@ func (c *Control) processSubscriptionRequests(restSubscription *RESTSubscription
                        restSubscription.AddMd5Sum(md5sum)
                        xapp.Logger.Debug("SubscriptionRequest index=%v processed successfullyfor %s. endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
                                index, *restSubId, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
-                       c.sendSuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, e2EventInstanceID, clientEndpoint, trans)
+                       c.sendSuccesfullResponseNotification(restSubId, restSubscription, xAppEventInstanceID, e2EventInstanceID, clientEndpoint, trans, errorInfo)
                }
        }
 }
@@ -632,6 +632,7 @@ func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e
                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)
@@ -640,10 +641,10 @@ func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e
                                errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
                        }
                case *e2ap.E2APSubscriptionFailure:
-                       err = fmt.Errorf("E2 SubscriptionFailure received")
-                       errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
+                       err = fmt.Errorf("E2 RICSubscriptionFailure received")
+                       errorInfo = c.e2ap.CheckActionNotAdmittedList(xapp.RIC_SUB_FAILURE, themsg.ActionNotAdmittedList, c)
                case *PackSubscriptionRequestErrortEvent:
-                       err = fmt.Errorf("E2 SubscriptionRequest pack failure")
+                       err = fmt.Errorf("E2 RICSubscriptionRequest pack failure")
                        errorInfo = themsg.ErrorInfo
                case *SDLWriteErrortEvent:
                        err = fmt.Errorf("SDL write failure")
@@ -659,7 +660,7 @@ func (c *Control) handleSubscriptionRequest(trans *TransactionXapp, subReqMsg *e
                }
        } else {
                // Timer expiry
-               err = fmt.Errorf("E2 subscription response timeout")
+               err = fmt.Errorf("E2 RICSubscriptionResponse timeout")
                errorInfo.SetInfo(err.Error(), "", models.SubscriptionInstanceTimeoutTypeE2Timeout)
                if subs.PolicyUpdate == true {
                        return nil, &errorInfo, err
@@ -697,10 +698,10 @@ func (c *Control) sendUnsuccesfullResponseNotification(restSubId *string, restSu
        restSubscription.SetProcessed(err)
        c.UpdateRESTSubscriptionInDB(*restSubId, restSubscription, false)
        if trans != nil {
-               xapp.Logger.Debug("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
+               xapp.Logger.Debug("Sending unsuccessful REST notification (Error cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
                        errorInfo.ErrorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
        } else {
-               xapp.Logger.Debug("Sending unsuccessful REST notification (cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v",
+               xapp.Logger.Debug("Sending unsuccessful REST notification (Error cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v",
                        errorInfo.ErrorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID)
        }
 
@@ -718,7 +719,7 @@ func (c *Control) sendUnsuccesfullResponseNotification(restSubId *string, restSu
 //
 //-------------------------------------------------------------------
 func (c *Control) sendSuccesfullResponseNotification(restSubId *string, restSubscription *RESTSubscription, xAppEventInstanceID int64, e2EventInstanceID int64,
-       clientEndpoint *models.SubscriptionParamsClientEndpoint, trans *TransactionXapp) {
+       clientEndpoint *models.SubscriptionParamsClientEndpoint, trans *TransactionXapp, errorInfo *ErrorInfo) {
 
        // Store successfully processed InstanceId for deletion
        restSubscription.AddE2InstanceId((uint32)(e2EventInstanceID))
@@ -729,16 +730,21 @@ func (c *Control) sendSuccesfullResponseNotification(restSubId *string, restSubs
                SubscriptionID: restSubId,
                SubscriptionInstances: []*models.SubscriptionInstance{
                        &models.SubscriptionInstance{E2EventInstanceID: &e2EventInstanceID,
-                               ErrorCause:          "",
+                               ErrorCause:          errorInfo.ErrorCause,
+                               ErrorSource:         errorInfo.ErrorSource,
                                XappEventInstanceID: &xAppEventInstanceID},
                },
        }
        // Mark REST subscription request processesd.
        restSubscription.SetProcessed(nil)
        c.UpdateRESTSubscriptionInDB(*restSubId, restSubscription, false)
-       xapp.Logger.Debug("Sending successful REST notification to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
-               clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
-
+       if errorInfo.ErrorCause != " " {
+               xapp.Logger.Debug("Sending successful REST notification (Error cause %s) to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
+                       errorInfo.ErrorCause, clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
+       } else {
+               xapp.Logger.Debug("Sending successful REST notification to endpoint=%v:%v, XappEventInstanceID=%v, E2EventInstanceID=%v, %s",
+                       clientEndpoint.Host, *clientEndpoint.HTTPPort, xAppEventInstanceID, e2EventInstanceID, idstring(nil, trans))
+       }
        c.UpdateCounter(cRestSubNotifToXapp)
        xapp.Subscription.Notify(resp, *clientEndpoint)
 
index 0d763e6..1c10846 100644 (file)
@@ -26,6 +26,7 @@ import "C"
 
 import (
        "encoding/hex"
+       "encoding/json"
        "fmt"
 
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
@@ -50,14 +51,14 @@ type E2ap struct {
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) SetASN1DebugPrintStatus(logLevel int) {
+func (e *E2ap) SetASN1DebugPrintStatus(logLevel int) {
        e2ap_wrapper.SetASN1DebugPrintStatus(logLevel)
 }
 
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) FillSubscriptionReqMsgs(params interface{}, subreqList *e2ap.SubscriptionRequestList, restSubscription *RESTSubscription) error {
+func (e *E2ap) FillSubscriptionReqMsgs(params interface{}, subreqList *e2ap.SubscriptionRequestList, restSubscription *RESTSubscription) error {
        xapp.Logger.Debug("FillSubscriptionReqMsgs")
 
        p := params.(*models.SubscriptionParams)
@@ -107,7 +108,35 @@ func (c *E2ap) FillSubscriptionReqMsgs(params interface{}, subreqList *e2ap.Subs
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) UnpackSubscriptionRequest(payload []byte) (*e2ap.E2APSubscriptionRequest, error) {
+func (e *E2ap) CheckActionNotAdmittedList(msgType int, actionNotAdmittedList e2ap.ActionNotAdmittedList, c *Control) ErrorInfo {
+
+       var prefixString string
+       var errorInfo ErrorInfo
+       var actionNotAdmittedString string
+       if len(actionNotAdmittedList.Items) > 0 {
+               if msgType == xapp.RIC_SUB_RESP {
+                       prefixString = "RICSubscriptionResponse partially accepted:"
+                       c.UpdateCounter(cPartialSubRespFromE2)
+               } else if msgType == xapp.RIC_SUB_FAILURE {
+                       prefixString = "RICSubscriptionFailure:"
+               }
+               jsonActionNotAdmittedList, err := json.Marshal(actionNotAdmittedList.Items)
+               if err != nil {
+                       actionNotAdmittedString = "ActionNotAdmittedList > 0. Submgr json.Marshal error"
+                       xapp.Logger.Error("CheckActionNotAdmittedList() json.Marshal error %s", err.Error())
+               } else {
+                       actionNotAdmittedString = "ActionNotAdmittedList: " + string(jsonActionNotAdmittedList)
+               }
+       }
+       err := fmt.Errorf("%s %s", prefixString, actionNotAdmittedString)
+       errorInfo.SetInfo(err.Error(), models.SubscriptionInstanceErrorSourceE2Node, "")
+       return errorInfo
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (e *E2ap) UnpackSubscriptionRequest(payload []byte) (*e2ap.E2APSubscriptionRequest, error) {
        e2SubReq := packerif.NewPackerSubscriptionRequest()
        err, subReq := e2SubReq.UnPack(&e2ap.PackedData{payload})
        if err != nil {
@@ -128,7 +157,7 @@ func (c *E2ap) PackSubscriptionRequest(req *e2ap.E2APSubscriptionRequest) (int,
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) UnpackSubscriptionResponse(payload []byte) (*e2ap.E2APSubscriptionResponse, error) {
+func (e *E2ap) UnpackSubscriptionResponse(payload []byte) (*e2ap.E2APSubscriptionResponse, error) {
        e2SubResp := packerif.NewPackerSubscriptionResponse()
        err, subResp := e2SubResp.UnPack(&e2ap.PackedData{payload})
        if err != nil {
@@ -137,7 +166,7 @@ func (c *E2ap) UnpackSubscriptionResponse(payload []byte) (*e2ap.E2APSubscriptio
        return subResp, nil
 }
 
-func (c *E2ap) PackSubscriptionResponse(req *e2ap.E2APSubscriptionResponse) (int, *e2ap.PackedData, error) {
+func (e *E2ap) PackSubscriptionResponse(req *e2ap.E2APSubscriptionResponse) (int, *e2ap.PackedData, error) {
        e2SubResp := packerif.NewPackerSubscriptionResponse()
        err, packedData := e2SubResp.Pack(req)
        if err != nil {
@@ -149,7 +178,7 @@ func (c *E2ap) PackSubscriptionResponse(req *e2ap.E2APSubscriptionResponse) (int
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) UnpackSubscriptionFailure(payload []byte) (*e2ap.E2APSubscriptionFailure, error) {
+func (e *E2ap) UnpackSubscriptionFailure(payload []byte) (*e2ap.E2APSubscriptionFailure, error) {
        e2SubFail := packerif.NewPackerSubscriptionFailure()
        err, subFail := e2SubFail.UnPack(&e2ap.PackedData{payload})
        if err != nil {
@@ -158,7 +187,7 @@ func (c *E2ap) UnpackSubscriptionFailure(payload []byte) (*e2ap.E2APSubscription
        return subFail, nil
 }
 
-func (c *E2ap) PackSubscriptionFailure(req *e2ap.E2APSubscriptionFailure) (int, *e2ap.PackedData, error) {
+func (e *E2ap) PackSubscriptionFailure(req *e2ap.E2APSubscriptionFailure) (int, *e2ap.PackedData, error) {
        e2SubFail := packerif.NewPackerSubscriptionFailure()
        err, packedData := e2SubFail.Pack(req)
        if err != nil {
@@ -170,7 +199,7 @@ func (c *E2ap) PackSubscriptionFailure(req *e2ap.E2APSubscriptionFailure) (int,
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) UnpackSubscriptionDeleteRequest(payload []byte) (*e2ap.E2APSubscriptionDeleteRequest, error) {
+func (e *E2ap) UnpackSubscriptionDeleteRequest(payload []byte) (*e2ap.E2APSubscriptionDeleteRequest, error) {
        e2SubDelReq := packerif.NewPackerSubscriptionDeleteRequest()
        err, subDelReq := e2SubDelReq.UnPack(&e2ap.PackedData{payload})
        if err != nil {
@@ -179,7 +208,7 @@ func (c *E2ap) UnpackSubscriptionDeleteRequest(payload []byte) (*e2ap.E2APSubscr
        return subDelReq, nil
 }
 
-func (c *E2ap) PackSubscriptionDeleteRequest(req *e2ap.E2APSubscriptionDeleteRequest) (int, *e2ap.PackedData, error) {
+func (e *E2ap) PackSubscriptionDeleteRequest(req *e2ap.E2APSubscriptionDeleteRequest) (int, *e2ap.PackedData, error) {
        e2SubDelReq := packerif.NewPackerSubscriptionDeleteRequest()
        err, packedData := e2SubDelReq.Pack(req)
        if err != nil {
@@ -191,7 +220,7 @@ func (c *E2ap) PackSubscriptionDeleteRequest(req *e2ap.E2APSubscriptionDeleteReq
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) UnpackSubscriptionDeleteResponse(payload []byte) (*e2ap.E2APSubscriptionDeleteResponse, error) {
+func (e *E2ap) UnpackSubscriptionDeleteResponse(payload []byte) (*e2ap.E2APSubscriptionDeleteResponse, error) {
        e2SubDelResp := packerif.NewPackerSubscriptionDeleteResponse()
        err, subDelResp := e2SubDelResp.UnPack(&e2ap.PackedData{payload})
        if err != nil {
@@ -200,7 +229,7 @@ func (c *E2ap) UnpackSubscriptionDeleteResponse(payload []byte) (*e2ap.E2APSubsc
        return subDelResp, nil
 }
 
-func (c *E2ap) PackSubscriptionDeleteResponse(req *e2ap.E2APSubscriptionDeleteResponse) (int, *e2ap.PackedData, error) {
+func (e *E2ap) PackSubscriptionDeleteResponse(req *e2ap.E2APSubscriptionDeleteResponse) (int, *e2ap.PackedData, error) {
        e2SubDelResp := packerif.NewPackerSubscriptionDeleteResponse()
        err, packedData := e2SubDelResp.Pack(req)
        if err != nil {
@@ -212,7 +241,7 @@ func (c *E2ap) PackSubscriptionDeleteResponse(req *e2ap.E2APSubscriptionDeleteRe
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
-func (c *E2ap) UnpackSubscriptionDeleteFailure(payload []byte) (*e2ap.E2APSubscriptionDeleteFailure, error) {
+func (e *E2ap) UnpackSubscriptionDeleteFailure(payload []byte) (*e2ap.E2APSubscriptionDeleteFailure, error) {
        e2SubDelFail := packerif.NewPackerSubscriptionDeleteFailure()
        err, subDelFail := e2SubDelFail.UnPack(&e2ap.PackedData{payload})
        if err != nil {
@@ -222,7 +251,7 @@ func (c *E2ap) UnpackSubscriptionDeleteFailure(payload []byte) (*e2ap.E2APSubscr
 }
 
 /*
-func (c *E2ap) PackSubscriptionDeleteFailure(req *e2ap.E2APSubscriptionDeleteFailure) (int, *e2ap.PackedData, error) {
+func (e *E2ap) PackSubscriptionDeleteFailure(req *e2ap.E2APSubscriptionDeleteFailure) (int, *e2ap.PackedData, error) {
        e2SubDelFail := packerif.NewPackerSubscriptionDeleteFailure()
        err, packedData := e2SubDelFail.Pack(req)
        if err != nil {
index 991437d..12f3f8e 100644 (file)
@@ -17,6 +17,7 @@ const (
        cSubReqToE2             string = "SubReqToE2"
        cSubReReqToE2           string = "SubReReqToE2"
        cSubRespFromE2          string = "SubRespFromE2"
+       cPartialSubRespFromE2   string = "PartialSubRespFromE2"
        cSubFailFromE2          string = "SubFailFromE2"
        cSubReqTimerExpiry      string = "SubReqTimerExpiry"
        cRouteCreateFail        string = "RouteCreateFail"
@@ -58,6 +59,7 @@ func GetMetricsOpts() []xapp.CounterOpts {
                {Name: cRestSubFailNotifToXapp, Help: "The total number of failure Rest SubscriptionNotification messages sent to xApp"},
                {Name: cSubReqToE2, Help: "The total number of SubscriptionRequest messages sent to E2Term"},
                {Name: cSubReReqToE2, Help: "The total number of SubscriptionRequest messages resent to E2Term"},
+               {Name: cPartialSubRespFromE2, Help: "The total number of partial SubscriptionResponse messages from E2Term"},
                {Name: cSubRespFromE2, Help: "The total number of SubscriptionResponse messages from E2Term"},
                {Name: cSubFailFromE2, Help: "The total number of SubscriptionFailure messages from E2Term"},
                {Name: cSubReqTimerExpiry, Help: "The total number of SubscriptionRequest timer expires"},
index 313811c..5ad6723 100644 (file)
@@ -39,6 +39,7 @@ func TestAddAllCountersOnce(t *testing.T) {
                Counter{cSubReqToE2, 1},
                Counter{cSubReReqToE2, 1},
                Counter{cSubRespFromE2, 1},
+               Counter{cPartialSubRespFromE2, 1},
                Counter{cSubFailFromE2, 1},
                Counter{cSubReqTimerExpiry, 1},
                Counter{cRouteCreateFail, 1},
@@ -76,6 +77,7 @@ func TestAddAllCountersOnce(t *testing.T) {
        mainCtrl.c.UpdateCounter(cSubReqToE2)
        mainCtrl.c.UpdateCounter(cSubReReqToE2)
        mainCtrl.c.UpdateCounter(cSubRespFromE2)
+       mainCtrl.c.UpdateCounter(cPartialSubRespFromE2)
        mainCtrl.c.UpdateCounter(cSubFailFromE2)
        mainCtrl.c.UpdateCounter(cSubReqTimerExpiry)
        mainCtrl.c.UpdateCounter(cRouteCreateFail)
index 79ed694..e66dc3a 100644 (file)
@@ -4615,6 +4615,83 @@ func TestRESTSubReqSubFailRespInSubmgr(t *testing.T) {
        mainCtrl.VerifyAllClean(t)
 }
 
+//-----------------------------------------------------------------------------
+// TestRESTSubReqPartialResp
+//
+//   stub                          stub
+// +-------+        +---------+    +---------+
+// | xapp  |        | submgr  |    | e2term  |
+// +-------+        +---------+    +---------+
+//     |                 |              |
+//     | RESTSubReq      |              |
+//     |---------------->|              |
+//     | RESTSubResp     |              |
+//     |<----------------|              |
+//     |                 | SubReq       |
+//     |                 |------------->|
+//     |                 | SubResp      | Partially accepted
+//     |                 |<-------------|
+//     |                 |              |
+//     | RESTNotif       |              |
+//     |<----------------|              |
+//     |                 |              |
+//     |           [SUBS DELETE]        |
+//     |                 |              |
+//
+//-----------------------------------------------------------------------------
+
+func TestRESTSubReqPartialResp(t *testing.T) {
+
+       // Init counter check
+       mainCtrl.CounterValuesToBeVeriefied(t, CountersToBeAdded{
+               Counter{cRestSubReqFromXapp, 1},
+               Counter{cRestSubRespToXapp, 1},
+               Counter{cSubReqToE2, 1},
+               Counter{cSubRespFromE2, 1},
+               Counter{cPartialSubRespFromE2, 1},
+               Counter{cRestSubNotifToXapp, 1},
+               Counter{cRestSubDelReqFromXapp, 1},
+               Counter{cSubDelReqToE2, 1},
+               Counter{cSubDelRespFromE2, 1},
+               Counter{cRestSubDelRespToXapp, 1},
+       })
+
+       // Req
+       params := xappConn1.GetRESTSubsReqReportParams(subReqCount)
+
+       actionId := int64(2)
+       actionType := "report"
+       actionDefinition := []int64{5678, 1}
+       subsequestActionType := "continue"
+       timeToWait := "w10ms"
+       params.AppendActionToActionToBeSetupList(actionId, actionType, actionDefinition, subsequestActionType, timeToWait)
+
+       restSubId := xappConn1.SendRESTSubsReq(t, params)
+       crereq, cremsg := e2termConn1.RecvSubsReq(t)
+       xappConn1.ExpectRESTNotification(t, restSubId)
+
+       actionNotAdmittedItem := e2ap.ActionNotAdmittedItem{}
+       actionNotAdmittedItem.ActionId = 1
+       actionNotAdmittedItem.Cause.Content = 1
+       actionNotAdmittedItem.Cause.Value = 8
+       actionNotAdmittedList := e2ap.ActionNotAdmittedList{}
+       actionNotAdmittedList.Items = append(actionNotAdmittedList.Items, actionNotAdmittedItem)
+       e2termConn1.SendPartialSubsResp(t, crereq, cremsg, actionNotAdmittedList)
+       e2SubsId := xappConn1.WaitRESTNotification(t, restSubId)
+
+       queryXappSubscription(t, int64(e2SubsId), "RAN_NAME_1", []string{"localhost:13560"})
+
+       // Del
+       deleteSubscription(t, xappConn1, e2termConn1, &restSubId)
+
+       mainCtrl.wait_subs_clean(t, e2SubsId, 10)
+       //Wait that subs is cleaned
+       waitSubsCleanup(t, e2SubsId, 10)
+
+       mainCtrl.VerifyCounterValues(t)
+       mainCtrl.VerifyAllClean(t)
+}
+
 //-----------------------------------------------------------------------------
 // TestRESTSubDelReqRetryInSubmgr
 //
index f2f31fd..602708f 100644 (file)
@@ -298,12 +298,69 @@ func (tc *E2Stub) SendSubsResp(t *testing.T, req *e2ap.E2APSubscriptionRequest,
                resp.ActionAdmittedList.Items[index].ActionId = req.ActionSetups[index].ActionId
        }
 
-       for index := uint64(0); index < 1; index++ {
-               item := e2ap.ActionNotAdmittedItem{}
-               item.ActionId = index
-               item.Cause.Content = 1
-               item.Cause.Value = 1
-               resp.ActionNotAdmittedList.Items = append(resp.ActionNotAdmittedList.Items, item)
+       packerr, packedMsg := e2SubsResp.Pack(resp)
+       if packerr != nil {
+               tc.TestError(t, "pack NOK %s", packerr.Error())
+       }
+       tc.Debug("%s", e2SubsResp.String())
+
+       params := &xapp.RMRParams{}
+       params.Mtype = xapp.RIC_SUB_RESP
+       //params.SubId = msg.SubId
+       params.SubId = -1
+       params.Payload = packedMsg.Buf
+       params.PayloadLen = len(packedMsg.Buf)
+       params.Meid = msg.Meid
+       //params.Xid = msg.Xid
+       params.Mbuf = nil
+
+       tc.Debug("SEND SUB RESP: %s", params.String())
+       snderr := tc.SendWithRetry(params, false, 5)
+       if snderr != nil {
+               tc.TestError(t, "RMR SEND FAILED: %s", snderr.Error())
+       }
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+func (tc *E2Stub) SendPartialSubsResp(t *testing.T, req *e2ap.E2APSubscriptionRequest, msg *xapp.RMRParams, actionNotAdmittedList e2ap.ActionNotAdmittedList) {
+       tc.Debug("SendPartialSubsResp")
+
+       if len(actionNotAdmittedList.Items) == 0 {
+               tc.TestError(t, "SendPartialSubsResp() Empty actionNotAdmittedList.Items")
+               return
+       }
+
+       e2SubsResp := e2asnpacker.NewPackerSubscriptionResponse()
+
+       //---------------------------------
+       // e2term activity: Send Subs Resp
+       //---------------------------------
+       resp := &e2ap.E2APSubscriptionResponse{}
+
+       resp.RequestId.Id = req.RequestId.Id
+       resp.RequestId.InstanceId = req.RequestId.InstanceId
+       resp.FunctionId = req.FunctionId
+
+       for index, actionNotAdmittedItem := range actionNotAdmittedList.Items {
+               for _, ActionToBeSetupItem := range req.ActionSetups {
+                       if ActionToBeSetupItem.ActionId == actionNotAdmittedItem.ActionId {
+                               actionNotAdmittedItem := e2ap.ActionNotAdmittedItem{}
+                               actionNotAdmittedItem.ActionId = ActionToBeSetupItem.ActionId
+                               actionNotAdmittedItem.Cause.Content = 1
+                               actionNotAdmittedItem.Cause.Value = 8
+                               resp.ActionNotAdmittedList.Items = append(resp.ActionNotAdmittedList.Items, actionNotAdmittedItem)
+                               // Remove the element
+                               req.ActionSetups = append(req.ActionSetups[:index], req.ActionSetups[index+1:]...)
+
+                       }
+               }
+       }
+       for _, ActionToBeSetupItem := range req.ActionSetups {
+               actionAdmittedItem := e2ap.ActionAdmittedItem{}
+               actionAdmittedItem.ActionId = ActionToBeSetupItem.ActionId
+               resp.ActionAdmittedList.Items = append(resp.ActionAdmittedList.Items, actionAdmittedItem)
        }
 
        packerr, packedMsg := e2SubsResp.Pack(resp)