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
                - 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
                - 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.
      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))
                        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 {
                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)
                                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:
                                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:
                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")
                        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
                }
        } 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
                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 {
        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 {
                        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)
        }
 
                        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,
 //
 //-------------------------------------------------------------------
 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))
 
        // 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,
                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)
                                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)
 
        c.UpdateCounter(cRestSubNotifToXapp)
        xapp.Subscription.Notify(resp, *clientEndpoint)
 
index 0d763e6..1c10846 100644 (file)
@@ -26,6 +26,7 @@ import "C"
 
 import (
        "encoding/hex"
 
 import (
        "encoding/hex"
+       "encoding/json"
        "fmt"
 
        "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
        "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)
 }
 
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
        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)
        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 {
        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 {
        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
 }
 
        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 {
        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 {
        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
 }
 
        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 {
        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 {
        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
 }
 
        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 {
        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 {
        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
 }
 
        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 {
        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 {
        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 {
        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"
        cSubReqToE2             string = "SubReqToE2"
        cSubReReqToE2           string = "SubReReqToE2"
        cSubRespFromE2          string = "SubRespFromE2"
+       cPartialSubRespFromE2   string = "PartialSubRespFromE2"
        cSubFailFromE2          string = "SubFailFromE2"
        cSubReqTimerExpiry      string = "SubReqTimerExpiry"
        cRouteCreateFail        string = "RouteCreateFail"
        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: 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"},
                {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{cSubReqToE2, 1},
                Counter{cSubReReqToE2, 1},
                Counter{cSubRespFromE2, 1},
+               Counter{cPartialSubRespFromE2, 1},
                Counter{cSubFailFromE2, 1},
                Counter{cSubReqTimerExpiry, 1},
                Counter{cRouteCreateFail, 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(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)
        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)
 }
 
        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
 //
 //-----------------------------------------------------------------------------
 // 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
        }
 
                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)
        }
 
        packerr, packedMsg := e2SubsResp.Pack(resp)